参数设置
重置
右子节点的样本数固定为 100。左子比例 = leftN / (leftN + 100)。
不纯度曲线与分裂的树形图
上:横轴 = p1,三条曲线(蓝 = Gini、绿 = 熵、红 = 误分类率)/ 下:父节点到子节点的分裂树形图
理论与主要公式
二分类(p1 = 类别 1 的比例,p2 = 1 − p1)的三种不纯度指标:
$$G = 2 p_1 p_2 = 2 p_1 (1 - p_1)$$
Shannon 熵(以 2 为底,在 p1 = 0 或 1 时取 H = 0):
$$H = -p_1 \log_2 p_1 - p_2 \log_2 p_2$$
误分类率:
$$ME = \min(p_1, p_2)$$
父节点到子节点分裂的信息增益:
$$IG = I(\text{parent}) - \sum_k \frac{|S_k|}{|S|} I(S_k)$$
三者都在 p1 = 0.5 处取最大值:Gini = 0.5,熵 = 1.0,ME = 0.5。
决策树不纯度模拟器是什么
🙋
决策树我大致理解为「一堆 if 语句堆起来」。这里说的「不纯度」到底是什么意思?
🎓
大致来说,它衡量一个节点中的样本「类别有多混乱」。一个节点里苹果和橘子各占一半,就「不纯」;几乎全是苹果的节点就「纯」。决策树每次分裂数据,都是想让这个不纯度尽可能下降。把模拟器里的「父节点类别 1 比例 p1」从 0.5 移到 0 或 1 看——Gini、熵和误分类率全部下降。
🙋
真的诶,三条曲线都在 0.5 处达到峰值,两端为零。但是 Gini(蓝)和熵(绿)是圆弧形的山,误分类率(红)是三角形的山,这是为什么?
🎓
这正是重点。Gini 和熵是平滑的「凹函数」,误分类率是分段线性的——在 p1 = 0.5 处有折角。在计算信息增益时,凹函数能保证「只要分裂就一定会有非负的增益」。误分类率是折线,所以即便分裂提高了纯度,增益也常常为零。因此 CART 和 ID3 都不把误分类率用作分裂准则。剪枝评估时用一下倒可以。
🙋
下面树形图里显示的 IG_Gini 就是「信息增益」吗?父 0.500 减去子节点加权 0.320 得到 0.180 那种。
🎓
就是这样。公式是 IG = I(父) − Σ (|S_k|/|S|) · I(子_k),把子节点的不纯度按样本数加权平均,再用父节点减去。在默认设置下(左 leftP1=0.8、右 rightP1=0.2),左右子节点都分别偏向一个类,纯度上升,所以 IG 较大。试试把左右的 p1 都设成 0.5——IG 会几乎为零。意思就是「分了也没增加任何信息」。
🙋
scikit-learn 的 DecisionTreeClassifier 默认是 criterion='gini'。为什么不是 entropy 而是 gini?
🎓
在实际中两者选出的分裂几乎一样——论文报告通常只差几个百分点。那就用更快的 Gini:熵需要 log2,Gini 只需要两次乘法。所以 CART 把 Gini 设为默认。ID3 和 C4.5 走的是熵(信息增益)路线。实际项目调参时,稳妥的做法是两个都试一下,比较交叉验证分数。
常见问题
为什么 Gini 不纯度的最大值是 0.5?
二分类下,G = 2·p1·p2 = 2·p1·(1−p1),是 p1 的二次函数,在 p1=0.5 处取得最大值 2·0.5·0.5 = 0.5。推广到 K 类时最大值为 1 − 1/K:二类是 0.5,三类是 2/3,十类是 0.9。Gini 可以解释为「随机抽两个样本属于不同类别的概率」。
熵的单位是 bit 吗?
单位取决于对数的底。log2 得到的单位是 bit,自然对数(ln)是 nat,log10 是 dit。决策树和大多数机器学习文献都使用 log2,单位是 bit:二类下最大值为 1 bit,K 类均匀分布下的最大值为 log2(K) bit。本模拟器使用 log2,二类的最大值是 1.0。
什么是信息增益比(Gain Ratio)?
把信息增益 IG 用「分裂信息(Split Information)」做归一化的指标。Gain Ratio = IG / SplitInfo,SplitInfo 是分裂分支数与大小的熵。原始 IG 会过度奖励取值数多的属性(例如客户 ID),C4.5 用 Gain Ratio 校正这种偏置。CART 始终是二叉分裂,分支数恒为 2,这个问题相对轻微。
类别不平衡数据可以用不纯度吗?
可以用,但要小心。在极端不平衡(如 99:1)下,Gini 与熵本身就小,不分裂也能看上去「很纯」。scikit-learn 中常用 class_weight='balanced',按反频率给每类加权,把少数类被误分的代价提高。另外结合 SMOTE 等过采样,以及 F1、AUC 等评估指标一起使用,也是常见做法。
实际应用
scikit-learn、XGBoost、LightGBM: Python 主流机器学习库内部都用 Gini 或熵来评估分裂。scikit-learn 的 DecisionTreeClassifier 默认 criterion='gini',XGBoost、LightGBM 等梯度提升树本质上也遵循同样的原理。本模拟器中你体会到的「分裂使不纯度下降」的感觉,正是这些库内部正在做的事。
信用评分与授信判断: 金融行业广泛使用决策树和随机森林。对「年收入」「在职年限」「过去违约次数」等属性进行分裂,把违约概率高与低的群体分离开来。「Gini 指数」在经济学中也用来衡量收入差距——基本概念是相通的。
医疗诊断与疾病预测: 从症状和检查值预测疾病的辅助诊断系统中,可解释的决策树很受青睐。「体温 > 38 度怀疑流感,再加上咳嗽则……」这类分支与医生的临床推理过程接近,不纯度的下降直观上对应「症状把诊断范围缩小到什么程度」。
制造业缺陷判定与质量控制: 从传感器数据自动判定不良品的系统中也常用决策树。「温度 > 80 度且振动 > 3.0 G 则为不良」这样的明确规则,现场操作员也很容易理解判定依据。本模拟器中「左子节点纯度高的分裂」,在现场就对应着「把不良品干净分离出来的好准则」。
常见误解与注意事项
最常见的误解是认为「选 Gini 还是熵会显著影响模型性能」 。实际上两个指标的曲线形状非常相似,分裂结果通常只相差几个百分点。scikit-learn 官方文档也写着 "There is no clear empirical evidence to suggest that one is better than the other"。重要的不是选哪个,而是认真调好其它超参数:树的深度(max_depth)、叶子最小样本数(min_samples_leaf)、剪枝强度(ccp_alpha)等。在模拟器里移动 p1 把两条曲线对照看,相似性一目了然。
其次常见的错误是想用误分类率作为分裂准则 。人会想:「最终目的不就是减少误分类吗?那就选误分类率最小的分裂呗。」但在模拟器里把左右子节点的 p1 设成 0.4 和 0.6 这种不对称值。Gini 给出正的信息增益,而误分类率的增益可能为零。原因是误分类率是分段线性的,缺少凹函数那种对分裂的敏感度。误分类率不适合作为分裂准则,但适合作为剪枝的评估指标。
最后请注意,信息增益大并不一定就是好分裂 。举个极端例子:给每个样本一个唯一的 ID,按 "ID=1 走左,ID=2 走右……" 分裂的话,每个叶子都是纯的,IG 取得最大值,但模型完全不能泛化。C4.5 的 Gain Ratio、CART 的最小样本数约束、梯度提升的正则化项,都是为了「抑制导致过拟合的分裂」。本模拟器中的 IG 是理论值,实际项目中务必配合交叉验证或测试集评估。