sklearn ensemble.RandomForestClassifier详解

sklearn.ensemble.RandomForestClassifier 是 scikit-learn 中最常用的集成学习分类器之一,基于Bagging + 决策树构建。下面从原理、参数、属性、方法到实战做一个系统详解。


一、核心原理

随机森林 = 多棵决策树 + 随机性 + 投票

  1. Bootstrap 采样:从原始数据集中有放回地抽取 n_samples 个样本,训练每棵树。
  2. 特征随机:每次分裂时,只从随机选取的 max_features 个特征中找最优分裂点。
  3. 投票集成:分类任务用多数投票,回归任务用均值。

为什么有效?

  • Bagging 降低方差(variance),多棵不相关的树平均后泛化更强。
  • 特征随机进一步降低树之间的相关性。
  • 对噪声和过拟合有较强鲁棒性。

二、构造函数与主要参数

from sklearn.ensemble import RandomForestClassifier

RandomForestClassifier(
    n_estimators=100,
    criterion='gini',
    max_depth=None,
    min_samples_split=2,
    min_samples_leaf=1,
    min_weight_fraction_leaf=0.0,
    max_features='sqrt',
    max_leaf_nodes=None,
    min_impurity_decrease=0.0,
    bootstrap=True,
    oob_score=False,
    n_jobs=None,
    random_state=None,
    verbose=0,
    warm_start=False,
    class_weight=None,
    ccp_alpha=0.0,
    max_samples=None,
    monotonic_cst=None,
)

关键参数分组说明

1. 森林规模

参数 含义 建议
n_estimators 树的数量 越大越稳,但收益递减;常用 100~500
n_jobs 并行核数 -1 用全部 CPU

2. 单棵树结构(与 DecisionTree 相同)

参数 含义
criterion 'gini' / 'entropy' / 'log_loss'
max_depth 最大深度,控制过拟合
min_samples_split 内部节点再分裂所需最小样本数
min_samples_leaf 叶节点最小样本数
max_leaf_nodes 最大叶节点数
min_impurity_decrease 分裂所需最小不纯度下降
ccp_alpha 代价复杂度剪枝参数,越大剪枝越强

3. 随机性控制(随机森林特有)

参数 含义
max_features 每次分裂考虑的特征数。分类默认 'sqrt',回归默认 1.0。可选 'log2'、整数、浮点
bootstrap 是否有放回采样,默认 True
max_samples bootstrap=True 时,每棵树抽取的样本数
random_state 随机种子,保证可复现

4. 评估与类别处理

参数 含义
oob_score 是否用袋外样本评估,True 时训练后可用 oob_score_
class_weight None / 'balanced' / 'balanced_subsample' / 字典,处理类别不平衡
warm_start True 时可在已有森林上继续加树

三、主要属性

训练后(fit 之后)可访问:

属性 含义
estimators_ 所有决策树列表
classes_ 类别标签数组
n_classes_ 类别数
n_features_in_ 输入特征数
feature_importances_ 特征重要性(基于不纯度减少,归一化后和为 1)
oob_score_ 袋外评分(需 oob_score=True
oob_decision_function_ 袋外预测概率
n_outputs_ 输出维度

四、主要方法

fit(X, y)                          # 训练
predict(X)                         # 预测类别
predict_proba(X)                   # 预测各类概率
predict_log_proba(X)               # 对数概率
score(X, y)                        # 返回准确率
apply(X)                           # 返回每个样本落在每棵树的叶节点索引
decision_path(X)                   # 返回决策路径稀疏矩阵
set_params(**params)               # 设置参数
get_params(deep=True)              # 获取参数

五、完整实战示例

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
import matplotlib.pyplot as plt

# 1. 数据
data = load_breast_cancer()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, stratify=y, random_state=42
)

# 2. 基础模型(带 OOB 评估)
rf = RandomForestClassifier(
    n_estimators=300,
    max_depth=None,
    max_features='sqrt',
    min_samples_leaf=1,
    oob_score=True,
    class_weight='balanced',
    n_jobs=-1,
    random_state=42,
)
rf.fit(X_train, y_train)

print("OOB Score:", rf.oob_score_)
y_pred = rf.predict(X_test)
print("Test Accuracy:", rf.score(X_test, y_test))
print(classification_report(y_test, y_pred))
print("ROC-AUC:", roc_auc_score(y_test, rf.predict_proba(X_test)[:, 1]))

# 3. 特征重要性
importances = rf.feature_importances_
idx = np.argsort(importances)[::-1]
plt.figure(figsize=(10, 6))
plt.bar(range(len(idx)), importances[idx])
plt.xticks(range(len(idx)), data.feature_names[idx], rotation=90)
plt.title("Feature Importances")
plt.tight_layout()
plt.show()

# 4. 网格搜索调参
param_grid = {
    'n_estimators': [200, 400],
    'max_depth': [None, 10, 20],
    'min_samples_split': [2, 5],
    'min_samples_leaf': [1, 2],
    'max_features': ['sqrt', 'log2'],
}
gs = GridSearchCV(
    RandomForestClassifier(random_state=42, n_jobs=-1),
    param_grid, cv=5, scoring='roc_auc', n_jobs=-1, verbose=1
)
gs.fit(X_train, y_train)
print("Best params:", gs.best_params_)
print("Best CV AUC:", gs.best_score_)
print("Test AUC:", roc_auc_score(y_test, gs.best_estimator_.predict_proba(X_test)[:, 1]))

六、调参经验总结

目标 调整方向
提高精度 增加 n_estimators;调 max_depthmin_samples_leaf
缓解过拟合 减小 max_depth,增大 min_samples_leaf/min_samples_split,增大 ccp_alpha
缓解欠拟合 增大 max_depth,减小 min_samples_leaf,增大 max_features
加快训练 减小 n_estimators,增大 min_samples_*n_jobs=-1
类别不平衡 class_weight='balanced''balanced_subsample'
高维稀疏数据 增大 max_features(如 0.3~0.5

常见默认组合n_estimators=500, max_features='sqrt', min_samples_leaf=1, oob_score=True


七、优缺点

优点

  • 精度高、鲁棒性强,几乎不需要精细调参即可用。
  • 能处理高维数据、缺失值(部分场景)、混合类型特征。
  • 提供特征重要性,可解释性比 boosting 类模型稍好。
  • 天然支持并行(n_jobs),OOB 可免费做验证。

缺点

  • 模型体积大、预测比单棵树慢。
  • 对噪声特别大的回归任务可能过拟合。
  • 特征重要性对高基数类别特征有偏(偏向取值多的特征)。
  • 外推能力差(树模型通病,回归时无法预测训练集范围外的值)。

八、与相关模型对比

模型 偏差 方差 特点
单棵决策树 易过拟合
随机森林 Bagging,并行,稳定
ExtraTrees 更低 分裂阈值也随机,更快
GradientBoosting/XGBoost 更低 Boosting,串行,精度常更高但调参更敏感

如果你需要,我可以进一步展开:

  • feature_importances_ 的计算细节与 permutation importance 对比
  • ExtraTreesClassifierHistGradientBoostingClassifier 的选型
  • 处理类别不平衡的完整方案
  • apply() + 逻辑回归做 stacking 特征
posted @ 2026-09-16 09:17  AceFenix  阅读(9)  评论(0)    收藏  举报