随机森林:集成学习的力量
随机森林:集成学习的力量
什么是随机森林
随机森林(Random Forest)是一种基于Bagging思想的集成学习算法。它通过构建多棵决策树,并将它们的预测结果进行汇总(投票或平均),来获得更稳定和准确的预测结果。
核心思想:"三个臭皮匠,顶个诸葛亮"——多棵树的集体智慧通常比单棵树更可靠。
随机森林的两个"随机"
- 样本随机:每棵树使用Bootstrap采样获得不同的训练子集
- 特征随机:每次分裂时只考虑随机选择的部分特征
这两个随机性机制确保了树之间的多样性,从而提升了集成效果。
集成学习类型
Bagging(Bootstrap Aggregating)
- 并行训练多棵树
- 每棵树独立预测
- 最终结果通过投票(分类)或平均(回归)得到
Boosting(提升)
- 顺序训练多棵树
- 每棵树修正前一棵的错误
- 代表算法:AdaBoost、Gradient Boosting、XGBoost
代码示例:随机森林实战
import numpy as np
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.ensemble import RandomForestClassifier, BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report
import time
import warnings
warnings.filterwarnings('ignore')
# 加载手写数字数据集
digits = load_digits()
X, y = digits.data, digits.target
print(f"数据集: {X.shape[0]}个样本, {X.shape[1]}个特征, {len(set(y))}个类别")
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# --- 单棵决策树 ---
print("=== 单棵决策树 ===")
start = time.time()
dt = DecisionTreeClassifier(random_state=42)
dt.fit(X_train, y_train)
dt_time = time.time() - start
dt_acc = accuracy_score(y_test, dt.predict(X_test))
print(f"准确率: {dt_acc:.4f}, 训练时间: {dt_time:.4f}秒")
# --- Bagging集成 ---
print("\n=== Bagging集成 (100棵树) ===")
start = time.time()
bagging = BaggingClassifier(
n_estimators=100, random_state=42, n_jobs=-1
)
bagging.fit(X_train, y_train)
bag_time = time.time() - start
bag_acc = accuracy_score(y_test, bagging.predict(X_test))
print(f"准确率: {bag_acc:.4f}, 训练时间: {bag_time:.4f}秒")
# --- 随机森林 ---
print("\n=== 随机森林 (100棵树) ===")
start = time.time()
rf = RandomForestClassifier(
n_estimators=100, # 树的数量
max_depth=None, # 不限深度
max_features='sqrt', # 每次分裂考虑sqrt(n)个特征
min_samples_split=2, # 内部节点再分裂所需最小样本数
min_samples_leaf=1, # 叶节点最少样本数
random_state=42,
n_jobs=-1 # 使用所有CPU核心
)
rf.fit(X_train, y_train)
rf_time = time.time() - start
rf_acc = accuracy_score(y_test, rf.predict(X_test))
print(f"准确率: {rf_acc:.4f}, 训练时间: {rf_time:.4f}秒")
# 交叉验证
cv_scores = cross_val_score(rf, X, y, cv=5, scoring='accuracy')
print(f"5折交叉验证: {cv_scores.mean():.4f} ± {cv_scores.std():.4f}")
# 特征重要性
print("\n=== 特征重要性(前10) ===")
importances = rf.feature_importances_
indices = np.argsort(importances)[::-1][:10]
for i, idx in enumerate(indices):
print(f" 特征{idx:2d}: {importances[idx]:.4f}")
# 不同树数量对性能的影响
print("\n=== 树数量与性能关系 ===")
n_estimators_range = [10, 25, 50, 100, 200, 300]
for n_trees in n_estimators_range:
rf_temp = RandomForestClassifier(n_estimators=n_trees, random_state=42)
cv_temp = cross_val_score(rf_temp, X, y, cv=5)
print(f" {n_trees:3d}棵树: {cv_temp.mean():.4f}")
# 详细分类报告
print("\n=== 分类报告 ===")
y_pred = rf.predict(X_test)
print(classification_report(y_test, y_pred))
关键参数调优
| 参数 | 说明 | 建议 |
|---|---|---|
| n_estimators | 树的数量 | 通常100-300,越多越稳定 |
| max_depth | 树的最大深度 | None或根据数据调整 |
| max_features | 每次分裂的特征数 | 分类用'sqrt',回归用'n' |
| min_samples_split | 内部节点最小样本数 | 防止过拟合 |
| min_samples_leaf | 叶节点最小样本数 | 防止过拟合 |
随机森林的优缺点
优点:
- 不易过拟合
- 能处理高维数据
- 可评估特征重要性
- 对缺失值和异常值鲁棒
缺点:
- 模型可解释性降低
- 训练和存储成本较高
- 对噪声较大的数据可能过拟合
总结
随机森林是实践中最常用的机器学习算法之一,因其稳定性好、调参简单而备受青睐。在大多数情况下,随机森林都能提供不错的基线性能,是机器学习从业者的必备工具。