sklearn与statsmodels实现Huber回归结果不一致问题排查
问题原因与解决方法
- 特征标准化处理差异:sklearn的
HuberRegressor拟合时默认会自动对输入特征做标准化处理,而statsmodels的RLM不会对输入数据做任何预处理。你用到的FSC-A、FSC-H都是流式细胞术的通道值,本身数值量级很大,原始尺度下Huber损失的阈值无法有效区分正常样本和异常值,所有样本都会被判定为正常点参与损失计算,最终结果就和普通线性回归完全一致。 - 默认参数差异:两个库的Huber损失阈值、正则项默认配置也不同:
- sklearn默认开启L2正则(
alpha=0.0001),statsmodels RLM默认无正则 - sklearn默认Huber阈值
epsilon=1.35,statsmodels的HuberT默认阈值t=1.345,虽然数值接近但也会带来微小差异
- sklearn默认开启L2正则(
修正后的statsmodels实现代码
import statsmodels.api as sm from sklearn.preprocessing import StandardScaler x = df["FSC-A"].values.reshape(-1, 1) y = df["FSC-H"].values # 先对特征做标准化,对齐sklearn的预处理逻辑 scaler = StandardScaler() x_scaled = scaler.fit_transform(x) # 加截距项 x_scaled_with_const = sm.add_constant(x_scaled) rlm_model = sm.RLM(endog = y, exog= x_scaled_with_const, M=sm.robust.norms.HuberT(t=1.35)) # 对齐sklearn的epsilon参数 rlm_results = rlm_model.fit() # 将标准化后的参数转换回原始尺度 slope = rlm_results.params[1] / scaler.scale_[0] intercept = rlm_results.params[0] - slope * scaler.mean_[0] print("------------") print(f"slope : {slope}") print(f"intercept : {intercept}")
修正后得到的斜率和截距就会和sklearn的输出基本一致。
内容的提问来源于stack exchange,提问作者bibi Hugo
相关产品推荐
相关产品推荐

