杰瑞科技汇

Python XGBoost回归如何提升预测精度?

XGBoost 回归的核心思想

XGBoost 回归的目标是学习一个函数 F(x),使得预测值 ŷ = F(x) 与真实值 y 之间的误差(通常是平方误差)最小化。

Python XGBoost回归如何提升预测精度?-图1
(图片来源网络,侵删)

其核心是梯度提升

  1. 初始模型:它会学习一个非常简单的模型,比如一个常数,这个常数通常是所有目标值的平均值。
  2. 迭代改进:它会进行多轮迭代,在每一轮 m 中:
    • 计算当前模型 F_{m-1}(x) 在所有样本上的预测残差(即真实值 y 减去预测值 F_{m-1}(x))。
    • 训练一棵新的决策树,但这棵树的目标不是预测 y,而是预测上一轮模型的残差
    • 将这棵新树乘以一个学习率(learning_rate,也叫 eta)后,加到现有模型上,得到新的模型 F_m(x) = F_{m-1}(x) + learning_rate * new_tree
  3. 最终模型:经过多轮迭代后,最终的模型是所有这些简单树的加权和。

这种“残差-修正”的思想使得模型能够逐步修正错误,从而不断提升预测精度。


环境准备

你需要安装 XGBoost 库,如果尚未安装,可以通过 pip 进行安装:

pip install xgboost

你还需要一些常用的数据科学库:

Python XGBoost回归如何提升预测精度?-图2
(图片来源网络,侵删)
pip install numpy pandas scikit-learn matplotlib

完整代码示例(从加载到评估)

下面是一个完整的端到端示例,展示如何使用 XGBoost 进行回归。

第 1 步:导入必要的库

import xgboost as xgb
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import matplotlib.pyplot as plt

第 2 步:准备数据

我们使用 Scikit-learn 自带的波士顿房价数据集作为示例。注意:这个数据集因伦理问题在新版 Scikit-learn 中已被移除,但如果你使用旧版或单独下载,仍然可以使用,这里我们用 fetch_openml 来获取一个类似的数据集。

# 从 OpenML 获取波士顿房价数据集
# 如果使用旧版 scikit-learn,可以直接: from sklearn.datasets import load_boston
boston = fetch_openml(name='boston', version=1, as_frame=True)
df = pd.DataFrame(boston.data, columns=boston.feature_names)
df['PRICE'] = boston.target
# 查看数据
print("数据前5行:")
print(df.head())
print("\n数据描述:")
print(df.describe())
# 准备特征和目标变量
X = df.drop('PRICE', axis=1)
y = df['PRICE']
# 划分训练集和测试集
# test_size=0.2 表示20%的数据作为测试集
# random_state 确保每次划分结果一致,便于复现
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print(f"\n训练集大小: {X_train.shape}")
print(f"测试集大小: {X_test.shape}")

第 3 步:创建和训练 XGBoost 回归模型

XGBoost 提供了两种主要的接口:XGBRegressor(类似 Scikit-learn 的 API)和 xgb.train(更底层、更灵活的 API),这里我们主要介绍 XGBRegressor,因为它更符合 Scikit-learn 的使用习惯。

# 1. 初始化模型
# XGBRegressor 是用于回归任务的 XGBoost 模型
xgb_reg = xgb.XGBRegressor(
    objective='reg:squarederror',  # 指定学习任务和相应的学习目标
    n_estimators=100,             # 树的数量(即迭代次数)
    learning_rate=0.1,            # 学习率/步长
    max_depth=5,                  # 树的最大深度
    subsample=0.8,                # 用于训练每棵树的样本比例
    colsample_bytree=0.8,         # 用于训练每棵树的特征比例
    random_state=42               # 随机种子,保证结果可复现
)
# 2. 训练模型
# 使用训练数据来拟合模型
print("\n开始训练模型...")
xgb_reg.fit(X_train, y_train)
print("模型训练完成!")

关键参数解释

Python XGBoost回归如何提升预测精度?-图3
(图片来源网络,侵删)
  • objective: 回归任务必须设置为 reg:squarederror,表示使用平方误差作为损失函数。
  • n_estimators: 模型中包含的树的数量,越多模型越复杂,但过拟合风险也越大。
  • learning_rate: 控制每棵树对最终模型的贡献,值越小,模型越稳健,但需要更多的树才能收敛。
  • max_depth: 单棵树的最大深度,控制树的复杂度。
  • subsamplecolsample_bytree: 引入随机性,防止过拟合,类似于随机森林中的采样。

第 4 步:进行预测

# 使用训练好的模型对测试集进行预测
y_pred = xgb_reg.predict(X_test)

第 5 步:模型评估

