随机森林表现低于预期

Posted

技术标签:

【中文标题】随机森林表现低于预期【英文标题】:Random forests performed under expectation 【发布时间】:2017-05-03 16:16:47 【问题描述】:

我正在学习决策树算法,并在 Weka 中实现了一个参考 RF 的随机森林。我使用相同的数据集测试了我的实现和 weka 实现(在默认设置下)。然而,我的准确率比 Weka 3.8 版获得的准确率低了约 5%(通过 'train-first1000.arff' 训练集和 'dev-first1000.arff' 测试集获得)。

我使用的 arff 格式数据集是来自 IMDb 的电影评论。对于每个实例,它都包含一些最常用词的频率,并标有“P”(表示肯定)或“N”(表示否定)。

为了比较,我在 Weka 随机森林中使用了默认设置(100 棵树,在拆分期间考虑 log() + 1 个特征,没有装袋等)

这是使用默认设置的 Weka 结果和我使用相同设置的结果(100 棵树,拆分期间考虑的 10 个随机特征):

首先我认为我的数据导入器中存在错误。然后我检查了我的导入器并与 python arff 导入器进行了比较,发现它们执行正确。

然后我查看了weka RF的源码: http://grepcode.com/file/repo1.maven.org/maven2/nz.ac.waikato.cms.weka/weka-dev/3.7.5/weka/classifiers/trees/RandomForest.java

并与我的仔细比较了不止一次,以确保实现是相同的。然而,我无法找到仍然存在 5% 差异的原因。

这是我的实现的链接:

https://github.com/YSZhuoyang/Parallelized-Random-Forests/tree/randomforests

更具体地说,训练算法的主要部分可以在“TreeBuilder.cpp”和“TreeBuilder.h”中找到。

更新:

我分别测试了10个特征数据和50个特征数据,我的实现得到的结果都低于weka实现。

10 个特征(100 棵树,拆分时要考虑的 4 个特征):

50 个特征(100 个树,6 个在拆分过程中要考虑的特征):

为了稍微整理一下结果并使其在随机化引起的变化方面更具说服力,我将它们分组到下表中(总共 50 个特征,在拆分过程中考虑了 6 个随机特征,两个随机种子都设置为 1 ):

------------------------------------------------------------
| num total features | num trees | weka result | my result |
|         50         |     1     |    55.61    |   52.34   |
|         50         |     5     |    59.08    |   54.35   |
|         50         |     10    |    60.07    |   55.43   |
|         50         |     20    |    62.54    |   57.20   |
|         50         |     50    |    64.14    |   59.56   |
|         50         |    100    |    65.28    |   61.09   |
------------------------------------------------------------

这表明它不是由于随机化。

已解决:

我使用了 weka 提供的糖尿病数据集,它只有 8 个特征(遵循@alexeykuzmin0 给出的建议),并在 weka 上使用随机树对其进行了测试,考虑了拆分过程中的所有特征。然后我将树可视化并与我的树进行比较,发现根节点上选择的分裂点与我的不同,这似乎是我计算的信息增益错误。最后我发现有一个类型错误,将 double 类型的值转换为 int 类型,导致结果不准确。

一段代码:

// Compute entropy of children
for (const vector<unsigned int>& group : groups)

    double entropyChild = ComputeEntropy( group );

    // Before being corrected
    // unsigned int numChildren = group.size();
    // infoGain -= numChildren / numInstances * entropyChild;

    // Corrected
    double numChildren = group.size();
    infoGain -= numChildren / (double) numInstances * entropyChild;


这是我和 weka 比较的更新版本:

------------------------------------------------------------
| num total features | num trees | weka result | my result |
|         50         |     1     |    55.61    |   55.34   |
|         50         |     5     |    59.08    |   58.73   |
|         50         |     10    |    60.07    |   60.86   |
|         50         |     20    |    62.54    |   62.97   |
|         50         |     50    |    64.14    |   64.68   |
|         50         |    100    |    65.28    |   65.35   |
------------------------------------------------------------

感谢所有回答和帮助。

【问题讨论】:

