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

使用StackingCVClassifier堆叠Sklearn与Keras分类器遇维度错误求助

问题解决:StackingCVClassifier维度不匹配错误

错误原因

你遇到的ValueError是因为KerasClassifier的预测输出维度与sklearn原生分类器(Logistic Regression、Random Forest)不一致导致的:

  • sklearn二分类器的predict_proba方法会返回形状为(n_samples, 2)的数组,包含负类和正类的概率;
  • 你的Keras模型使用sigmoid输出,predict_proba仅返回正类概率,形状为(n_samples, 1)(部分版本下可能意外产生3维数组);
  • StackingCVClassifier在拼接这些元特征时,维度不匹配就会触发错误。

解决方法

方法1:统一KerasClassifier的输出维度

自定义一个包装类,修改KerasClassifier的predict_proba方法,让它输出和sklearn一致的(n_samples, 2)格式:

from keras.wrappers.scikit_learn import KerasClassifier
import numpy as np

class KerasClassifierWrapper(KerasClassifier):
    def predict_proba(self, X, **kwargs):
        # 获取Keras模型的正类概率
        proba_pos = super().predict_proba(X, **kwargs)
        # 补全负类概率,生成(n_samples, 2)的数组
        proba_neg = 1 - proba_pos
        return np.hstack([proba_neg, proba_pos])

# 替换原来的NN_clf定义
NN_clf = KerasClassifierWrapper(build_fn=create_model, epochs=5, batch_size=5)
NN_clf._estimator_type = "classifier"

方法2:使用类别标签作为元特征

如果不需要用概率作为元特征,可以设置StackingCVClassifier的use_probas=False,此时所有基分类器会输出预测类别(一维数组),拼接时维度一致:

clf = StackingCVClassifier(
    classifiers=[pipeline1, pipeline2, pipeline3],
    meta_classifier=MLPClassifier(),
    use_probas=False
)

额外优化建议

  1. 移除多余的Flatten层:你的Keras模型输入已经是二维的(样本数×特征数),Flatten()层在这里没有作用,可以删除;
  2. 适配新版本Keras:新版本Keras中build_fn参数已被废弃,建议改用model参数,同时优化学习率参数名:
def create_model():
    model = Sequential()
    model.add(Dense(10, input_dim=10, activation='relu'))
    model.add(Dropout(0.2))
    model.add(Dense(units=1, activation='sigmoid'))
    # 新版本Keras中lr改为learning_rate
    optimizer = keras.optimizers.RMSprop(learning_rate=0.001)
    model.compile(
        loss='binary_crossentropy',
        optimizer=optimizer,
        metrics=[keras.metrics.AUC(), 'accuracy']
    )
    return model

# 新版本KerasClassifier用法
NN_clf = KerasClassifierWrapper(model=create_model(), epochs=5, batch_size=5)

修改后的完整代码

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from tensorflow import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout
from mlxtend.classifier import StackingCVClassifier
from mlxtend.feature_selection import ColumnSelector
from sklearn.pipeline import make_pipeline
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.neural_network import MLPClassifier

X, y = make_classification()
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=0)

# 定义神经网络模型(移除多余Flatten层)
def create_model():
    model = Sequential()
    model.add(Dense(10, input_dim=10, activation='relu'))
    model.add(Dropout(0.2))
    optimizer = keras.optimizers.RMSprop(learning_rate=0.001)
    model.add(Dense(units=1, activation='sigmoid'))
    model.compile(
        loss='binary_crossentropy',
        optimizer=optimizer,
        metrics=[keras.metrics.AUC(), 'accuracy']
    )
    return model

# 包装KerasClassifier统一输出维度
class KerasClassifierWrapper(KerasClassifier):
    def predict_proba(self, X, **kwargs):
        proba_pos = super().predict_proba(X, **kwargs)
        proba_neg = 1 - proba_pos
        return np.hstack([proba_neg, proba_pos])

NN_clf = KerasClassifierWrapper(model=create_model(), epochs=5, batch_size=5)
NN_clf._estimator_type = "classifier"

# 定义各特征子集的管道
pipeline1 = make_pipeline(ColumnSelector(cols=np.arange(0, 5)), LogisticRegression())
pipeline2 = make_pipeline(ColumnSelector(cols=np.arange(5, 10)), RandomForestClassifier())
pipeline3 = make_pipeline(ColumnSelector(cols=np.arange(10, 20)), NN_clf)

# 堆叠模型
clf = StackingCVClassifier(classifiers=[pipeline1, pipeline2, pipeline3], meta_classifier=MLPClassifier())
clf.fit(X_train, y_train)

print("Stacking model score: %.3f" % clf.score(X_val, y_val))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:20:16