为什么我的决策树创建了一个实际上没有划分样本的分割?

时间:2018-04-28 14:25:03

标签: python python-3.x machine-learning scikit-learn decision-tree

这是我对众所周知的Iris数据集进行双重特征分类的基本代码:

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from graphviz import Source

iris = load_iris()
iris_limited = iris.data[:, [2, 3]] # This gets only petal length & width.

# I'm using the max depth as a way to avoid overfitting
# and simplify the tree since I'm using it for educational purposes
clf = DecisionTreeClassifier(criterion="gini",
                             max_depth=3,
                             random_state=42)

clf.fit(iris_limited, iris.target)

visualization_raw = export_graphviz(clf, 
                                    out_file=None,
                                    special_characters=True,
                                    feature_names=["length", "width"],
                                    class_names=iris.target_names,
                                    node_ids=True)

visualization_source = Source(visualization_raw)
visualization_png_bytes = visualization_source.pipe(format='png')
with open('my_file.png', 'wb') as f:
    f.write(visualization_png_bytes)

当我检查树的可视化时,我发现了这个:

Tree visualization result

乍一看这是一棵相当普通的树,但我注意到它有些奇怪。节点#6总共有46个样本,其中只有一个是多色的,因此该节点被标记为virginica。这似乎是一个相当合理的地方。但是,由于某些原因我无法理解,算法决定进一步分裂为节点#7和#8。但奇怪的是,仍然在那里的1个杂色仍然被错误分类,因为无论如何两个节点最终都有弗吉尼亚的类。它为什么这样做?它是否盲目地只关注基尼的减少,而不考虑它是否有所作为 - 这对我来说似乎很奇怪,我无法在任何地方找到它。

是否可以禁用,或者这实际上是否正确?

1 个答案:

答案 0 :(得分:2)

为什么要这样做?

因为它提供了有关样本类的更多信息。你是对的,这种分裂不会改变任何预测的结果,但现在模型更加确定。考虑节点#8中的样本:在分割之前,模型大约98%对这些样本是弗吉尼亚州有信心。然而,分裂后,模型说这些样品肯定是维吉尼亚。

是否盲目地只关注基尼的减少,而不考虑它是否有所作为

默认情况下,DecisionTree会继续拆分,直到所有叶节点都是纯粹的。有一些参数影响分裂行为。但是,它没有明确考虑拆分节点是否会在预测标签方面产生影响。

是否可以禁用,或者这实际上是否正确?

如果split生成具有相同标签的两个叶节点,我认为没有办法强制DecisionTreeClassifier不拆分。但是,通过仔细设置min_samples_leaf和/或min_impurity_decrease参数,您可以实现类似的功能。