这对于这里的普通女孩/男人来说阅读量太大了。如果您希望有任何机会帮助您在此处发布实际代码,那么只有您现在认为导致差异的最小部分。 @kabanus 是的,我理解,但是我无法进一步缩小范围,因为我不确定问题出在哪里,对此感到抱歉。我唯一能指出的是类文件“TreeBuilder.cpp”,它可能是出现问题的地方。 尝试创建具有不同结果的最小数据集 - 如果您有一些错误,它可能会出现,或者只是一个包含 1-3 个对象的小数据集,这更容易调试 这个问题,无论对你的努力有多痛苦,都应该成为一个 [Verifiable ] MCVE 问题。可能已经重新阅读了关于如何最好地在 *** 上提出问题的建议 >>> ***.com/help/mcve 所以尝试隔离一个可重新测试的案例,将其与 implementation-source 和 DataSET 一起发布(和也许使用 Weka 预先计算的结果)来追查根本原因。仍然是一组相当高级的麻烦(让随机化差异只是要提到的一个) 【参考方案1】:

(几乎)相同的学习算法的两种实现方式在很多方面都会大不相同。这引入了一个主要差异,相同的 DataSET 会从其他类似的高级机器学习过程中获得略有不同的结果。

Event如果实现完全一样,结果不保证是一样的。最好的例子就是机器学习的随机森林类:

随机森林是高度随机化树的 Breimann 森林

注意随机化这个词。

正如上面评论中所指出的,即使其他实现的差异可能不会引起读者的兴趣,随机森林的本质要求随机化——作为一种重复使用的工具——在处理过程中发生.

严谨的研究需要使用可重复的实验,因此随机森林学习器通常允许为底层 RNG(随机数生成器)提供明确提供的 seed 值。

在相同的 DataSET 上测试相同的 RandomForest .fit() 方法,但使用不同的 seed 值提供收益率在其他基本相同的过程重复上实现的结果(im)精度的一定量的差异。提供相同的seed 值应该提供相同的结果(当且仅当没有其他主机共置进程损坏随机森林生成阶段中使用的 RNG 工厂的临时状态状态)。

好消息是,随着集合的增长,主方差的数量会从大约 >10% 减少(树的数量越少,RNG 引入的主方差越低) .

所以 4% ~ 6% 对于 RF 这种现象来说是完全可以达到的。

Z轴展示了随机森林集成方法预测性能的提高+主方差减少量(由不同的@引入987654331@ ) 叠加在预测上。

X轴(向右跑)携带N_trees

Y轴(向左运行)带有seed-序数~100个不同的显式seed值(从aBASE, aBASE+1, +2, +3, ..., +99开始)


结语

鉴于 OP,您可以通过在同一 DataSET 上重新运行您的 RF-learner 实现来重新测试您自己的实现对 RNG-seed 的依赖性,以便在您的 [ Your-Learner, DataSET, ( Your-RNG, seed ) ] 上接收对该现象的定量评估(现在)-确定性系统。

如果您可以对 [ Weka-Learner, DataSET, ( Weka-RNG, seed ) ] 复合体执行相同的测试,您将获得更清晰的这个主要景观。

【讨论】:

谢谢@user3666197 答案很有帮助。然而,我的结果表明,两种实现的差异(或者说主方差)不会随着集合的增长而减少(我用 10、20、50、100 棵树进行了测试),而我的总是较低,这似乎很不寻常。 你介意吗,Oscar,发布一份 MCVE-DataSET + HyperParameterVECTOR 设置列表,用于 Weka RF 流程和您的实施 RF 流程以及观察到的评论行为的定量结果? 我已将获得的结果整理成一个表格,这样可能更容易看出差异。

以上是关于随机森林表现低于预期的主要内容,如果未能解决你的问题,请参考以下文章

随机森林与Adaboost

在 scikit 学习随机森林模型中,预期和预测的数组最终相同

随机森林原理与Sklearn参数详解

在拥有分类数据时,使用 Sklearn 随机森林进行特征选择并没有给我预期的结果

何时使用随机森林

随机森林