You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义模型与StandardScaler构建Pipeline时预测未反归一化问题

问题根源分析

你的问题核心是对Sklearn Pipeline的工作逻辑和自定义模型角色的理解偏差:
Sklearn的StandardScaler仅负责输入特征X的标准化,不会对模型的输出结果做任何逆变换操作。

  • 对于Lasso这类标准回归模型:它在训练时学习的是标准化后的X到原始尺度y_true的映射关系,所以预测时,即使输入X被标准化,Lasso输出的依然是匹配y_true尺度的预测值。
  • 而你的自定义mean_stacker:它的predict方法直接返回标准化后X的行均值——这个值的尺度是标准化后的(均值为0、方差为1),和原始y_true的尺度完全不匹配,所以看起来像是没做反归一化。
两种修复方案

方案一:让自定义模型学习标准化特征到y的映射(推荐)

如果你想让mean_stacker和Lasso一样在Pipeline中配合StandardScaler工作,需要让模型学习「标准化后的X均值」到「原始y尺度」的线性映射,而不是直接返回X的均值。修改后的模型代码如下:

class mean_stacker():
    def __init__(self, desc='Simple Mean Stacker'):
        self.description = desc
    def predict(self, X):
        check_is_fitted(self, ['coef_', 'intercept_'])
        X = check_array(X)
        # 计算标准化后X的行均值
        x_mean = np.mean(X, axis=1)
        # 用训练好的系数映射回y的原始尺度
        return self.coef_ * x_mean + self.intercept_
    def fit(self, X, y):
        X, y = check_X_y(X, y)
        # 把每个样本的X均值作为单独特征,拟合线性模型
        x_mean = np.mean(X, axis=1).reshape(-1, 1)
        from sklearn.linear_model import LinearRegression
        lr = LinearRegression(fit_intercept=True)
        lr.fit(x_mean, y)
        # 保存线性模型的系数和截距
        self.coef_ = lr.coef_[0]
        self.intercept_ = lr.intercept_[0]
        # 标记模型已拟合
        self.is_fitted_ = True
        return self

这个修改后的模型会在训练时自动学习标准化特征到原始y的映射关系,预测时输出的结果会和y_true的尺度完全对齐。

方案二:移除Pipeline中的StandardScaler(适合简单场景)

如果你的mean_stacker只是想直接对原始输入X取均值作为预测值,那么它根本不需要特征标准化(取均值的操作不受特征尺度影响)。此时可以直接使用模型,不需要用Pipeline包裹Scaler:

stacker_models =[ 
    make_pipeline(StandardScaler(), Lasso(alpha = 0.0005, random_state = 4)), 
    mean_stacker() 
]

这样mean_stacker的predict会直接返回原始X的行均值,和y_true的尺度自然匹配。

验证效果

修改后运行你的代码,绘制的图表中yMean会和ytrue的趋势、尺度完全一致,不再出现明显偏移。

内容的提问来源于stack exchange,提问作者Phun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:57:40