共计 1385 个字符,预计需要花费 4 分钟才能阅读完成。
为什么选择基尼系数?
决策树分裂时需要衡量数据的不纯度,最常用的两个指标是信息熵(Entropy)和基尼系数(Gini Index)。它们的数学定义如下:

- 信息熵:$H(D) = -\sum_{k=1}^K p_k \log_2 p_k$
- 基尼系数:$Gini(D) = 1 – \sum_{k=1}^K p_k^2$
实际工程中 CART 树默认选择基尼系数,主要因为:
- 计算效率更高(省去了对数运算)
- 对类别分布不均匀时更敏感
- 在 sklearn 的基准测试中,基尼系数训练速度比熵快 15%-20%
基尼系数的实现优化
原始实现需要遍历所有类别计算概率平方和,通过 numpy 向量化可以显著加速:
import numpy as np
def gini_impurity(y: np.ndarray) -> float:
"""计算基尼不纯度(向量化版本)"""
if len(y) == 0:
return 0.0
p = np.bincount(y) / len(y)
return 1 - np.sum(p ** 2)
# 时间复杂度分析:# - bincount: O(n)
# - 平方和计算: O(k) k 为类别数
# 总复杂度: O(n + k)
sklearn 实战配置
关键参数配置示例(以 iris 数据集为例):
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
iris = load_iris()
clf = DecisionTreeClassifier(
criterion='gini', # 显式指定基尼系数
max_depth=3, # 防止过拟合
min_samples_split=10, # 节点最小样本数
class_weight='balanced' # 处理类别不平衡
)
clf.fit(iris.data, iris.target)
调参经验:
max_depth:从 3 开始逐步增加,观察验证集精度min_samples_split:对于大数据集建议设为 0.1%-1% 总样本量- 使用
class_weight调整类别权重比手动过采样更高效
生产环境优化策略
高维特征处理
当特征维度超过 1000 时:
- 先进行方差筛选(VarianceThreshold)
- 用
max_features='sqrt'限制每步考虑的特征数 - 使用 GPU 加速实现(如 lightgbm)
类别不平衡场景
除了设置class_weight,还可以:
- 在计算基尼系数时加入类别权重因子
- 对少数类样本进行 SMOTE 过采样
- 改用 AUC 作为评估指标
决策树可视化
安装 graphviz 后生成解释图:
from sklearn.tree import export_graphviz
import graphviz
dot_data = export_graphviz(
clf,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True
)
graphviz.Source(dot_data)
图中颜色越深表示该节点纯度越高,通过 clf.feature_importances_ 可以获取特征重要性排序。
开放问题讨论
在基尼系数接近 0.5(完全随机)时:
– 强制停止分裂可以防止过拟合
– 但可能丢失潜在的模式
实际建议结合验证集表现决定,而不是单纯依赖阈值。
(注:完整代码和 UCI 数据集测试结果见 GitHub 仓库)
正文完