回归任务中常用的评估指标包括:

  • 均方误差: 预测值与真实值之差的平方的平均值,对大误差的惩罚更重。
  • 平均绝对误差: 预测值与真实值之差的绝对值的平均值,更容易解释。
  • R² 分数 (决定系数): 表示模型对数据方差的解释程度,范围在 0 到 1 之间,越接近 1 表示模型拟合得越好。
# 计算评估指标
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("\n模型评估结果:")
print(f"均方误差: {mse:.4f}")
print(f"均方根误差: {rmse:.4f}")
print(f"平均绝对误差: {mae:.4f}")
print(f"R² 分数: {r2:.4f}")

第 6 步:结果可视化

将真实值与预测值进行对比,可以直观地看到模型的性能。

# 创建一个散点图来对比真实值和预测值
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.7)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], '--r', linewidth=2)
plt.xlabel('真实房价')
plt.ylabel('预测房价')'真实房价 vs. 预测房价')
plt.grid(True)
plt.show()

如果模型完美,所有点都会落在红色虚线上,点越接近红线,说明模型预测越准确。


使用 xgb.train 的进阶用法

xgb.train 提供了更多的自定义选项,通常用于追求极致性能的场景。

# 1. 将数据转换为 DMatrix
# DMatrix 是 XGBoost 优化过的数据结构,速度更快
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)
# 2. 设置参数
# 注意:这里的参数格式是字典
params = {
    'objective': 'reg:squarederror',
    'max_depth': 5,
    'eta': 0.1,  # learning_rate 的别名
    'subsample': 0.8,
    'colsample_bytree': 0.8,
    'seed': 42
}
# 3. 训练模型
# num_boost_round 等同于 n_estimators
evals = [(dtrain, 'train'), (dtest, 'test')] # 用于监控训练和测试集的性能
xgb_model = xgb.train(
    params,
    dtrain,
    num_boost_round=100,
    evals=evals,
    early_stopping_rounds=10, # 如果连续10轮测试集性能没有提升,就提前停止训练
    verbose_eval=10          # 每10轮打印一次日志
)
# 4. 进行预测
y_pred_train = xgb_model.predict(dtrain)
y_pred_test = xgb_model.predict(dtest)
# 5. 评估
print("\n使用 xgb.train 训练的模型评估结果:")
print(f"测试集 R² 分数: {r2_score(y_test, y_pred_test):.4f}")

early_stopping_rounds 是一个非常实用的参数,它可以自动找到最优的迭代次数,防止过拟合。


模型调优

XGBoost 的性能很大程度上依赖于超参数的设置,常用的调优方法有:

  • 网格搜索: GridSearchCV
  • 随机搜索: RandomizedSearchCV

下面是一个使用 GridSearchCV 的例子:

from sklearn.model_selection import GridSearchCV
# 定义要搜索的参数网格
param_grid = {
    'n_estimators': [50, 100, 200],
    'learning_rate': [0.01, 0.1, 0.2],
    'max_depth': [3, 5, 7],
    'subsample': [0.8, 1.0]
}
# 初始化模型
xgb_reg = xgb.XGBRegressor(objective='reg:squarederror', random_state=42)
# 初始化 GridSearchCV
# cv=3 表示3折交叉验证
# scoring='neg_mean_squared_error' 使用MSE作为评估指标,GridSearchCV会最大化这个值(即最小化MSE)
grid_search = GridSearchCV(
    estimator=xgb_reg,
    param_grid=param_grid,
    cv=3,
    scoring='neg_mean_squared_error',
    verbose=1,
    n_jobs=-1  # 使用所有可用的CPU核心
)
# 执行网格搜索
print("\n开始进行网格搜索...")
grid_search.fit(X_train, y_train)
# 输出最佳参数和最佳分数
print("\n网格搜索完成!")
print("最佳参数:", grid_search.best_params_)
print("最佳MSE分数:", -grid_search.best_score_)
# 使用最佳模型进行预测
best_model = grid_search.best_estimator_
y_pred_best = best_model.predict(X_test)
print(f"\n最佳模型在测试集上的 R² 分数: {r2_score(y_test, y_pred_best):.4f}")
步骤 关键操作 代码示例
准备数据 加载、划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(...)
创建模型 初始化 XGBRegressor xgb_reg = xgb.XGBRegressor(objective='reg:squarederror', ...)
训练模型 使用 fit() 方法 xgb_reg.fit(X_train, y_train)
进行预测 使用 predict() 方法 y_pred = xgb_reg.predict(X_test)
评估模型 计算 MSE, MAE, R² 等 r2_score(y_test, y_pred)
调优模型 使用 GridSearchCVRandomizedSearchCV GridSearchCV(estimator, param_grid, ...)

XGBoost 是一个非常强大的工具,掌握了以上基本流程和核心概念,你就可以用它来解决各种回归问题了,随着你对它理解的深入,还可以探索更高级的特性,如自定义损失函数、特征重要性分析等。

分享:
扫描分享到社交APP
上一篇
下一篇