共计 1808 个字符,预计需要花费 5 分钟才能阅读完成。
核心概念
C&RT(Classification and Regression Trees)决策树的核心是Gini 系数,用于衡量节点的不纯度。计算公式为:

$$ Gini(t) = 1 – \sum_{i=1}^{C} (p(i|t))^2 $$
其中 $p(i|t)$ 是节点 $t$ 中类别 $i$ 的占比。分裂时选择使 Gini 系数下降最多的特征和阈值,即最大化:
$$ \Delta Gini = Gini(parent) – \left(\frac{N_{left}}{N} Gini(left) + \frac{N_{right}}{N} Gini(right) \right) $$
痛点分析
- 类别不平衡:少数类样本容易被忽略,导致模型偏差
- 过拟合:树深度过大时捕获噪声,泛化性能下降
- 高基数特征:如用户 ID 这类特征会主导分裂过程
技术方案
1. 基础模型实现
from sklearn.tree import DecisionTreeClassifier
# 关键参数说明:# max_depth:防止过拟合
# min_samples_split:节点继续分裂的最小样本数
model = DecisionTreeClassifier(criterion='gini',
max_depth=5,
min_samples_split=20)
2. 超参数调优
from sklearn.model_selection import GridSearchCV
param_grid = {'max_depth': [3, 5, 7],
'min_samples_leaf': [1, 5, 10]
}
grid_search = GridSearchCV(model, param_grid, cv=5)
grid_search.fit(X_train, y_train)
3. 特征选择
from sklearn.inspection import permutation_importance
result = permutation_importance(model, X_test, y_test, n_repeats=10)
sorted_idx = result.importances_mean.argsort()
完整代码示例
数据预处理
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
num_pipe = Pipeline([('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
cat_pipe = Pipeline([('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
可视化决策树
import graphviz
from sklearn.tree import export_graphviz
dot_data = export_graphviz(model, feature_names=feature_names,
class_names=class_names,
filled=True, rounded=True)
graph = graphviz.Source(dot_data)
graph.render('decision_tree')
模型持久化
import joblib
joblib.dump(model, 'crt_model.pkl')
# 加载模型
model = joblib.load('crt_model.pkl')
生产环境建议
- 内存优化:
- 限制
max_depth在 5 - 8 之间 -
设置
min_samples_leaf≥50 -
稳定性保障:
- 固定
random_state(如random_state=42) -
对类别特征强制使用 one-hot 编码
-
监控方案:
- 计算 PSI(Population Stability Index)检测特征分布漂移
- 定期重新计算 permutation importance
性能对比
| 模型 | 准确率 | 推理速度(ms/ 样本) | 内存占用(MB) |
|---|---|---|---|
| C&RT | 0.82 | 0.15 | 12 |
| 随机森林 | 0.85 | 0.28 | 45 |
| XGBoost | 0.86 | 0.22 | 38 |
思考题
- 如何处理包含 1000+ 取值的类别特征(如城市名称)?
- 当决策树在测试集表现良好但生产环境性能下降时,可能是什么原因?
正文完
