Scikit Learn 随机森林 内存错误

5
我正在尝试在mnist手写数字数据集上运行scikit learn随机森林算法。训练算法时,系统出现了内存错误。请告诉我如何解决此问题。 CPU统计信息:Intel Core 2 Duo处理器,4GB RAM。
数据集的形状为60000, 784。完整的Linux终端错误如下:
> File "./reducer.py", line 53, in <module>
>     main()   File "./reducer.py", line 38, in main
>     clf = clf.fit(data,labels) #training the algorithm   File "/usr/lib/pymodules/python2.7/sklearn/ensemble/forest.py", line 202,
> in fit
>     for i in xrange(n_jobs))   File "/usr/lib/pymodules/python2.7/joblib/parallel.py", line 409, in
> __call__
>     self.dispatch(function, args, kwargs)   File "/usr/lib/pymodules/python2.7/joblib/parallel.py", line 295, in
> dispatch
>     job = ImmediateApply(func, args, kwargs)   File "/usr/lib/pymodules/python2.7/joblib/parallel.py", line 101, in
> __init__
>     self.results = func(*args, **kwargs)   File "/usr/lib/pymodules/python2.7/sklearn/ensemble/forest.py", line 73, in
> _parallel_build_trees
>     sample_mask=sample_mask, X_argsorted=X_argsorted)   File "/usr/lib/pymodules/python2.7/sklearn/tree/tree.py", line 476, in fit
>     X_argsorted=X_argsorted)   File "/usr/lib/pymodules/python2.7/sklearn/tree/tree.py", line 357, in
> _build_tree
>     np.argsort(X.T, axis=1).astype(np.int32).T)   File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line
> 680, in argsort
>     return argsort(axis, kind, order) MemoryError

创建随机森林时使用哪些参数? - lejlot
我只是使用 n_estimators=10 - impiyush
4
请将n_jobs=1设置为1。 - lejlot
4个回答

4
要么设置n_jobs=1,要么升级到最新版本的scikit-learn。问题在于当前发布的版本使用多个进程并行拟合树,这意味着数据(Xy)需要被复制到这些进程中。下一个版本将使用线程而不是进程,因此树学习器将共享内存。

我尝试添加n_jobs=1,但仍然出现相同的错误。您能否提供一些方法,让我能够使用新版本的scikit-learn? - impiyush
@Piyush 如果您使用 n_jobs=1 仍然出现此错误,则升级无济于事。X 最初是以 np.float32 格式吗?它是否是按 Fortran 排序 (列优先) 的? - Fred Foo

2

Scikit-learn Dev Team在.ensemble方法上改进了内存管理和性能

尊重其他意见,scikit-learn 0.16.1并没有像一些早期版本那样有所谓的"nasty" X, y复制品问题。

由于一些其他原因,我花费了相当长的时间在RandomForestRegressor()超参数的概貌及其内存占用问题上。

截至0.16.1,在默认n_jobs = 1的情况下,与{ 2, 3, ... }相比,并行-joblib的内存要求仅增加不到2%

最近scikit-learn发行版的共同创始人@glouppe发布了一个奇妙而深入的演示文稿(2014年8月,rel.0.15.0),其中包括与基于R和其他已知随机森林框架的比较。

个人认为,第25页以上介绍了一些增加速度的技术,包括np.asfortranarray(...),但这些对我来说似乎只是Scikit-learn开发团队内部分享的指导方向,而不是我们这些生活在"外部世界"的凡人的建议。

回归还是分类?

是的,这很重要。如果没有进行全面的特征集向量装袋,则需要进行一些额外的特征工程和测试。您的学习者似乎是分类器情况,因此请深入研究以下内容:

  1. 尝试非默认设置的max_features等参数
  2. 在1中调整好学习者后,使用操作系统服务处理更大的虚拟内存mkswap+ swapon(如果需要)。

补充说明

经过另一轮测试,出现了一个有趣的观察结果。

虽然已成功地使用.set_params( n_jobs = -1 ).fit( X, y )配置训练了RandomForestRegressor(),但当尝试在这种预训练对象上使用.predict( X_observed )时,却出现了类似的map/reduce内存问题(现在是0.17.0)。

然而,同样的单一任务 .set_params( n_jobs = 1 ).predict( X_observed ).predict() 上表现良好。

1

一个解决方案是使用最新版本(0.19)的scikit-learn。在变更日志中,他们在错误修复部分提到了一个主要改进:

 Fixed excessive memory usage in prediction for random forests estimators. #8672 by Mike Benfield.

您可以使用以下方式安装此版本:

pip3 install scikit-learn==0.19.0

0
请使用单棵树训练随机森林并检查树的深度。在scikit-learn中,默认情况下会生长完整的树。深度可能非常大,因此即使是森林中的少数几棵树也可能使用大量内存。您可以尝试使用max_depth超参数来限制树的深度。
当我将树的深度从42(森林中树的平均深度)降低到6时,我运行了实验。内存减少了66倍,而性能略有提高(约4%)。

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