Day 84:【99天精通Python】机器学习进阶 - 决策树与随机森林
·
Day 84:【99天精通Python】机器学习进阶 - 决策树与随机森林
前言
欢迎来到第84天!
逻辑回归是一个线性模型,它试图用一条直线(或超平面)来划分数据。但如果数据的边界是弯弯曲曲的,线性模型就无能为力了。
决策树 (Decision Tree) 是一种强大的非线性模型。它通过一系列 if/else 的问题来对数据进行划分,非常符合人类的决策逻辑。
而 随机森林 (Random Forest) 则是决策树的"威力加强版",通过"集体投票"的方式大大提升了模型的稳定性和准确性。
本节内容:
- 决策树原理 (信息熵 / 基尼不纯度)
- 训练与可视化决策树
- 随机森林:集成学习的力量
- 特征重要性分析
- 实战练习:泰坦尼克号生还预测
一、决策树原理
决策树的目标是找到一系列"最优"的切分点。比如判断一个人是否会买电脑:
- 年龄 > 30 吗?
- 是学生吗?
- 收入 > 1万吗?
它会选择能让数据最"纯"的划分方式(比如按年龄划分后,一边全是"买",另一边全是"不买")。这个"纯度"通常用信息熵或基尼不纯度来衡量。
二、训练与可视化
我们继续使用鸢尾花数据集。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree
import matplotlib.pyplot as plt
# 加载数据 (3分类问题)
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
# 1. 创建模型
# max_depth=3: 限制树的最大深度,防止过拟合
model = DecisionTreeClassifier(max_depth=3)
# 2. 训练
model.fit(X_train, y_train)
print(f"准确率: {model.score(X_test, y_test):.2f}")
# 3. 可视化决策树
plt.figure(figsize=(15, 10))
plot_tree(model,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True, # 填充颜色
rounded=True)
# plt.show()
三、随机森林:三个臭皮匠,顶个诸葛亮
单个决策树容易过拟合 (Overfitting),即在训练数据上表现完美,但在新数据上表现很差。
随机森林是一种集成学习 (Ensemble Learning) 方法。它通过构建很多棵不同的决策树,然后让它们投票决定最终结果。
- 随机体现在两方面:
- 行采样 (Bootstrap):每棵树只用一部分随机抽样的训练数据。
- 列采样 (Feature Sampling):每次分裂时,只考虑一部分随机选择的特征。
这保证了每棵树都是"片面的",但把它们组合起来就非常强大且稳定。
3.1 训练随机森林
from sklearn.ensemble import RandomForestClassifier
# n_estimators=100: 森林里有 100 棵树
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)
print(f"随机森林准确率: {rf_model.score(X_test, y_test):.2f}")
四、特征重要性 (Feature Importance)
随机森林还有一个好处:它可以告诉我们哪些特征对预测结果最重要。
import pandas as pd
# 获取特征重要性
importances = rf_model.feature_importances_
# 组合成 DataFrame
feature_importance_df = pd.DataFrame({
'feature': iris.feature_names,
'importance': importances
}).sort_values('importance', ascending=False)
print(feature_importance_df)
# 结果通常是花瓣长度/宽度最重要
五、实战:泰坦尼克号生还预测
这是一个经典的 Kaggle 入门赛题。我们需要根据乘客信息(年龄、性别、舱位)预测他是否能生还。
5.1 数据准备
import seaborn as sns
import pandas as pd
# 1. 加载数据
titanic = sns.load_dataset('titanic')
# 2. 数据清洗与特征工程
# 填充缺失值
titanic['age'].fillna(titanic['age'].median(), inplace=True)
titanic.dropna(subset=['embarked'], inplace=True)
# 将分类变量转为数值 (独热编码 One-Hot)
titanic = pd.get_dummies(titanic, columns=['sex', 'embarked'], drop_first=True)
# 3. 选择特征
features = ['pclass', 'age', 'sibsp', 'parch', 'fare', 'sex_male', 'embarked_Q', 'embarked_S']
target = 'survived'
X = titanic[features]
y = titanic[target]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
5.2 训练与评估
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
model.fit(X_train, y_train)
print(f"生还预测准确率: {model.score(X_test, y_test):.2f}")
# 约 0.81
# 查看特征重要性
pd.Series(model.feature_importances_, index=features).sort_values().plot(kind='barh')
plt.title("Feature Importances")
# plt.show()
# 结果显示:性别(sex_male)最重要,其次是票价和年龄。
六、常见问题
Q1:决策树和随机森林哪个好?
- 决策树:速度快,结果易于解释(可以画图)。但容易过拟合。
- 随机森林:精度高,抗过拟合能力强。但计算量大,且是个"黑盒"(无法解释内部逻辑)。
通常情况下,首选随机森林。
Q2:max_depth 参数是什么?
树的最大深度。如果不限制,树会无限生长直到每个叶子节点都"纯净",这极易导致过拟t合。它是最重要的超参数 (Hyperparameter) 之一。
Q3:random_state 是什么?
随机种子。设置它能保证你每次运行代码时,随机采样的结果都是一样的,方便复现实验。
七、小结
关键要点:
- 随机森林是分类问题中最常用、最稳健的算法之一。
- 特征重要性分析能帮你理解数据。
- 处理分类变量时,记得用 One-Hot 编码 (
pd.get_dummies)。
八、课后作业
- 调参:在泰坦尼克号案例中,尝试调整
n_estimators和max_depth,看看能否获得更高的准确率。 - 回归树:决策树和随机森林不仅能做分类,也能做回归(
DecisionTreeRegressor,RandomForestRegressor)。尝试用它们来解决波士顿房价预测问题,并与线性回归对比。 - XGBoost (进阶):学习另一个更强大的集成模型 XGBoost (
pip install xgboost),它是各大 Kaggle 比赛的刷分神器。
下节预告
Day 85:机器学习进阶 - 支持向量机 (SVM) - 找到那条"最宽的路"来划分数据。明天我们学习另一个经典的分类算法 SVM。
系列导航:
- 上一篇:Day 83 - 机器学习进阶逻辑回归
- 下一篇:Day 85 - 支持向量机SVM(待更新)
更多推荐


所有评论(0)