
接上一篇《七天学完十大机器学习经典算法-02.逻辑回归:从概率到决策的智慧》
本文是机器学习可解释性最强的算法,通过医疗诊断、金融风控等真实案例,揭示决策树如何像人类一样逐步推理。无需数学公式,初中生也能轻松理解!
想象你要判断是否贷款给某人:
年收入 > 50万?
→ 是 → 查看信用分
→ 信用分 > 700?
→ 是 → 批准
→ 否 → 拒绝
→ 否 → 查看抵押物
→ 有房产?
→ 是 → 批准
→ 否 → 拒绝这正是决策树的工作方式! 它通过一系列是/否问题模拟人类决策过程。
行业应用统计:
特征 | 好瓜(1) | 坏瓜(0) |
|---|---|---|
纹理 | ||
清晰 | 8 | 2 |
模糊 | 1 | 9 |
敲声 | ||
清脆 | 9 | 1 |
沉闷 | 2 | 8 |
人类决策逻辑:

案例计算(买瓜数据集):
Entropy = - [0.5*log₂(0.5) + 0.5*log₂(0.5)] = 1

纹理特征的信息增益:
![Gain = 1 - [ (10/20)*0.72 + (10/20)*0.47 ] = 0.405](https://developer.qcloudimg.com/http-save/yehe-100000/7006db552778679309c74f102348e935.png)
![Gain = 1 - [ (10/20)*0.47 + (10/20)*0.72 ] = 0.405](https://developer.qcloudimg.com/http-save/yehe-100000/319057a469ebbd1d74b95b95e8e72817.png)
发现:纹理和敲声增益相同?此时需用基尼系数作为第二标准!
from sklearn.tree import DecisionTreeClassifier
# 关键参数
model = DecisionTreeClassifier(
max_depth=3, # 树的最大深度
min_samples_split=10, # 节点继续分裂的最小样本数
min_samples_leaf=5, # 叶节点的最小样本数
max_features=5 # 每次分裂考虑的最大特征数
)import pandas as pd
from sklearn.tree import plot_tree
# 加载数据
titanic = pd.read_csv("titanic.csv")
print(titanic.columns)
# ['PassengerId','Survived','Pclass','Name','Sex','Age','SibSp','Parch','Ticket','Fare','Cabin','Embarked']# 1. 提取有用特征
features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
# 2. 处理缺失值
titanic['Age'].fillna(titanic['Age'].median(), inplace=True)
# 3. 类别特征编码
titanic['Sex'] = titanic['Sex'].map({'male':0, 'female':1})
titanic = pd.get_dummies(titanic, columns=['Embarked'])
# 4. 创建决策树模型
X = titanic[['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked_C','Embarked_Q','Embarked_S']]
y = titanic['Survived']model = DecisionTreeClassifier(max_depth=3, random_state=42)
model.fit(X, y)
# 可视化决策树(需安装graphviz)
plt.figure(figsize=(15,10))
plot_tree(model,
feature_names=X.columns,
class_names=['Died','Survived'],
filled=True,
rounded=True)
plt.savefig('titanic_tree.png')
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(
n_estimators=100, # 100棵决策树
max_depth=5,
max_features=3, # 每棵树随机选3个特征
random_state=42
)
rf.fit(X_train, y_train)
print("准确率:", rf.score(X_test, y_test)) # 通常比单棵树高5-10%分箱处理:将连续变量离散化
titanic['AgeGroup'] = pd.cut(titanic['Age'],
bins=[0,12,18,60,100],
labels=['Child','Teen','Adult','Elder'])组合特征:挖掘特征间关系
titanic['FamilySize'] = titanic['SibSp'] + titanic['Parch']
titanic['IsAlone'] = (titanic['FamilySize'] == 0).astype(int)# 调整类别权重
model = DecisionTreeClassifier(
class_weight={0:1, 1:2} # 更关注少数类(生存者)
)
# 或使用SMOTE过采样
from imblearn.over_sampling import SMOTE
smote = SMOTE()
X_res, y_res = smote.fit_resample(X, y)# 代价复杂度剪枝
model = DecisionTreeClassifier(ccp_alpha=0.02) # 越大剪枝越狠
# 剪枝效果对比
plt.figure()
model.fit(X_train, y_train)
plot_tree(model) # 对比未剪枝的树更简洁真相:对连续变量分裂有影响!
# 错误做法:直接使用未标准化的年龄和票价
# 正确方案:标准化连续特征
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X[['Age','Fare']] = scaler.fit_transform(X[['Age','Fare']])解决方案:
# 方法1:分裂时增加缺失值分支
model = DecisionTreeClassifier(splitter='best')
# 方法2:用模型预测缺失值
from sklearn.impute import KNNImputer
imputer = KNNImputer()
X_imputed = imputer.fit_transform(X)过拟合风险:深度=10的树在训练集准确率99%,测试集仅70%
调试技巧:
# 绘制学习曲线
train_scores, test_scores = [], []
depths = range(1, 15)
for depth in depths:
model.set_params(max_depth=depth)
model.fit(X_train, y_train)
train_scores.append(model.score(X_train, y_train))
test_scores.append(model.score(X_test, y_test))
# 找到测试集峰值对应的深度
optimal_depth = depths[np.argmax(test_scores)]场景 | 推荐算法 | 决策树优势 |
|---|---|---|
需要模型解释性 | 决策树 | 可视化决策路径 |
高维稀疏数据 | 线性模型 | 不受特征维度影响 |
图像/语音识别 | 深度学习 | 处理非结构化数据更强 |
金融风控 | 随机森林 | 更高的准确率和稳定性 |

# 完整项目代码
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
# 加载数据集
data = pd.read_csv('diabetes.csv')
# 特征选择
features = ['Pregnancies','Glucose','BloodPressure','SkinThickness',
'Insulin','BMI','DiabetesPedigreeFunction','Age']
X = data[features]
y = data['Outcome']
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 创建模型
model = DecisionTreeClassifier(
max_depth=4,
min_samples_leaf=5,
class_weight='balanced'
)
# 训练与评估
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))
# 特征重要性可视化
plt.barh(features, model.feature_importances_)
plt.title('Feature Importance')关键输出:
precision recall f1-score support
0 0.83 0.85 0.84 107
1 0.68 0.65 0.67 52
accuracy 0.78 159人类思考的算法映射:决策树将人类分步决策的过程数学化,是连接人脑与AI的桥梁
创作不易,如有收获请点🌟收藏加关注,谢谢各位兄弟,祝前程似锦!!
!
下期预告:《七天学完十大机器学习经典算法-04.随机森林:群众智慧的机器学习实践》