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

如何用scikit-learn实现单最终估计器的多输出堆叠回归?

如何在scikit-learn中实现支持多输出的堆叠回归器(使用单个最终估计器)

我尝试过sklearn.ensemble.StackingRegressor,但根据其文档,该工具仅支持最终估计器输出形状为(n_samples,)的单变量场景,而我需要输出形状为(n_samples, n_features)的多变量结果。

作为替代方案,我试过sklearn.multioutput.MultiOutputRegressor,但它会为每个输出特征单独训练模型,在高维数据上训练速度慢且参数冗余,不符合我的需求。我希望用单个最终估计器(比如随机森林)来接收多变量输入并输出多变量结果,让预测流水线更简洁、训练更快。

我期望的流程如下:

+-----------------------+----+--------------+-------------------------------------------+----+-------------+----+------------------+
| Set of observations 1 | -> | Base Model 1 |                                           |    |             |    |                  |
|    (nsmpls, nfeats)   |    |              |                                           |    |             |    |                  |
+-----------------------+----+--------------+-------------------------------------------+----+-------------+----+------------------+
|                                           | Concatenated predictions from base models | -> | Final model | -> | Final prediction |
|                                           |             (nsmpls, 2 * nfeats)          |    |             |    | (nsmpls, nfeats) |
+-----------------------+----+--------------+-------------------------------------------+----+-------------+----+------------------+
| Set of observations 2 | -> | Base Model 2 |                                           |    |             |    |                  |
|    (nsmpls, nfeats)   |    |              |                                           |    |             |    |                  |
+-----------------------+----+--------------+-------------------------------------------+----+-------------+----+------------------+

注:示例中基础模型的输入输出特征数相同,逻辑也适用于其他情况;每个基础模型使用不同输入特征集的问题我已经解决。我也可以直接在拼接输入上训练最终模型,但希望同时训练两个基础模型(它们本身有研究价值),实现一举两得。


解决方案:手动实现多输出堆叠逻辑

scikit-learn官方的StackingRegressor暂不支持多输出的最终估计器,你可以手动实现堆叠流程,既保留基础模型的独立训练,又能使用单个多输出最终估计器:

1. 训练基础模型并生成预测特征

先分别训练两个基础模型,再用它们对训练集生成预测结果,作为最终模型的输入特征:

import numpy as np
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split

# 假设X1、X2是两个基础模型的输入特征,y是多输出目标
X1, X2, y = ...  # 替换为你的数据集
X1_train, X1_test, X2_train, X2_test, y_train, y_test = train_test_split(X1, X2, y, test_size=0.2)

# 训练基础模型
base_model1 = RandomForestRegressor()
base_model1.fit(X1_train, y_train)

base_model2 = RandomForestRegressor()
base_model2.fit(X2_train, y_train)

# 生成训练集的预测结果并拼接
train_preds1 = base_model1.predict(X1_train)
train_preds2 = base_model2.predict(X2_train)
X_final_train = np.hstack([train_preds1, train_preds2])  # 形状为(nsmpls, 2*nfeats)

# 生成测试集的预测结果并拼接
test_preds1 = base_model1.predict(X1_test)
test_preds2 = base_model2.predict(X2_test)
X_final_test = np.hstack([test_preds1, test_preds2])

2. 训练多输出最终估计器

直接用原生支持多输出的模型(比如随机森林)作为最终估计器,在拼接后的特征上训练:

# 训练最终多输出模型
final_model = RandomForestRegressor()
final_model.fit(X_final_train, y_train)

# 生成多输出预测
y_pred = final_model.predict(X_final_test)
# y_pred形状为(nsmpls, nfeats),满足需求

3. 封装为可复用类(可选)

如果需要像scikit-learn内置模型一样调用fit和predict,可以封装一个自定义类:

from sklearn.base import BaseEstimator, RegressorMixin
from sklearn.base import clone

class MultiOutputStackingRegressor(BaseEstimator, RegressorMixin):
    def __init__(self, base_models, final_model):
        self.base_models = base_models
        self.final_model = final_model
        
    def fit(self, X_list, y):
        # X_list是基础模型的输入列表,例如[X1, X2]
        self.base_models_ = []
        train_preds = []
        for idx, X in enumerate(X_list):
            model = clone(self.base_models[idx])
            model.fit(X, y)
            self.base_models_.append(model)
            train_preds.append(model.predict(X))
        # 拼接所有基础模型的预测结果
        X_final = np.hstack(train_preds)
        self.final_model.fit(X_final, y)
        return self
    
    def predict(self, X_list):
        test_preds = []
        for idx, X in enumerate(X_list):
            test_preds.append(self.base_models_[idx].predict(X))
        X_final = np.hstack(test_preds)
        return self.final_model.predict(X_final)

# 使用示例
stacking_reg = MultiOutputStackingRegressor(
    base_models=[RandomForestRegressor(), RandomForestRegressor()],
    final_model=RandomForestRegressor()
)
stacking_reg.fit([X1_train, X2_train], y_train)
y_pred = stacking_reg.predict([X1_test, X2_test])

这个自定义类完全匹配你的需求:既保留了可独立研究的基础模型,又通过单个多输出最终模型完成堆叠预测,避免了MultiOutputRegressor的参数冗余问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:43:15