随机森林在预期下进行

时间:2016-12-18 13:02:23

标签: c++ machine-learning weka random-forest decision-tree

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

我使用的arff格式数据集是来自IMDb的电影评论。对于每个实例,它包含多个最频繁的单词频率,并标有“P' P' (对于正面)或' N' (对于否定)。

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

以下是具有默认设置的Weka结果和具有相同设置的我的结果(100棵树,在拆分期间考虑了10个随机特征):

Weka results and my results

首先,我认为我的数据导入器存在错误。然后我检查了我的导入器并与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"和#34; TreeBuilder.h"。

更新

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

10个功能(100棵树,分割时要考虑的4个功能): 10 features, 100 trees

50个功能(100棵树,分割时要考虑的6个功能): 50 features, 100 trees

为了整理结果并使其在随机化引起的变化方面更具说服力,我将它们分组到下表中(总共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;

}

以下是我和韦卡比较的更新版本:

------------------------------------------------------------
| 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   |
------------------------------------------------------------

感谢所有答案和帮助。

1 个答案:

答案 0 :(得分:1)

(几乎)相同学习算法的两种实现在许多方面将主要不同。这引入了一个主要区别,相同的DataSET将获得与其他类似的高级机器学习过程略有不同的结果。

如果实现完全相同,则不保证结果相同。显示这一点的最佳案例是随机森林类的机器学习学习者:

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

请注意随机化一词。

如上面的评论中所述,即使其他任何实施都没有。差异可能是读者的兴趣,随机森林的本质要求随机化 - 作为一种重复使用的工具 - 在处理过程中发生。

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

在同一 RandomForest 上测试相同的 .fit() DataSET方法,但使用不同的 {{1} 提供的值在其他主要相同的过程重复中实现的(im) - 精度产生一定量的变化。提供相同的seed值应该提供相同的结果(当且仅当在没有其他主机共同定位的过程损害随机森林生成阶段内使用的RNG工厂的临时有状态的情况下)

enter image description here

好消息是,随着整体的增长,主要方差的这一数量从一些> 10%减少(树木数量越少,RNG引入的主要方差越低) )。

因此,4%~6%的射频可以达到这种现象。

enter image description here

Z轴显示随机森林集合方法的增加的预测性能 +主要方差的减少量(由不同的{引入) {1}})叠加在预测上。

X轴(向右跑)带有seed

Y轴(向左运行)带有RNG( seed ) - 序数~100个不同的显式N_trees值(从seed开始)

后记

鉴于OP,您可以通过在同一seed上重新运行RF学习器实现来重新测试您自己的RNG实现 - aBASE, aBASE+1, +2, +3, ..., +99依赖性,以接收对此现象的定量评估你的seed(现在) - 确定性系统。

如果您可以在DataSET复合体上执行相同的测试,则可以获得关于此主要景观的更清晰视图。