1. 决策树分类:像老师一样一步步做判断
决策树(Decision Tree)是机器学习中最直观易懂的算法之一,它模拟人类做决策时的思考过程——就像老师批改试卷时,会按照"先看总分→检查重点题型→分析错误类型"这样的步骤层层判断。在Python中,我们可以用scikit-learn库快速实现这一算法。以下是完整实现代码:
from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier, export_text # 加载鸢尾花数据集 iris = load_iris() X, y = iris.data, iris.target # 创建深度为3的决策树 clf = DecisionTreeClassifier(max_depth=3, random_state=42) clf.fit(X, y) # 输出决策规则 tree_rules = export_text(clf, feature_names=iris['feature_names']) print(tree_rules)运行后会输出类似这样的判断规则:
|--- petal width (cm) <= 0.80 | |--- class: 0 |--- petal width (cm) > 0.80 | |--- petal width (cm) <= 1.75 | | |--- petal length (cm) <= 4.95 | | | |--- class: 1 | | |--- petal length (cm) > 4.95 | | | |--- class: 2 | |--- petal width (cm) > 1.75 | | |--- petal length (cm) <= 4.85 | | | |--- class: 2 | | |--- petal length (cm) > 4.85 | | | |--- class: 21.1 决策树的核心原理
决策树通过递归地选择最优特征进行数据划分,其核心是信息增益的计算。以判断水果类型为例:
首先计算整个数据集的熵(混乱程度):
import math # 假设有10个苹果和10个香蕉 entropy = - (0.5 * math.log2(0.5) + 0.5 * math.log2(0.5)) # 结果为1然后计算按不同特征划分后的信息增益:
- 按颜色划分:红色组(8苹果2香蕉),绿色组(2苹果8香蕉)
- 红色组熵 = - (0.8log2(0.8) + 0.2log2(0.2)) ≈ 0.72
- 绿色组熵 ≈ 0.72
- 信息增益 = 原始熵 - (10/200.72 + 10/200.72) = 0.28
选择信息增益最大的特征作为当前节点的划分标准
注意:scikit-learn默认使用基尼系数而非信息增益,但原理类似,都是衡量数据纯度的指标
1.2 关键参数解析
决策树的超参数会显著影响模型表现,以下是几个关键参数:
| 参数 | 说明 | 推荐设置 |
|---|---|---|
| max_depth | 树的最大深度 | 3-10(根据数据复杂度) |
| min_samples_split | 节点分裂的最小样本数 | 2-5 |
| min_samples_leaf | 叶节点的最小样本数 | 1-3 |
| max_features | 考虑的最大特征数 | 'auto'(默认√n_features) |
| criterion | 分裂标准 | 'gini'或'entropy' |
# 更健壮的参数设置示例 clf = DecisionTreeClassifier( max_depth=5, min_samples_split=4, min_samples_leaf=2, max_features='sqrt', random_state=42 )2. 决策树可视化实战
2.1 图形化展示决策树
安装graphviz工具后,可以用以下代码生成可视化树:
from sklearn.tree import export_graphviz import graphviz dot_data = export_graphviz( clf, out_file=None, feature_names=iris.feature_names, class_names=iris.target_names, filled=True, rounded=True ) graph = graphviz.Source(dot_data) graph.render("iris_tree") # 生成PDF文件2.2 可视化效果优化技巧
限制显示深度:
export_graphviz(..., max_depth=3)添加特征重要性标记:
for name, importance in zip(iris.feature_names, clf.feature_importances_): print(f"{name}: {importance:.2f}")使用dpi参数提高分辨率:
graph.render("iris_tree", format='png', dpi=300)
常见问题:如果遇到Graphviz报错,请确保已安装系统级graphviz软件(brew install graphviz / apt-get install graphviz)
3. 决策树实战进阶技巧
3.1 处理类别型特征
决策树天然支持数值型特征,对于类别型特征需要编码:
from sklearn.preprocessing import OrdinalEncoder # 假设有颜色特征['红','绿','蓝'] encoder = OrdinalEncoder(categories=[['红','绿','蓝']]) X_encoded = encoder.fit_transform(X)3.2 防止过拟合的策略
后剪枝(Cost Complexity Pruning):
path = clf.cost_complexity_pruning_path(X, y) ccp_alphas = path.ccp_alphas # 选择最优alpha clf_pruned = DecisionTreeClassifier(ccp_alpha=optimal_alpha)交叉验证选择最优深度:
from sklearn.model_selection import GridSearchCV params = {'max_depth': range(3,10)} grid = GridSearchCV(clf, params, cv=5) grid.fit(X, y)
3.3 决策树的优缺点对比
优势:
- 白盒模型,规则直观可解释
- 不需要特征缩放
- 支持混合特征类型
- 对异常值不敏感
局限:
- 容易过拟合(需剪枝)
- 对数据微小变化敏感
- 可能产生偏向性(倾向选择多值特征)
4. 决策树在真实场景中的应用
4.1 金融风控案例
在贷款审批中,决策树可以构建这样的规则:
1. 信用评分 > 650? ├─ 是 → 2 └─ 否 → 拒绝 2. 月收入/月供 > 3? ├─ 是 → 通过 └─ 否 → 3 3. 抵押物价值 > 贷款金额? ├─ 是 → 通过 └─ 否 → 拒绝4.2 医疗诊断系统
使用决策树判断糖尿病风险:
# 使用Pima Indians Diabetes数据集 from sklearn.tree import DecisionTreeClassifier import pandas as pd data = pd.read_csv('diabetes.csv') X = data.drop('Outcome', axis=1) y = data['Outcome'] clf = DecisionTreeClassifier(max_depth=4) clf.fit(X, y) # 最重要的三个特征: # 1. 葡萄糖耐量测试结果 # 2. BMI指数 # 3. 年龄4.3 工业异常检测
在生产线质量控制中,可以构建:
1. 温度是否在[20,25]℃? ├─ 否 → 异常 └─ 是 → 2 2. 压力是否<100kPa? ├─ 是 → 正常 └─ 否 → 3 3. 流速是否>5L/min? ├─ 是 → 异常 └─ 否 → 正常5. 决策树集成方法
5.1 随机森林实现
from sklearn.ensemble import RandomForestClassifier rf = RandomForestClassifier( n_estimators=100, max_features='sqrt', oob_score=True, random_state=42 ) rf.fit(X, y) print(f"OOB Score: {rf.oob_score_:.3f}")5.2 Gradient Boosting决策树
from sklearn.ensemble import GradientBoostingClassifier gbdt = GradientBoostingClassifier( n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42 ) gbdt.fit(X, y)5.3 模型解释工具SHAP
import shap explainer = shap.TreeExplainer(rf) shap_values = explainer.shap_values(X) # 可视化单个预测解释 shap.force_plot(explainer.expected_value[0], shap_values[0][0,:], X.iloc[0,:])决策树在实际应用中最大的价值在于其可解释性。我曾在一个银行项目中用决策树规则替代了部分黑盒模型,不仅满足了监管要求,业务人员也能直接理解拒绝贷款的具体原因。对于刚接触机器学习的新手,建议从决策树开始理解机器学习的基本思想,再逐步过渡到更复杂的模型。