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

scikit-learn中GradientBoostingRegressor3维输出报错解决方法

问题背景

尝试使用scikit-learn库中的RandomForestRegressor和GradientBoostingRegressor模型,实现13维输入数据到3维输出数据的映射。RandomForestRegressor可正常运行,但GradientBoostingRegressor训练时抛出如下ValueError:

ValueError: y should be a 1d array, got an array of shape (16127, 3) instead.

两类模型均以决策树为弱学习器,仅GradientBoostingRegressor出现该报错。直接将3维输出标签转换为1维数组的方式无法满足3维向量映射需求,需要找到使用梯度提升模型实现3维输出回归的可行方案。

原实现代码如下:

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor

# Read data from  csv files
Input_data_features = pd.read_csv("C:/Users/wi9632/Desktop/TestData_InputFeatures.csv", sep=';')
Input_data_labels = pd.read_csv("C:/Users/wi9632/Desktop/TestData_OutputLabels.csv", sep=';')
Input_data_features = Input_data_features.values
Input_data_labels = Input_data_labels.values


# standardize input features X and output labels Y
scaler_standardized_X = StandardScaler()
Input_data_features = scaler_standardized_X.fit_transform(Input_data_features)

scaler_standardized_Y = StandardScaler()
Input_data_labels = scaler_standardized_Y.fit_transform(Input_data_labels)


# Split dataset into train, validation, an test
index_X_Train_End = int(0.7 * len(Input_data_features))
index_X_Validation_End = int(0.9 * len(Input_data_features))

X_train = Input_data_features[0: index_X_Train_End]
X_valid = Input_data_features[index_X_Train_End: index_X_Validation_End]
X_test = Input_data_features[index_X_Validation_End:]

Y_train = Input_data_labels[0: index_X_Train_End]
Y_valid = Input_data_labels[index_X_Train_End: index_X_Validation_End]
Y_test = Input_data_labels[index_X_Validation_End:]


#Define a random forest model and train it
model_randomForest = RandomForestRegressor( )
model_randomForest.fit(X_train, Y_train)

#Predict the test data with Random Forest
Y_pred_randomForest = model_randomForest.predict(X_test)
print(f"Random Forest Prediction: {Y_pred_randomForest}")


#Define a gradient boosting  model and train it (-->Here I get the ValueError)
model_gradientBoosting = GradientBoostingRegressor( )
model_gradientBoosting.fit(X_train, Y_train)

#Predict the test data with Gradient Boosting
Y_pred_gradientBoosting = model_gradientBoosting.predict(X_test)
print(f"Gradient Boosting Prediction: {Y_pred_gradientBoosting}")

问题补充:该问题暂未解决,需要可行的解决思路。

报错根因

scikit-learn原生的GradientBoostingRegressor在设计上不原生支持多输出回归任务,这和模型是否基于决策树构建没有直接关系。
RandomForestRegressor在代码实现层面原生适配了多输出场景,训练时会为每个输出维度独立构建对应的随机森林子模型,因此可以直接传入shape为(n_samples, n_outputs)的二维标签训练。但传统GradientBoostingRegressor的实现逻辑仅支持单目标回归,训练时会强制校验输入标签为一维数组,直接传入3维标签就会触发上述报错。

可行解决方案

方案1:使用MultiOutputRegressor包装器适配多输出

这是scikit-learn官方提供的多输出任务通用适配方案,改动代码量最小。其原理是为每个输出维度单独训练一个独立的GradientBoostingRegressor模型,预测时将所有子模型的输出拼接为最终的多维预测结果,完全匹配3维输出的需求。
修改步骤:

  1. 导入多输出包装器:
from sklearn.multioutput import MultiOutputRegressor
  1. 替换原代码中GBDT模型的定义、训练逻辑,其余代码保持不变:
# 用MultiOutputRegressor包装原生GBDT,适配多输出回归
model_gradientBoosting = MultiOutputRegressor(GradientBoostingRegressor())
model_gradientBoosting.fit(X_train, Y_train)

# 预测结果直接为shape (n_samples, 3)的矩阵,和随机森林输出格式一致
Y_pred_gradientBoosting = model_gradientBoosting.predict(X_test)
print(f"Gradient Boosting Prediction: {Y_pred_gradientBoosting}")

注意:该方案下每个输出维度的GBDT模型独立训练,不会建模不同输出维度之间的相关性。

方案2:替换为原生支持多输出的梯度提升实现

如果希望模型原生支持多输出、无需额外包装,可以直接替换为已经内置多输出回归支持的梯度提升实现:

  • 优先选用scikit-learn官方的HistGradientBoostingRegressor:这是scikit-learn推出的直方图优化GBDT实现,训练速度远快于传统GradientBoostingRegressor,接口和原有模型完全兼容,原生支持多输出回归,无需额外包装。使用时仅需修改导入和模型定义代码即可:
    from sklearn.ensemble import HistGradientBoostingRegressor
    model_gradientBoosting = HistGradientBoostingRegressor()
    # 后续fit、predict逻辑和原代码完全一致,直接传入二维Y_train即可正常训练
    
  • 也可以根据需求替换为XGBoost、LightGBM、CatBoost等主流梯度提升框架的回归接口,这些框架均原生支持多输出回归,同时提供更丰富的调参选项和更快的训练速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 00:12:16