Spark GBTRegressor输出RMSE与预测结果不匹配问题咨询
Spark MLlib回归评估指标与直观预测效果不匹配的核心原因
高频问题根因
- 可视化样本的天然偏差
直观看到的预测和标签匹配度,基本来自show()默认输出的前20~100行样本。RMSE是基于全量测试集所有样本计算的全局指标,计算过程会对残差做平方加权,少数大误差样本对最终指标的影响远高于普通样本。只要全量集中存在少量标签处于高值区间、预测残差达数百的离群样本,整体RMSE就会被拉高到600+的量级——哪怕90%的样本误差都在10以内,10个残差达800的样本就足以把RMSE拉到680左右的水平,和你遇到的数值完全匹配。 - 预处理流程的隐蔽分布错配
你提到训练集、测试集独立完成缺失值插补,这里极易出现流程漏洞:如果插补、矢量化的模型没有先在训练集上fit完成后固定应用到测试集,而是在测试集上单独fit了一次插补器/矢量化器,会导致训练时模型学习到的特征分布,和测试集输入给模型的特征分布完全错位。最终模型对测试集内带缺失值的样本会输出完全偏离的预测结果,而这类带缺失值的样本往往不会出现在默认展示的前几行数据里,就会造成“预测看起来很准,但评估分数很差”的反差。 - 列映射错位
RegressionEvaluator默认严格读取你指定的labelCol和predictionCol列值做计算。如果你可视化展示结果时,错把某个原始数值特征列当成了预测值列,会直观产生“预测和标签几乎一致”的错觉,但实际prediction列的数值和label列的偏差极大。 - 交叉验证的随机划分偏差
代码里的CrossValidator没有设置固定随机种子,3折划分时很可能把高值离群样本全部分配到某一个训练折内,最终选出的最优模型会过度拟合这类离群点,到独立测试集上遇到未见过的离群标签时,会输出偏差极大的预测,最终拉高整体评估指标。
快速定位操作
- 直接统计全量测试集的残差分布:运行
predictions.select(abs(col("label") - col("prediction")).alias("residual")).describe().show(),查看残差的最大值、90分位值,即可定位是不是少数大残差拉高了整体RMSE。 - 验证列映射正确性:运行
predictions.select("label", "prediction").show(20),排除把其他列当成预测值的错位问题。 - 修正预处理流程:把Imputer、VectorAssembler全部封装在Pipeline中,先在训练集上fit整个管道,再用训练好的管道transform测试集,不要单独对测试集做独立预处理。
- 消除交叉验证的随机偏差:初始化CrossValidator时传入固定随机种子,比如
seed=42,保证数据划分的可复现性。
内容的提问来源于stack exchange,提问作者Alejandro Marín
相关产品推荐
相关产品推荐

