You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的决策树会生成未实际划分样本的分裂?附鸢尾花数据集代码

为什么我的决策树会生成没有实际划分样本的分裂?

先把你没写完的代码补全(猜你是漏写了random_state参数):

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]] # 仅获取花瓣长度与宽度
# 我使用最大深度来避免过拟合并简化树结构,用于教学用途
clf = DecisionTreeClassifier(criterion="gini", max_depth=3, random_state=42)
clf.fit(iris_limited, iris.target)

# 可视化决策树
graph = Source(export_graphviz(clf, out_file=None, 
                feature_names=['petal length', 'petal width'],
                class_names=iris.target_names,
                filled=True, rounded=True))
graph.render("iris_tree")

咱们来拆解一下为什么会出现这种“看起来没划分样本”的分裂:

  • 样本分布的天然特性:鸢尾花的花瓣长/宽这两个特征本身区分度极强,尤其是针对setosa品种。比如某个节点里的所有样本,花瓣宽度都大于某个阈值,那算法选这个阈值做分裂点时,自然会出现一侧子节点没有样本的情况——这不是算法bug,是数据本身的分布导致的。
  • max_depth约束下的最优选择:你设置了max_depth=3,算法会在这个深度限制内,严格挑选能让节点纯度(这里用的是gini系数)提升最多的分裂方式。哪怕某个分裂会导致一侧空节点,只要它是当前节点的最优选项,算法就会执行这个分裂——毕竟它是完全按照“最小化不纯度”的逻辑来运行的。
  • sklearn的实现逻辑:sklearn的决策树在遍历所有可能的分裂选项时,不会预先过滤“会产生空节点”的阈值。只要这个分裂能降低当前节点的不纯度,就会被选中。这种看似“无效”的分裂,其实是算法严谨性的体现,它只是在执行当下最优的划分策略而已。

如果你想避免这种情况,或者更直观验证原因,可以试试这些方法:

  • 可视化时添加样本细节:在export_graphviz里加上node_ids=True, proportion=True,每个节点会显示样本数量和占比,你一眼就能明白为什么某个分裂会出现空节点。
  • 调整min_samples_split参数:比如设置min_samples_split=5,只有当节点样本数≥5时才会尝试分裂,从根源上避免因样本太少导致的空节点。
  • 绘制特征散点图:用matplotlib把两个特征的样本分布画出来,你会发现某些区域的样本是“扎堆”的,分裂阈值刚好卡在样本群的边缘,自然就把所有样本分到了一侧。

内容的提问来源于stack exchange,提问作者naiveai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:21:25