【问题标题】:Classification tree in sklearn giving inconsistent answerssklearn 中的分类树给出的答案不一致
【发布时间】:2023-03-24 17:25:02
【问题描述】:

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

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 在这个小例子中是相同的,但是当我在自己的更大的数据集上运行时,我得到了不同的结果。发生这种情况有什么原因吗?

EDIT 在查看了一些文档后,我发现DecisionTreeClassifier 有一个输入random_state,它控制着起点。通过将此值设置为常数,我摆脱了以前遇到的问题。但是现在我担心我的模型并不像它可能的那样最优。这样做的推荐方法是什么?随便试试?还是预期所有结果都差不多?

【问题讨论】:

    标签: python classification scikit-learn decision-tree


    【解决方案1】:

    我对@9​​87654321@ 一无所知,但是...

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

    你应该创建一个新的吗?

    【讨论】:

      【解决方案2】:

      DecisionTreeClassifier 的工作原理是根据某些特征的值重复拆分训练数据。 Scikit-learn 实现允许您通过为 splitter 关键字参数提供值来在几种拆分算法之间进行选择。

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

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

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

      如果您绝对必须每次都拥有一棵相同的树,那么我会重新使用相同的 random_state。否则,我希望这些树每次都会或多或少地等效,并且在没有大量保留数据的情况下,我不确定您将如何决定哪种随机树是最好的。

      另见:Source code for the splitter

      【讨论】:

        【解决方案3】:

        Matt Krause 提供的答案并未完全正确回答问题。

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

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

        因此,当使用max_features=n_features 时,每次拆分都会考虑所有特征。然而,实现仍然会从特征列表中随机采样它们(即使这意味着所有的特征都将被采样,在这种情况下)。 因此,考虑特征的顺序是伪随机的。如果两个可能的拆分并列,则遇到的第一个将用作最佳拆分。

        这正是您的决策树每次调用它都会产生不同结果的原因:所考虑的特征顺序在每个节点上是随机的,当两个可能的拆分被绑定时,要使用的拆分将取决于哪个一个被优先考虑。

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

        【讨论】:

        • 我认为在我的回答中被“随机选择一个特征”和“随机选择一个特征”所涵盖。
        • 有点,但不完全。作为用户,您期望在使用splitter=random 进行拆分时会有随机行为,但在使用splitter=best 时可能不会这么多。这是要回答的主要问题。这里的随机化来自这样一个事实,即使在max_features=n_features 时,它们也是随机抽样的(没有替换)。在您的回答中,您声明“最佳”随机选择一个特征并为其找到“最佳”可能的拆分,即使情况并非如此:它考虑了 max_features 随机特征,并选择了可能的最佳拆分.
        【解决方案4】:

        特征总是在每次拆分时随机排列。因此,即使在相同的训练数据和 max_features=n_features 的情况下,如果在搜索最佳拆分期间列举的几个拆分的标准改进相同,则找到的最佳拆分可能会有所不同。要在拟合期间获得确定性行为,必须固定 random_state。

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

        【讨论】:

          猜你喜欢
          • 2017-05-03
          • 1970-01-01
          • 2021-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-12
          • 2015-04-02
          相关资源
          最近更新 更多