我正在使用来自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)
对于这个小例子, r1
和r2
是相同的,但是当我运行自己的大得多的数据集时,我会得到不同的结果。这有什么原因会发生吗?
编辑在查看一些文档后,我看到DecisionTreeClassifier
有一个输入random_state
来控制起点。通过将此值设置为常量,我摆脱了以前遇到的问题。但是现在我担心我的模型不尽如人意。这样做的推荐方法是什么?随便尝试一下?或者预计所有结果大致相同?
答案 0 :(得分:10)
DecisionTreeClassifier
通过根据某些功能的值反复拆分训练数据来工作。 Scikit-learn实现允许您通过为splitter
关键字参数提供值来选择几种拆分算法。
“最佳”随机选择一个特征,并根据某些标准(您也可以选择;参见方法特征和criterion
参数)找到它的“最佳”分割。看起来代码执行N_feature次,所以它实际上就像一个引导程序。
“随机”选择要随机考虑的功能,如上所述。然而,它还会测试该特征上随机生成的阈值(随机,受限于它在最小值和最大值之间的约束)。这可能有助于避免树上的“量化”错误,其中阈值受到训练数据中精确值的强烈影响。
这两种随机化方法都可以提高树木的性能。 Lui, Ting, and Fan's (2005) KDD paper中有一些相关的实验结果。
如果你每次绝对必须有一个相同的树,那么我会重复使用相同的random_state。否则,我希望树木每次都或多或少相等,并且在没有大量数据的情况下,我不确定你如何决定哪种随机树最好。
答案 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。
答案 3 :(得分:-1)
我对sklearn
一无所知,但......
我猜DecisionTreeClassifier
有一些内部状态,由fit
创建,只会更新/扩展。
你应该创建一个新的吗?