解决scikit-learn OneVsRest RandomForests反序列化缓慢问题

3
我有一个应用程序,其中我正在加载非常大的Python对象--它们是序列化的scikit-learn分类器及其相关词汇表。
这些分类器足够大(大约为1-100 MB),将它们加载到内存中是一项不简单的任务。实际读取很快,但反序列化需要很长时间,对于4MB的分类器大约需要10秒钟。
是否有比cPickle.dumps / cPickle.loads更快的序列化/反序列化对象的方法?
额外的信息:
这些分类器是10个元素的一对多随机森林实例。这些分类器是在大约1000个样本,大约500个特征和52个可能标签上进行训练的。min_density参数设置为0。
cProfile输出cPickle.load:
   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000  300.168  300.168 <ipython-input-4-9b8a128f290d>:1(loader)
        1    0.899    0.899  301.067  301.067 <string>:1(<module>)
    51380  288.151    0.006  288.151    0.006 __init__.py:93(__RandomState_ctor)
    51380    0.059    0.000    0.404    0.000 fromnumeric.py:1774(amax)
        1   11.613   11.613  300.168  300.168 {cPickle.load}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    51380    0.344    0.000    0.344    0.000 {method 'max' of 'numpy.ndarray' objects}
        1    0.000    0.000    0.000    0.000 {open}

我正在github.com/scikit-learn上开一个问题(issue)来讨论这个问题。

1个回答

2

您尝试过使用joblib picker吗?它在sklearn包中捆绑:

>>> from sklearn.externals import joblib
>>> joblib.dump(model, '/path/to/model.pkl')
>>> model_copy = joblib.load('/path/to/model.pkl')

编辑:实际上对于随机森林,使用默认的HIGHEST协议进行pickle似乎更快:

>>> from cPickle import dump, load, HIGHEST_PROTOCOL
>>> dump(model, open('/tmp/model_highest.pkl', 'wb'), HIGHEST_PROTOCOL)
>>> load(open('/tmp/model_highest.pkl', 'rb'))
编辑2: 根据您的个人资料报告,问题似乎是伪随机数生成器实例的反序列化。请提供您用于训练模型的精确Python代码片段以及数据集的形状,并将其与分析报告一起作为错误提交到scikit-learn项目的GitHub问题跟踪器上。

我目前正在使用cPickle dump和load,使用HIGHEST_PROTOCOL。我还没有尝试过joblib,但我想我可以试一试。也许我可以并行反序列化? - Maus
感谢您提供的性能分析输出,请查看我回答中的第二个编辑。 - ogrisel
我在 scikit-learn 的 GitHub 上开了一个问题(issue):https://github.com/scikit-learn/scikit-learn/issues/1622 。那里的帖子回应了 ogrisel 的第二次编辑。 - Maus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接