sklearn中的分类树给出不一致的答案

时间:2014-01-27 20:53:06

标签: python classification scikit-learn decision-tree

我正在使用来自sklearn的分类树,当我使用相同的数据进行两次模型训练时,并使用相同的测试数据进行预测,我得到了不同的结果。我尝试在较小的虹膜数据集上进行再现,并且它按预期工作。这是一些代码

from sklearn import tree
from sklearn.datasets import iris

clf = tree.DecisionTreeClassifier()
clf.fit(iris.data, iris.target)
r1 = clf.predict_proba(iris.data)

clf.fit(iris.data, iris.target)
r2 = clf.predict_proba(iris.data)
对于这个小例子,

r1r2是相同的,但是当我运行自己的大得多的数据集时,我会得到不同的结果。这有什么原因会发生吗?

编辑在查看一些文档后,我看到DecisionTreeClassifier有一个输入random_state来控制起点。通过将此值设置为常量,我摆脱了以前遇到的问题。但是现在我担心我的模型不尽如人意。这样做的推荐方法是什么?随便尝试一下?或者预计所有结果大致相同?

4 个答案:

答案 0 :(得分:10)

DecisionTreeClassifier通过根据某些功能的值反复拆分训练数据来工作。 Scikit-learn实现允许您通过为splitter关键字参数提供值来选择几种拆分算法。

  • “最佳”随机选择一个特征,并根据某些标准(您也可以选择;参见方法特征和criterion参数)找到它的“最佳”分割。看起来代码执行N_feature次,所以它实际上就像一个引导程序。

  • “随机”选择要随机考虑的功能,如上所述。然而,它还会测试该特征上随机生成的阈值(随机,受限于它在最小值和最大值之间的约束)。这可能有助于避免树上的“量化”错误,其中阈值受到训练数据中精确值的强烈影响。

这两种随机化方法都可以提高树木的性能。 Lui, Ting, and Fan's (2005) KDD paper中有一些相关的实验结果。

如果你每次绝对必须有一个相同的树,那么我会重复使用相同的random_state。否则,我希望树木每次都或多或少相等,并且在没有大量数据的情况下,我不确定你如何决定哪种随机树最好。

另请参阅:Source code for the splitter

答案 1 :(得分:6)

Matt Krause提供的答案并没有完全正确地回答这个问题。

this issue on GitHub中解释了scikit-learn DecisionTreeClassifier中观察到的行为的原因。

使用默认设置时,每次拆分都会考虑所有功能。这由max_features参数控制,该参数指定每次拆分时应考虑的功能数量。在每个节点,分类器随机抽样max_features而不替换(!)。

因此,在使用max_features=n_features时,每次拆分都会考虑所有要素。但是,实现仍将从功能列表中随机抽样(即使这意味着将对所有功能进行采样,在本例中)。 因此,考虑特征的顺序是伪随机的。如果绑定了两个可能的拆分,则遇到的第一个拆分将用作最佳拆分。

这正是你的决策树每次调用时产生不同结果的原因:所考虑的特征顺序在每个节点随机化,当两个可能的分裂然后绑定时,要使用的分割将取决于哪个一个被认为是第一个。

如前所述,可以使用random_state参数指定用于随机化的种子。

答案 2 :(得分:0)

  

每次拆分时都会随机置换功能。因此,即使使用相同的训练数据和max_features = n_features,如果在搜索最佳分割期间枚举的几个分割的标准的改进相同,则最佳找到的分割可以变化。为了在拟合期间获得确定性行为,必须修复random_state。

来源:http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier#Notes

答案 3 :(得分:-1)

我对sklearn一无所知,但......

我猜DecisionTreeClassifier有一些内部状态,由fit创建,只会更新/扩展。

你应该创建一个新的吗?