随机森林:内存不足

3

我正在使用scikit-learn中的随机森林算法来拟合一个大约30MB的训练数据,但我的笔记本电脑在运行时总是因为应用程序内存不足而崩溃。测试数据比训练数据还要大几倍。我的设备是Macbook Air 2GHz 8GB内存。

有哪些方法可以解决这个问题呢?

rf = RandomForestClassifier(n_estimators = 100, n_jobs=4)
print "20 Fold CV Score: ", np.mean(cross_validation.cross_val_score(rf, X_train_a, y_train, cv=20, scoring='roc_auc'))

你使用的是哪个版本的scikit-learn?0.15版本在随机森林的内存消耗方面有一些重大改进。 - Andreas Mueller
'0.15.2'. 我尝试切换到顺序构建的GBRT,但不知何故它也会耗尽内存。这是否意味着我真的需要尝试在EC2集群上运行或进行随机抽样? - ananuc
@AndreasMueller:感谢您关于高级Sklearn的有用演讲。也许我可以尝试一些那里的想法。我还没有机会去看ogrissel在EC2上的并行ML教程。我想知道我们需要考虑启动EC2集群的哪个阶段? - ananuc
很高兴你喜欢它。正如@Timo建议的那样,您需要调整参数以在此框上工作。我建议使用一些正则化,例如“max_depth”或“max_leaf_nodes”。这应该会大大减少内存消耗,或者减少n_estimators。另一个选择是切换到GradientBoostingClassifier,这可能需要更少或更浅的估算器,但是训练是顺序的。 - Andreas Mueller
你什么时候应该使用EC2?如果你从低的“max_depth”和“n_estimators”开始,它可以在你的笔记本电脑上运行。绘制准确性随着更多估算器或更深的树而提高的图表。如果看起来需要更多的内存才能提高准确性,或者如果运行时间太长,考虑使用EC2。顺便说一句,尝试EC2是便宜且容易的。 - Andreas Mueller
2个回答

6
您最好的选择是调整参数。
n_jobs=4

这将使计算机同时执行四个训练和测试循环。不同的Python任务在单独的进程中运行,因此也会复制整个数据集。尝试将n_jobs减少到2或1以节省内存。n_jobs==4使用四倍的内存,而n_jobs==1只使用一次。

cv=20

这将原始数据分成20份,代码执行了20次训练和测试。这意味着训练数据的大小是原始数据的19份。你可以放心地把它减少到10份,但你的准确度估计可能会变差。这不会节省太多内存,但可以使运行时间更快。

n_estimators = 100

降低此参数将会节省少量内存,但会使算法运行更快,因为随机森林将包含更少的树。
总之,我建议将 "n_jobs" 减少到2,以节省内存(运行时间增加2倍)。为了弥补运行时间,我建议将“cv”更改为10(运行时间减少两倍)。如果还没有帮助,请将“n_jobs”更改为1,并将估计器数量减少到50(额外提高两倍的处理速度)。

1
截至2021年,由于sklearn库已经有所改进,因此n_jobs对RAM使用的影响很小。因此,减少n_jobs并不能提供太多好处。https://dev59.com/kH7aa4cB1Zd3GeqPu8s4 - Peter

1
我曾处理过大约4MB的数据集,使用scikit-learn中默认超参数的随机森林占用了大约50MB的内存(因此是数据量的10倍以上)。通过设置max_depth = 6,内存消耗减少了66倍。在我的数据集上,浅层随机森林的性能得到了提高!我在博客post中记录了这个实验。
从我的经验来看,在回归任务中,内存使用量甚至可能增长得更多,因此控制树的深度非常重要。可以通过直接控制max_depth或调整以下参数来控制树的深度:min_samples_splitmin_samples_leafmin_weight_fraction_leafmax_featuresmax_leaf_nodes
当然,随机森林的内存也可以通过集成中的树的数量来控制。

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