XGBoost回归实战:从Excel数据到散点图折线图完整闭环

发布时间:2026/10/3 3:57:20
XGBoost回归实战:从Excel数据到散点图折线图完整闭环
简介基于XGBoost的数据回归预测Python代码面向机器学习初学者与应用型开发者以波士顿房价为实验对象演示从Excel加载数据、划分训练集与测试集、训练XGBoost回归模型并评估的完整流程。压缩包共5个文件包含主脚本.py、训练与测试数据集.xlsx、结果展示图.png以及说明文档.md包体仅191KB轻量易用。目前已有4293人学习/下载是快速上手梯度提升回归的实用参考。脚本运行后将生成训练集与测试集的真实值-预测值散点图并绘制测试集逐样本对比折线图同时输出均方根误差RMSE作为量化指标。借助附带数据集与README说明读者可一键复现实验也可替换为自己的Excel数据进行迁移练习适合课设、论文复现或入门机器学习项目时参考。1. 这份XGBoost回归代码从Excel到散点图折线图一次跑通的完整闭环很多人以为XGBoost是打比赛、做分类用的其实回归预测才是它最见功力的场景。你手里如果有一批历史数据存在Excel里想预测房价、销量、温度这种连续值最常见的做法就是pandas读表、XGBoost训练、再画图看拟合效果。这份代码包做的事情正好就是这个闭环boston_housing_train_data.xlsx和boston_housing_test_data.xlsx已经把波士顿房价数据拆好了训练集和测试集xgboost_regression.py加载后直接训练XGBoost回归模型最终输出三张图——训练集散点图、测试集散点图、测试集折线图外加一个RMSE均方根误差数值。适合谁刚把sklearn基础跑通、想上手XGBoost的Python数据分析新手最合适已经写过机器学习代码但懒得从零搭数据管线的熟手也能直接拿这个脚本当模板改。下面我从数据加载、模型参数、可视化细节到踩坑记录把这份代码整个拆开讲透。2. 数据准备与建模选型为什么是XGBoostExcel怎么读才对2.1 波士顿房价数据集13个特征预测一个连续值波士顿房价是回归任务里的经典数据集506个样本每个样本包含CRIM犯罪率、RM房间数、AGE房龄等13个特征目标值是MEDV自住房屋中位数价格。整套数据本质上是小样本表格数据非常契合树模型的发挥区间。这份项目里数据不是从sklearn内置接口加载的而是预先拆成了两个Excel文件。训练集和测试集已经按行分好这意味着你不需要自己再调train_test_split但代价是必须保证两个文件的特征列顺序完全一致。我第一次拿到这类拆分好的文件时习惯先打印两个表的shape确认特征列数相同再干活。import pandas as pd train_df pd.read_excel(boston_housing_train_data.xlsx) test_df pd.read_excel(boston_housing_test_data.xlsx) print(训练集 shape:, train_df.shape) print(测试集 shape:, test_df.shape) print(训练集列名:, train_df.columns.tolist()) print(测试集列名:, test_df.columns.tolist()) print(训练集空值统计:\n, train_df.isnull().sum())逻辑说明先看形状和列名能第一时间发现文件拆错了、列对不齐这类基础问题。空值统计这一步不能省XGBoost虽然自带缺失值处理但如果空值比例异常训练出来的模型会被带偏。参数说明read_excel不指定sheet_name时默认读第一个sheet如果文件里有多个sheet要写成pd.read_excel(xxx.xlsx, sheet_nameSheet1)。2.2 XGBoost回归原理为什么它对中小表格数据这么能打XGBoost全称是Extreme Gradient Boosting核心思想是不断训练决策树让后一棵树拟合前一棵树的残差。它和普通梯度提升树的关键区别在于目标函数里加了正则化项并且对损失函数做了二阶泰勒展开收敛更快、泛化更稳。对回归任务来说XGBoost默认的损失函数是平方误差回归损失。它有个很实用的特性不需要像线性回归那样做特征标准化因为树模型是分桶分裂的特征尺度不影响分裂点。对这份波士顿房价数据我直接用原始Excel字段就能训练省掉了一大段特征工程代码。import xgboost as xgb from xgboost import XGBRegressor X_train train_df.drop(columns[MEDV]) y_train train_df[MEDV] X_test test_df.drop(columns[MEDV]) y_test test_df[MEDV] model XGBRegressor( n_estimators200, max_depth4, learning_rate0.1, subsample0.8, colsample_bytree0.8, random_state42 ) model.fit(X_train, y_train)逻辑说明这里把MEDV列单独拎出来当标签其余13列全部作为特征。XGBRegressor是XGBoost封装的回归接口不需要手动把数据转成DMatrix格式适合快速验证。参数说明n_estimators200是树的数量波士顿数据只有几百个样本200棵足够max_depth4限制树的深度防止过拟合千万不要一上来就设成10subsample和colsample_bytree都是0.8意思是每棵树随机用80%的样本和80%的特征相当于自带bagging效果。3. 模型训练与核心评估RMSE怎么算两组散点图怎么画3.1 训练集和测试集的RMSE先看数值再看图训练完成后的第一件事就是算误差。RMSE均方根误差是回归任务最常用的评估指标它把预测值和真实值的差平方后取平均再开方单位跟房价本身一致能直观反映平均偏差。import numpy as np from sklearn.metrics import mean_squared_error y_train_pred model.predict(X_train) y_test_pred model.predict(X_test) rmse_train np.sqrt(mean_squared_error(y_train, y_train_pred)) rmse_test np.sqrt(mean_squared_error(y_test, y_test_pred)) print(f训练集 RMSE: {rmse_train:.4f}) print(f测试集 RMSE: {rmse_test:.4f})逻辑说明先把训练集和测试集的预测值都算出来再分别和真实标签计算RMSE。这里有个值得注意的点——如果训练集RMSE远低于测试集RMSE比如训练集1.2、测试集4.8说明模型过拟合了后面调参重点是减小max_depth、增大min_child_weight。参数说明mean_squared_error计算的是均方误差开根号后才叫RMSE保留四位小数足够看出差异实际汇报时用两位小数即可。3.2 训练集散点图和测试集散点图一张图看出过拟合散点图是回归预测最直观的体检报告横轴是真实值纵轴是预测值所有点贴在对角线yx上就是完美预测。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False fig, axes plt.subplots(1, 2, figsize(12, 5)) axes[0].scatter(y_train, y_train_pred, alpha0.6, edgecolorsk, linewidths0.3) axes[0].plot([y_train.min(), y_train.max()], [y_train.min(), y_train.max()], r--, lw1.5) axes[0].set_xlabel(真实值) axes[0].set_ylabel(预测值) axes[0].set_title(f训练集散点图 (RMSE{rmse_train:.2f})) axes[0].grid(alpha0.3) axes[1].scatter(y_test, y_test_pred, alpha0.6, edgecolorsk, linewidths0.3) axes[1].plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], r--, lw1.5) axes[1].set_xlabel(真实值) axes[1].set_ylabel(预测值) axes[1].set_title(f测试集散点图 (RMSE{rmse_test:.2f})) axes[1].grid(alpha0.3) plt.tight_layout() plt.savefig(Figure_1.png, dpi150) plt.show()逻辑说明两张子图横向并排左边训练集、右边测试集一眼就能对比。红色虚线是理想预测线点散得越窄、越贴线说明模型表现越好。alpha0.6控制点的透明度数据点密集时能避免黑乎乎一大片。参数说明edgecolorsk给散点加了黑色描边这在点很多时能显著提升区分度grid(alpha0.3)把网格调淡防止网格线抢了数据点的视觉权重dpi150保证保存的图放大不糊。提示如果两张图的点都明显偏离对角线优先检查特征是否包含了和标签同义的数据列。4. 折线图逐样本对比把平均误差还原成「哪里差、差多少」4.1 测试集折线图画法真实值序列和预测值序列叠一起散点图告诉我们整体拟合程度但看不出模型到底在哪些样本上翻车。折线图把测试集按样本序号排开真实值一条线、预测值一条线两条线贴得越近越好。num_samples len(y_test) x_idx np.arange(num_samples) plt.figure(figsize(14, 5)) plt.plot(x_idx, y_test.values, b-o, markersize3, label真实值) plt.plot(x_idx, y_test_pred, r-o, markersize3, label预测值) plt.xlabel(测试集样本序号) plt.ylabel(MEDV 房价) plt.title(f测试集真实值与预测值对比 (RMSE{rmse_test:.2f})) plt.legend() plt.grid(alpha0.3) plt.tight_layout() plt.show()逻辑说明蓝色线是真实房价红色线是模型预测值横轴是测试集的行序号。这种图的价值在于能看到局部偏差——比如某个区间两条线明显分开说明模型对那个价格段的样本学习得不够。参数说明b-o表示蓝色实线加圆点标记markersize3控制圆点大小样本量大时marker可以去掉改成b-避免点太密看不清。4.2 折线图的三种典型「病相」与因果折线图不是画完就完事的得会读。我一般看三个地方整体贴合度、峰谷是否错位、有没有系统性偏移。第一种情况预测线整体比真实线低一截大概率是特征里漏掉了某个重要驱动因素。第二种情况真实线冲到高位的时候预测线没跟上说明模型对高房价段拟合不足可以适当增加max_depth。第三种情况预测值波动得比真实值厉害出现了锯齿状通常是树数量太少或learning_rate设得太大。# 找出偏差最大的前 5 个样本 residual np.abs(y_test.values - y_test_pred) worst_idx np.argsort(residual)[-5:][::-1] for idx in worst_idx: print(f样本#{idx}: 真实值{y_test.values[idx]:.2f}, f预测值{y_test_pred[idx]:.2f}, 偏差{residual[idx]:.2f})逻辑说明计算每个样本预测值和真实值的绝对误差用argsort排序后取后五个最大偏差样本打印出来。这样能定位到具体是哪些样本拉高了RMSE。如果最差的几个样本都是高房价样本可以针对性地考虑要不要对目标值做对数变换。5. 常见问题与避坑这份代码跑起来可能遇到的四个真实坑5.1 读Excel直接报错xlrd版本冲突现象pd.read_excel(boston_housing_train_data.xlsx)执行时抛异常提示xlrd不支持xlsx格式。原因xlrd从2.0.0版本开始只支持.xls不支持.xlsx。如果你用pip install xlrd装到了最新版哪怕代码写得再对这一步也会翻车。解决用openpyxl引擎。pip install openpyxl之后把读取代码改成pd.read_excel(xxx.xlsx, engineopenpyxl)。我自己的习惯是直接只用openpyxl因为新版xlrd基本废了。5.2 散点图糊成一团黑色完全看不出趋势现象图是出来了但所有点重叠在一起看起来像一块黑板。原因数据点太密集默认的scatter设置没有透明度也没有描边点与点互相覆盖。解决设置透明度alpha0.5~0.7加描边edgecolorsk调整点的大小s20~50。如果这样还不够可以把一个子图单独放大看局部区域或者用hexbin六边形密度图替代散点图。5.3 RMSE算出来是天文数字几千上百万现象程序跑通了图也画了但RMSE输出大得离谱完全不像房价尺度。原因八成是特征里混进了和标签相关的反推列。比如Excel里同时给了MEDV和某列与MEDV线性相关的数值模型在训练集上完美拟合但测试集一换数据就崩另一种可能是drop的时候列名写错导致特征矩阵里碰巧还留着MEDV。解决打印X_train.columns.tolist()肉眼检查有没有不该出现的列名。波士顿数据集的标准做法是drop(columns[MEDV])这一行代码写错位置或写错列名后面全是白干。5.4 训练集效果好、测试集一塌糊涂现象训练集RMSE只有1.8测试集RMSE飙到6.5散点图一眼就看出过拟合。原因经典的过拟合——树太深、树太多、数据太少。波士顿只有三百多条训练样本max_depth10、n_estimators1000这种配置几乎必然过拟合。解决把max_depth降到3~5learning_rate降到0.05~0.1然后增加n_estimators配合早停。XGBoost支持early_stopping_rounds用验证集做早停判断比手动试参数靠谱得多。注意XGBoost的early_stopping_rounds参数需要配合验证集传入eval_set不是随便加个数字就能启动的。6. 往工程化走一步输出特征重要性和预测结果文件跑通这份回归代码只是起点真正要把它用到实际项目里我一般会再加两步打印特征重要性、把预测结果导回Excel。import pandas as pd importance model.feature_importances_ feat_names X_train.columns.tolist() feat_imp_df pd.DataFrame({ 特征: feat_names, 重要性: importance }).sort_values(重要性, ascendingFalse) print(\n特征重要性 Top5:) print(feat_imp_df.head(5).to_string(indexFalse)) result_df pd.DataFrame({ 真实值: y_test.values, 预测值: y_test_pred, 绝对误差: residual }) result_df.to_excel(prediction_result.xlsx, indexFalse)逻辑说明feature_importances_是XGBoost模型训练完成后自带的属性按特征被用于分裂的增益加权统计得出。把这它和特征名拼成DataFrame排序能快速看出哪些字段对房价预测贡献最大。预测结果导出到Excel则方便给下游业务同事核验。从那以后我每次跑回归模型不管任务多急都强制自己走一遍这个流程先打印特征重要性再导出预测文件。一来是逼着自己理解模型、别当黑匣子用二来是对方万一说“你这个预测不对”我可以翻出文件逐条对账。XGBoost这份资源的核心价值不是帮你调出完美模型而是给你一个能稳定复现的基线——后续换数据、换特征、换模型都能拿它当参照物对比效果。希望帮到你。本文还有配套的精品资源点击获取