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

如何基于Scikit-learn构建两阶段回归Pipeline:X1拟合y后用X2拟合残差

用Scikit-learn Pipeline实现残差堆叠回归

要实现你描述的两步回归流程,核心是自定义符合Scikit-learn接口的组件,将残差计算环节整合到Pipeline中。以下是完整的实现方案:

1. 自定义残差堆叠回归器

我们需要一个复合回归器,继承Scikit-learn的基础类来适配Pipeline,它会完成"用X1训练回归器→计算残差→用X2训练回归器预测残差"的完整逻辑。

2. 完整代码实现

import numpy as np
from sklearn.base import BaseEstimator, RegressorMixin
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 自定义堆叠回归器,实现残差预测逻辑
class ResidualStackedRegressor(BaseEstimator, RegressorMixin):
    def __init__(self, regressor1, regressor2, x1_cols, x2_cols):
        self.regressor1 = regressor1
        self.regressor2 = regressor2
        self.x1_cols = x1_cols  # X1在合并特征矩阵中的列索引
        self.x2_cols = x2_cols  # X2在合并特征矩阵中的列索引
        
    def fit(self, X, y):
        # 提取X1特征训练第一个回归器
        X1 = X[:, self.x1_cols]
        self.regressor1.fit(X1, y)
        # 计算残差
        y_pred1 = self.regressor1.predict(X1)
        residual = y - y_pred1
        # 提取X2特征训练第二个回归器预测残差
        X2 = X[:, self.x2_cols]
        self.regressor2.fit(X2, residual)
        return self
    
    def predict(self, X):
        # 用X1得到第一阶段预测值
        X1 = X[:, self.x1_cols]
        y_pred1 = self.regressor1.predict(X1)
        # 用X2得到残差预测值
        X2 = X[:, self.x2_cols]
        y_pred_residual = self.regressor2.predict(X2)
        # 总预测值为两者之和
        return y_pred1 + y_pred_residual

# 生成模拟数据
np.random.seed(42)
X1 = np.random.rand(1000, 10)  # 10个X1特征
X2 = np.random.rand(1000, 10)  # 10个X2特征
X = np.hstack([X1, X2])  # 合并为单特征矩阵
y = 2 * X1[:, 0] + 3 * X1[:, 1] + np.log(X2[:, 2] + 1) + np.random.randn(1000) * 0.1

# 拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 构建Pipeline
pipeline = Pipeline([
    ('stacked_reg', ResidualStackedRegressor(
        regressor1=LinearRegression(),
        regressor2=RandomForestRegressor(n_estimators=100, random_state=42),
        x1_cols=list(range(10)),  # X1对应前10列
        x2_cols=list(range(10, 20))  # X2对应后10列
    ))
])

# 训练与预测
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)

# 评估效果
print(f"测试集MSE: {mean_squared_error(y_test, y_pred):.4f}")

3. 扩展:添加特征预处理

如果需要对X1、X2分别做预处理(比如标准化),可以在Pipeline中加入ColumnTransformer实现分组处理:

from sklearn.preprocessing import StandardScaler
from sklearn.compose import ColumnTransformer

# 分组预处理:分别标准化X1和X2
preprocessor = ColumnTransformer(
    transformers=[
        ('scaler_x1', StandardScaler(), list(range(10))),
        ('scaler_x2', StandardScaler(), list(range(10, 20)))
    ])

# 带预处理的完整Pipeline
full_pipeline = Pipeline([
    ('preprocess', preprocessor),
    ('stacked_reg', ResidualStackedRegressor(
        regressor1=LinearRegression(),
        regressor2=RandomForestRegressor(n_estimators=100, random_state=42),
        x1_cols=list(range(10)),
        x2_cols=list(range(10, 20))
    ))
])

4. 注意事项

  • 如果X1和X2是独立的特征矩阵,建议合并为单个矩阵后再传入Pipeline,这更符合Scikit-learn的设计逻辑。
  • regressor1和regressor2可以替换为任意Scikit-learn兼容的回归器(如SVR、GradientBoostingRegressor等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 06:05:23