StatsModels中特征转换后新数据样本外预测值手动计算与模型输出不一致的问题排查
问题根源:未对新数据的年龄做训练集均值中心化
你遇到的预测值差异,核心原因是手动计算时没有对新数据的age使用训练集(即insurance数据集)的年龄均值做中心化处理——你的模型里的I(age - np.mean(age)),本质是用训练集的age均值来对所有输入数据(包括预测时的新数据)做中心化,而非直接使用原始年龄值,也不是用新数据自身的均值。
具体验证与修正
首先先算出训练集age的实际均值:
import numpy as np train_age_mean = insurance['age'].mean() # 该数据集的age均值约为 39.207
然后修正你的手动计算逻辑:
- 对于索引0(age=19,smoker=yes):
中心化后的年龄为19 - train_age_mean ≈ -20.207,代入公式(b0 + b2) + (b1 + b3) * (-20.207),计算结果会和模型predict输出的27581.27完全一致。 - 对于索引2(age=43,smoker=no):
中心化后的年龄为43 - train_age_mean ≈ 3.793,代入公式b0 + b1 * 3.793,计算结果会和模型predict输出的10702.77完全一致。
优化建议:提前创建中心化特征
为了避免这类混淆,建议你提前把中心化后的年龄作为单独列存入数据集,模型公式会更清晰,预测时也不容易出错:
# 预处理:创建训练集中心化后的年龄列 insurance['age_centered'] = insurance['age'] - insurance['age'].mean() # 拟合模型 model1 = smf.ols('charges ~ age_centered * smoker', data=insurance) fit1 = model1.fit() # 预测时,新数据必须用训练集的均值做中心化 new_data['age_centered'] = new_data['age'] - insurance['age'].mean() # 调用predict fit1.predict(new_data)
这样手动计算时,直接用new_data['age_centered']的值代入公式,就能和模型输出完全匹配了。
内容的提问来源于stack exchange,提问作者Francisco
相关产品推荐
相关产品推荐

