使用Scikit-learn包训练基于随机森林的回归器模型

举报
yd_37369233 发表于 2026/07/30 09:57:21 2026/07/30
【摘要】 一、引言在机器学习领域,回归任务的目标是预测一个连续值——比如房价、温度或销量。单棵决策树虽然直观易懂,但容易过拟合,对训练数据中的噪声过于敏感。随机森林(Random Forest)正是为了解决这个问题而生的——它不靠“一棵树”单打独斗,而是用“多棵树”集体决策,通过集成学习的方式显著提升预测的稳定性和准确性。随机森林是一种基于Bagging(Bootstrap Aggregating)...

一、引言

在机器学习领域,回归任务的目标是预测一个连续值——比如房价、温度或销量。单棵决策树虽然直观易懂,但容易过拟合,对训练数据中的噪声过于敏感。随机森林(Random Forest)正是为了解决这个问题而生的——它不靠“一棵树”单打独斗,而是用“多棵树”集体决策,通过集成学习的方式显著提升预测的稳定性和准确性。

随机森林是一种基于Bagging(Bootstrap Aggregating)思想的集成学习算法,通过在训练过程中引入双重随机性来降低模型方差:

  • 样本随机采样:每棵树使用有放回抽样(Bootstrap)从原始数据集中抽取不同的子样本;
  • 特征随机子集:每次节点分裂时,仅从随机选取的部分特征中寻找最优划分。

在回归任务中,随机森林的每棵决策树都会输出一个具体的数值预测,最终将所有树的预测值取算术平均作为模型的最终输出。这种“集体智慧”既保留了决策树处理非线性关系的能力,又有效控制了过拟合风险。

二、RandomForestRegressor 核心参数

Scikit-learn 的 RandomForestRegressor 提供了丰富的超参数,以下是最关键的几个:

参数 默认值 说明
n_estimators 100 森林中决策树的数量。值越大模型越稳定,但训练时间也越长
criterion ‘squared_error’ 分裂质量评估函数。可选 ‘squared_error’(均方误差)、‘absolute_error’(绝对误差)、‘friedman_mse’、‘poisson’
max_depth None 每棵树的最大深度。None 表示节点会一直扩展直到所有叶子纯化或达到最小样本数
min_samples_split 2 内部节点分裂所需的最小样本数
min_samples_leaf 1 叶子节点的最小样本数
max_features 1.0 每次分裂时考虑的最大特征数。常用 ‘sqrt’ 或 ‘log2’
bootstrap True 是否使用自助采样(有放回抽样)
random_state None 随机种子,设置后可保证结果可复现
n_jobs None 并行计算使用的CPU核心数,-1 表示使用所有核心
oob_score False 是否使用袋外样本(out-of-bag)进行模型评估

三、完整建模流程

下面我们以 Scikit-learn 内置的 California Housing 数据集为例,演示从数据加载到模型训练、评估的完整流程。

3.1 导入所需库

import numpy as np
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import matplotlib.pyplot as plt
import seaborn as sns

3.2 加载并探索数据

# 加载加州住房数据集
housing = fetch_california_housing()
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = pd.Series(housing.target, name='MedHouseVal')

print(f"特征数量: {X.shape[1]}")
print(f"样本数量: {X.shape[0]}")
print(X.head())

该数据集包含8个特征,如收入中位数、房龄、平均房间数等,目标变量是街区房价中位数(单位:十万美元)。

3.3 划分训练集和测试集

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
print(f"训练集大小: {X_train.shape[0]}")
print(f"测试集大小: {X_test.shape[0]}")

3.4 创建并训练随机森林回归模型

# 创建模型实例
rf_model = RandomForestRegressor(
    n_estimators=100,      # 100棵决策树
    max_depth=10,          # 限制树的最大深度,防止过拟合
    min_samples_split=5,   # 内部节点分裂最少需要5个样本
    min_samples_leaf=2,    # 叶子节点最少需要2个样本
    n_jobs=-1,             # 使用所有CPU核心并行计算
    random_state=42,       # 固定随机种子保证可复现
    oob_score=True         # 启用袋外评估
)

# 训练模型
rf_model.fit(X_train, y_train)
print("模型训练完成!")

这里的关键参数设置思路:

  • n_estimators=100 是一个常用的起点,可根据数据规模和计算资源在50-500之间调整;
  • max_depth=10 限制了树的深度,避免单棵树过度拟合训练数据;
  • min_samples_splitmin_samples_leaf 进一步控制了树的生长粒度。

3.5 模型预测与评估

# 在测试集上进行预测
y_pred = rf_model.predict(X_test)

# 计算评估指标
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print("=== 模型评估结果 ===")
print(f"均方误差 (MSE): {mse:.4f}")
print(f"均方根误差 (RMSE): {rmse:.4f}")
print(f"平均绝对误差 (MAE): {mae:.4f}")
print(f"决定系数 (R²): {r2:.4f}")

# 袋外评分(如果启用了oob_score)
if hasattr(rf_model, 'oob_score_'):
    print(f"袋外评分 (OOB Score): {rf_model.oob_score_:.4f}")

评估指标解读:

  • MSE / RMSE:值越小,预测误差越小;
  • MAE:反映了预测值与真实值的平均绝对偏差;
  • R²(决定系数) :取值范围0到1,越接近1表示模型对目标变量变异的解释能力越强。

3.6 特征重要性分析

随机森林的一大优势是可以天然提供特征重要性评估。feature_importances_ 属性返回每个特征的重要性分数,数值越大表示该特征对预测越关键。

# 获取特征重要性
importances = rf_model.feature_importances_
feature_names = housing.feature_names

# 创建特征重要性DataFrame并排序
importance_df = pd.DataFrame({
    '特征': feature_names,
    '重要性': importances
}).sort_values('重要性', ascending=False)

print("\n=== 特征重要性排序 ===")
print(importance_df)

# 可视化特征重要性
plt.figure(figsize=(10, 6))
sns.barplot(data=importance_df, x='重要性', y='特征')
plt.title('随机森林回归模型 - 特征重要性')
plt.xlabel('重要性分数')
plt.tight_layout()
plt.show()

3.7 模型持久化保存

训练好的模型可以通过 joblib 保存到磁盘,方便后续直接加载使用,无需重新训练:

import joblib

# 保存模型
joblib.dump(rf_model, 'random_forest_regressor.pkl')
print("模型已保存为 random_forest_regressor.pkl")

# 加载模型
# loaded_model = joblib.load('random_forest_regressor.pkl')
# predictions = loaded_model.predict(X_new)

四、超参数调优(进阶)

默认参数通常不是最优的,可以通过网格搜索(GridSearchCV) 系统地寻找最佳超参数组合:

from sklearn.model_selection import GridSearchCV

# 定义参数搜索空间
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [None, 10, 20, 30],
    'min_samples_split': [2, 5, 10],
    'max_features': ['sqrt', 'log2']
}

# 创建网格搜索对象(5折交叉验证)
grid_search = GridSearchCV(
    RandomForestRegressor(random_state=42),
    param_grid,
    cv=5,
    scoring='r2',
    n_jobs=-1,
    verbose=1
)

# 执行搜索
grid_search.fit(X_train, y_train)

print(f"最佳参数组合: {grid_search.best_params_}")
print(f"最佳交叉验证R²: {grid_search.best_score_:.4f}")

# 使用最佳模型进行预测
best_model = grid_search.best_estimator_
y_pred_best = best_model.predict(X_test)
print(f"测试集R²: {r2_score(y_test, y_pred_best):.4f}")
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。