简介基于XGBoost的数据回归预测Python代码演示在波士顿房价数据集上完成回归建模与可视化面向机器学习初学者和需要快速上手XGBoost回归的开发者覆盖Excel数据加载、训练集/测试集划分、模型训练与评估并输出真实值与预测值对比的散点图以及测试集逐样本折线图同时给出均方根误差RMSE。压缩包共5个文件包含2个Excel数据集、1个Python脚本、1张示例结果图和1个说明文档大小仅191KB结构清晰便于直接复现项目已有4297人学习下载。具体来说Python脚本完成数据读取、模型训练、预测评估和绘图展示全流程两个散点图分别呈现训练集与测试集的真实值-预测值分布折线图则逐样本对比测试集预测效果便于直观发现误差较大的样本。通过这份代码可掌握XGBoost回归的标准流程理解散点图和折线图在回归效果分析中的具体用法提供可替换的Excel数据入口适合课程设计、科研实验或业务预测等场景稍作修改即可迁移到其他回归任务。1. XGBoost 回归不是黑匣子一份能直接跑的房价预测代码拿到一份回归任务特征几十列、样本几千行线性回归欠拟合神经网络又嫌数据量不够这时候 XGBoost 是最稳的选择。这份资源就是一个完整的 XGBoost 回归示例Python 脚本、训练和测试两个 Excel 文件、README跑通后自动出两张散点图一张折线图还带上 RMSE 指标。适合两类人一是刚学机器学习、想在一个小数据集上把 XGBoost 全流程走一遍的新手二是业务侧要做回归基线、又不想从零写数据预处理和可视化的从业者。整个流程不是调包侠式的一行预测数据加载、拆分、训练、评估、绘图的每一步都是明摆着的改数据就能复用。2. 数据入口从 Excel 到训练集和测试集的拆分拿到这个压缩包解压后先看文件清单xgboost_regression.py是主脚本boston_housing_train_data.xlsx是训练数据boston_housing_test_data.xlsx是测试数据Figure_1.png是脚本运行后生成的示例图README.md里写了最基础的运行方式。这里的数据文件不是常见的 CSV而是 Excel 格式这点值得先聊。2.1 为什么这份代码选择 Excel 作为数据载体很多入门教程习惯用 CSV 加载数据因为pd.read_csv()一行就能读进来。但在实际业务里数据交接经常发生在 Excel 里——业务同事导出的报表、清洗后的中间表很多时候就是.xlsx。XGBoost 回归脚本直接用 Excel 加载省去了「先转 CSV 再读」的中间步骤也避免了 CSV 转码时中文表头乱码的问题。读取 Excel 的常见做法是用 pandas 的pd.read_excel()依赖库是openpyxl或xlrd。在跑这份脚本之前先确认环境里装好了这三个包pip install xgboost pandas openpyxl matplotlib这里注意openpyxl不能漏。只装了 pandas 没装 openpyxlread_excel遇到.xlsx后缀会直接抛ImportError。这个坑在第五章还会细说。装完之后在脚本所在目录执行python xgboost_regression.py正常输出会看到训练开始、RMSE 数值然后弹出或保存图形窗口。2.2 pandas 读取 Excel 的字段约定脚本里读取数据的代码大致是这样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(训练集形状:, train_df.shape) print(测试集形状:, test_df.shape) print(训练集列名:, train_df.columns.tolist())read_excel默认读取第一个 sheet表头默认取第一行。如果你的 Excel 文件表头不在第一行需要加header参数如果文件里有多个 sheet需要加sheet_name参数指定。打印shape和columns是拿到数据后必做的一步——先确认列名符合预期再往下走否则后面特征列名对不上模型训练直接报错或者结果完全失真。这份数据集的标签列通常是文件名里暗示的房价中位数那一列脚本里一般会把特征矩阵命名为X、标签命名为y。从训练集和测试集分开存放这个设计就能看出这份资源的拆分逻辑是「原始数据已经按业务口径分好」不是从同一个文件里随机切分。2.3 训练集和测试集的保留策略很多初学者习惯把数据加载进来之后再用train_test_split随机切一次。但这份资源不是这么设计的——它直接把两个 Excel 当成训练集和测试集。这种做法在业务上是合理的测试集往往是「最新的时间窗」或「独立采集的样本」不能混进训练集参与拟合否则时序泄漏会高估模型效果。如果你想把两份数据合并后重新随机划分代码可以这样改import pandas as pd from sklearn.model_selection import train_test_split train_df pd.read_excel(boston_housing_train_data.xlsx) test_df pd.read_excel(boston_housing_test_data.xlsx) df pd.concat([train_df, test_df], axis0, ignore_indexTrue) X df.drop(columns[target]) y df[target] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 )random_state42是固定随机种子保证每次运行切分的样本一致方便复现。test_size0.2表示测试集占 20%。如果业务场景是时间序列建议别用随机切分改成按时间排序后取前 80% 训练、后 20% 测试。从这两份 Excel 的命名看数据已经分好了直接用它原本的拆分更省事也更能验证「没见过的新样本」上的表现。3. 模型核心XGBoost 回归参数怎么设、怎么调数据加载完成之后脚本进入核心环节——初始化 XGBoost 回归器并训练。这个环节也是新手最容易囫囵吞枣的地方只知道调用XGBRegressor()但里面的参数到底在干什么、调到什么值合理需要逐个说清楚。3.1 回归任务的目标函数选择XGBoost 的分类和回归共用一套框架区别在objective参数。这份脚本做的是回归目标函数用的是reg:squarederror也就是平方误差损失。选它是因为回归任务的默认场景就是最小化预测值和真实值的平方差RMSE 指标和它是直接对上的。初始化模型的代码大致如下import xgboost as xgb model xgb.XGBRegressor( objectivereg:squarederror, n_estimators300, max_depth6, learning_rate0.1, subsample0.8, colsample_bytree0.8, random_state42 )这里的n_estimators300是树的数量max_depth6是每棵树的最大深度learning_rate0.1是学习率subsample0.8表示每轮迭代随机采样 80% 的样本colsample_bytree0.8表示每棵树随机使用 80% 的特征。objective指定为reg:squarederror之后模型内部计算的就是均方误差的梯度和eval_metric里设置 RMSE 可以搭配使用。这几个参数是 XGBoost 最常用的核心参数初学者照着设一般不会出大问题但要知道它们各自控制什么。3.2 参数组合的优先级先树深后学习率调参最忌讳一上来就网格搜索全部参数。我一般会遵循一个优先级先固定n_estimators和learning_rate再调max_depth和min_child_weight最后调subsample和colsample_bytree。因为树的复杂度深度、叶子节点权重直接影响过拟合而采样比例是在复杂度定下来之后做正则化收尾。如果训练集很小几千行以内max_depth设 6 可能偏大容易把训练集记死。遇到这种情况先把max_depth降到 4加一个min_child_weight参数model xgb.XGBRegressor( objectivereg:squarederror, n_estimators500, max_depth4, learning_rate0.05, min_child_weight5, subsample0.8, colsample_bytree0.8, random_state42 )min_child_weight5的含义是叶子节点的样本权重之和至少为 5低于这个值就不再分裂相当于给树生长设了最小样本门槛。学习率降到 0.05 之后树的数量相应增加到 500因为学习率越低每棵树的贡献越小需要更多棵树来拟合。这个组合在中小数据集上比默认参数稳得多。3.3 fit 与 predict 的完整流程训练和预测的代码是这份脚本的骨架model.fit(X_train, y_train) y_train_pred model.predict(X_train) y_test_pred model.predict(X_test)fit传入特征矩阵和标签XGBoost 内部会做特征重要性统计、树结构学习并保留训练过程中的历史信息。predict返回一个一维数组长度和输入的行数一致。这里有一个隐藏细节X_train和X_test的列顺序必须完全一致否则predict的结果在特征对齐上会出问题。pandas 的 DataFrame 如果列顺序不同模型不会报错但每棵树在做分裂判断时用的特征不对结果就废了。如果你想把训练过程中的中间指标打出来可以用eval_set配合early_stopping_roundsmodel.fit( X_train, y_train, eval_set[(X_train, y_train), (X_test, y_test)], verboseFalse )eval_set传入验证集列表模型会在每轮迭代后计算验证集的误差。early_stopping_rounds这一项在这个场景里值得注意——如果你用了早停后续predict用的是最佳迭代轮数的模型而不是最后一轮。在测试集上评估时这一点能明显影响最终 RMSE。4. 可视化验证散点图和折线图把误差画在明面上训练完模型脚本会生成两张散点图和一张折线图。这部分是整个资源里最直观的价值点不用只看 RMSE 一个数字图能告诉你模型在哪些区间表现好、哪些区间系统性偏了。4.1 散点图真实值和预测值的对角线关系散点图的横轴是真实值纵轴是预测值。如果模型完美拟合所有点应该落在y x这条对角线上。点越贴近对角线预测误差越小点在对角线下方说明预测值偏低点在上方说明预测值偏高。绘制训练集散点图的代码一般是这样的结构import matplotlib.pyplot as plt plt.figure(figsize(6, 5)) plt.scatter(y_train, y_train_pred, alpha0.5, labelTrain) plt.plot([y_train.min(), y_train.max()], [y_train.min(), y_train.max()], r--, linewidth1, labelyx) plt.xlabel(True Value) plt.ylabel(Predicted Value) plt.title(Train: True vs Predicted) plt.legend() plt.tight_layout() plt.savefig(Figure_train_scatter.png, dpi150)alpha0.5控制点的透明度样本重叠多的时候能看出密度分布。红色的虚线是对角线参考线方便肉眼判断偏离方向。plt.tight_layout()防止坐标轴标签被裁剪保存图时dpi150保证放大后不糊。训练集上通常点会很贴对角线因为模型见过这些样本如果训练集上就大片偏离说明模型欠拟合或者特征没选对。测试集的散点图逻辑完全一致只是换成y_test和y_test_pred。注意测试集的散点图更有参考价值因为它反映的是模型在未见数据上的真实表现。如果训练集贴线、测试集偏离明显那就是过拟合了需要回到第三章的参数组合降低max_depth或增大min_child_weight。如果你用的是交互式环境Jupyter Notebookplt.show()会直接内嵌显示但脚本运行时savefig更可靠不会因为图形窗口阻塞而卡住。.png格式通用性最好论文和汇报都用得上。4.2 折线图逐样本的误差形态折线图的画法和散点图不同它把测试集的每个样本按顺序排开横轴是样本序号纵轴是数值真实值一条线、预测值一条线两条线在同一张图上对比。import numpy as np import matplotlib.pyplot as plt test_idx np.arange(len(y_test)) plt.figure(figsize(10, 5)) plt.plot(test_idx, y_test.values, b-o, markersize3, labelTrue) plt.plot(test_idx, y_test_pred, r-x, markersize3, labelPred) plt.xlabel(Sample Index) plt.ylabel(Target Value) plt.title(Test: True vs Predicted Sequence) plt.legend() plt.tight_layout() plt.savefig(Figure_line.png, dpi150)注意这里y_test如果是 pandas Series 且有索引错位直接.values取值是安全的。b-o表示蓝色实线加圆形标记r-x表示红色实线加叉形标记。两条线如果大部分区域贴合说明模型在大多数样本上预测稳定如果某些区段红蓝明显分离说明模型在这些样本区间存在系统性偏差往往是训练集里这些区间的样本太少。折线图最大的价值是定位「哪一段数据预测得差」。假设折线图显示目标值高的区域比如 40 以上预测普遍偏低那说明高价值样本在训练集里稀缺模型对极值的拟合能力不够。对比散点图右上角区域如果点在对角线下方两个图能互相印证。4.3 RMSE 的计算方式脚本里计算 RMSE 的代码一般长这样from sklearn.metrics import mean_squared_error import numpy as np 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(fTrain RMSE: {rmse_train:.4f}) print(fTest RMSE: {rmse_test:.4f})mean_squared_error计算的是均方误差外面套np.sqrt转成 RMSE让数值回到和目标变量相同的量纲业务人员能直接看懂。在这个数据集上目标变量是房价RMSE 的单位也是「房价单位」比如 RMSE 是 3.5意思是平均预测偏差 3.5 个单位。建议打印 RMSE 时保留四位小数方便对比不同参数组合的差异。5. 避坑手册数据读取、样本对齐与参数设置的五个常见问题这部分是跑通这份脚本时最容易翻车的地方每一条都是实际运行中踩过的坑按「现象 → 原因 → 解决」写清楚。5.1 报错ModuleNotFoundError: No module named openpyxl现象运行脚本pd.read_excel()那一行抛异常提示找不到openpyxl。原因read_excel读取.xlsx格式依赖openpyxl库很多环境只装了 pandas没装这个底层引擎。pandas 在读取 Excel 时不会自动帮你装依赖缺了就直接报错。解决执行pip install openpyxl装完之后重新运行。如果公司网络受限可以用pip install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple指定镜像源。装完可以用import openpyxl验证一下是否成功。5.2 测试集预测结果全部偏低或偏高一个固定量现象训练集 RMSE 很小测试集散点图整体偏移折线图两条线平行但不是贴合偏差接近一个常数。原因最常见的情况是目标变量在训练集和测试集里的分布不同比如训练集里的目标值整体偏高模型学到了这个偏移。另一种可能是特征列顺序不一致XGBoost 按位置分裂列顺序错乱会导致预测系统偏差。解决先检查两个 DataFrame 的列名顺序是否完全一致用assert list(X_train.columns) list(X_test.columns)。如果列名一致但偏差仍在把两个数据集的标签分布画个直方图对比偏差大就用pd.concat合并后重新切分。5.3 中文路径导致文件读取失败现象脚本放在D:\项目\房价预测\目录下pd.read_excel(boston_housing_train_data.xlsx)报FileNotFoundError但文件名明明是对的。原因Windows 上部分 Python 环境对中文路径的处理有问题pandas 读取文件时路径编码解析失败或者终端的工作目录和脚本所在目录不一致。解决切换到英文路径再跑一次或者在脚本里用绝对路径拼os.path.join。最省事的方式是打开终端先cd到脚本所在目录再执行python xgboost_regression.py这样相对路径一定是对的。5.4 训练时 loss 震荡、RMSE 降不下去现象训练集 RMSE 很大折线图预测线几乎是平的特征重要性也很分散。原因learning_rate设得太大比如 0.3 以上配合n_estimators过多后期树在过拟合和欠拟合之间震荡或者特征里混入了大量无关列比如 ID 列、字符串列XGBoost 对 ID 类特征容易产生虚假分裂。解决把learning_rate降到 0.05n_estimators提到 500配合early_stopping_rounds50。同时检查特征矩阵把唯一值过多的 ID 列删掉字符串列做编码或直接丢弃。5.5 只看 RMSE 就下结论忽略了业务口径现象RMSE 降到了 3.0看起来不错但画散点图发现目标值 20 以下的区域预测很准30 以上的区域全部偏低。原因RMSE 是全局指标对误差做了平方平均大误差样本的影响力被放大了但它的数值反映不了误差在哪个区间集中。如果业务更关心高目标值区间的准确性全局 RMSE 会掩盖局部短板。解决多画图、分层评估。按目标值分箱比如小于 20、20 到 30、大于 30分别计算每个区间的 RMSE定位短板区间后再考虑补充数据或调整特征。这一步在回归任务里比调参更有价值。6. 进阶验证残差检查与模型落地的一个具体技巧RMSE 和两张散点图已经够用了但想确认模型没有系统性偏差我一般会再画一张残差分布图。残差就是「真实值减预测值」如果残差随目标值增大而增大喇叭口形状说明模型存在异方差性高目标值区间的预测不可信。画法很简单import seaborn as sns residuals y_test.values - y_test_pred plt.figure(figsize(7, 5)) sns.histplot(residuals, kdeTrue, bins30) plt.xlabel(Residual) plt.ylabel(Count) plt.axvline(x0, colorr, linestyle--) plt.savefig(Figure_residual_hist.png, dpi150)这张图里残差应该大致以 0 为中心、呈正态分布如果明显左偏或右偏说明模型存在系统性偏差。axvline画在 0 处作参考线一眼能看出中心是否偏移。模型验证没问题之后下一个问题是落地。脚本每次运行都要重新训练业务上更常见的是「训练一次、预测多次」。这时候要把模型保存下来用joblib最省事import joblib joblib.dump(model, xgboost_regression_model.pkl) # 新数据预测时 loaded_model joblib.load(xgboost_regression_model.pkl) new_pred loaded_model.predict(new_feature_df)joblib.dump会把模型完整的参数和树结构序列化到磁盘joblib.load加载后直接predict。注意加载模型做预测时输入数据的列名和训练时保持一致pandas DataFrame 的列顺序如果变了先按训练时的列名reindex一遍new_feature_df new_feature_df[list(X_train.columns)]这个细节看似琐碎但上线阶段预测接口的输入列顺序往往来自业务侧拼接最容易翻车。从那以后我每次保存模型都会把训练集的列名列表一起存成.npy或写进配置文件加载后强制对齐列顺序再 predict血泪经验换来的习惯。希望帮到你。本文还有配套的精品资源点击获取