共计 1997 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点分析
决策树作为机器学习中最直观的算法之一,初学者常会遇到两个关键问题:

-
特征选择困惑 :信息增益(ID3)和基尼系数(CART)都是常用标准,但新手往往不理解它们的数学本质差异。信息增益倾向于选择取值多的特征,而基尼系数对类别分布更敏感。
-
过拟合问题 :未经剪枝的决策树会生成复杂的树结构,在训练集上表现完美但测试集性能骤降。典型表现是决策边界出现不合理的锯齿状分裂。
算法对比
| 算法 | 分裂标准 | 支持特征类型 | 适用场景 |
|---|---|---|---|
| ID3 | 信息增益 | 仅分类特征 | 小规模离散数据 |
| C4.5 | 信息增益比 | 分类 + 连续 | 存在噪声数据 |
| CART | 基尼系数 / 方差 | 分类 + 连续 | 回归和分类任务 |
核心原理实现
信息增益计算
信息熵定义:
$$H(D) = -\sum_{k=1}^K p_k \log_2 p_k$$
特征 A 对数据集 D 的信息增益:
$$Gain(D,A) = H(D) – \sum_{v=1}^V \frac{|D^v|}{|D|}H(D^v)$$
Python 代码实现
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def train_decision_tree(
criterion: str = 'gini',
max_depth: int = 3
) -> DecisionTreeClassifier:
"""
训练决策树分类器
Parameters
----------
criterion : str
分裂标准 ('gini'/'entropy')
max_depth : int
树的最大深度
Returns
-------
DecisionTreeClassifier
训练好的模型实例
"""
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
clf = DecisionTreeClassifier(
criterion=criterion,
max_depth=max_depth,
random_state=42
)
clf.fit(X_train, y_train)
return clf
# 示例调用
model = train_decision_tree(criterion='entropy', max_depth=3)
生产实践技巧
预剪枝效果演示
通过调整 max_depth 参数观察模型复杂度变化:
import matplotlib.pyplot as plt
from sklearn.metrics import accuracy_score
depths = range(1, 10)
train_scores = []
test_scores = []
for depth in depths:
model = train_decision_tree(max_depth=depth)
train_scores.append(accuracy_score(y_train, model.predict(X_train)))
test_scores.append(accuracy_score(y_test, model.predict(X_test)))
plt.plot(depths, train_scores, label='Train')
plt.plot(depths, test_scores, label='Test')
plt.xlabel('Max Depth')
plt.ylabel('Accuracy')
plt.legend()
特征重要性可视化
importances = model.feature_importances_
features = ['sepal length', 'sepal width', 'petal length', 'petal width']
plt.barh(features, importances)
plt.xlabel('Feature Importance')
plt.ylabel('Features')
避坑指南
- 类别不平衡处理 :
- 使用 class_weight 参数调整类别权重
-
对少数类样本进行过采样
-
深度调试经验 :
- 二分类问题建议初始尝试深度 3 -5
- 特征较多时可设置 max_leaf_nodes 控制复杂度
延伸思考
-
超参数优化 :
from sklearn.model_selection import GridSearchCV params = {'max_depth': [3,5,7], 'min_samples_split': [2,5,10] } grid_search = GridSearchCV(DecisionTreeClassifier(), params, cv=5) -
连续特征处理 :
- CART 算法通过排序后寻找最佳分裂点
- 实际应用中建议先做分箱处理
正文完
发表至: 未分类
近三天内
