Scikit学习RandomForest内存错误

时间:2014-04-16 19:19:49

标签: python python-2.7 scikit-learn

我正在尝试在mnist手写数字数据集上运行scikit学习随机森林算法。在算法训练期间,系统进入内存错误。请告诉我该怎么做才能解决这个问题。

CPU统计数据:Intel Core 2 Duo,内存为4GB

数据集的形状为 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

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

Scikit-learn Dev Team在内存管理方面做了很多改进。 .ensemble方法

的表现

在充分尊重其他意见的情况下, scikit-learn 0.16.1 并不能证明自己有“讨厌的 X y 复制品,引用了一些早期版本。

由于其他一些原因,我花了相当长的时间在 RandomForestRegressor() 超参数的情况下,包括。他们的记忆足迹问题。

0.16.1起,并列joblib内存要求低于2%增加到默认n_jobs = 1以上 { 2, 3, ... } < /强>

近期scikit-learn发布的共同主持人@glouppe发布了a marvelous & insight-full presentation (2014-Aug, rel. 0.15.0),包括。与基于R和其他已知的RandomForest框架进行比较。

恕我直言,第25页以上提到了提高速度的技术,包括 np.asfortranarray(...) ,但这些似乎在我看来(没有任何实验证明)只是在Scikit-learn开发团队内部共享的内部指示,而不是对我们这些凡人的推荐在“外部世界”。

回归或分类?

是的,这很重要。一些额外的特征工程工作&amp;如果不进行全面的FeatureSET矢量套袋,测试可能会到位。您的学习者似乎是分类器案例,因此请深入研究:

  1. 试验max_features
  2. 的非默认设置
  3. 在1中调整学员后,使用O / S服务处理更大的虚拟内存 mkswap + swapon
  4. 附录

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

    虽然 .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() 个人作业

答案 2 :(得分:1)

一种解决方案是使用scikit-learn的最新版本(0.19)。在更改日志中,他们在bug fixes section中提到了(实际上,有一个重大改进):

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

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

pip3 install scikit-learn==0.19.0

答案 3 :(得分:0)

请用一棵树训练随机森林并检查树的深度。默认情况下,完整树在scikit-learn中增长。深度可能非常大,因此森林中的几棵树都可能占用大量内存。您可以尝试使用max_depth超参数来限制树的深度。

当我将树的深度从42(森林中树的平均深度)减少到6时,我运行experiment。内存减少了66倍,而性能略好一些(大约4%)。