如何在 sklearn 的 AdaBoost 中使用 Keras 模型?

How to use a Keras model inside of sklearn's AdaBoost?

我有一个 Keras 模型,想使用 sklearn 的 AdaBootClassifier 来提升它。不幸的是,我收到以下错误消息并且不知道如何解决它。如果有任何帮助,我将非常高兴!

ValueError Traceback(最后一次调用) 在 () ----> 1 boosted_classifier.fit(X,y)

3帧 /usr/local/lib/python3.6/dist-packages/sklearn/ensemble/_weight_boosting.py in _boost_discrete(self, iboost, X, y, sample_weight, random_state) 602 # 只提升正权重 603 sample_weight *= np.exp(estimator_weight * 不正确 * --> 604 (sample_weight > 0)) 605 606returnsample_weight,estimator_weight,estimator_error

ValueError:形状为 (670,) 的不可广播输出操作数与广播形状 (670,670) 不匹配

这是我的代码:

import sklearn
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import AdaBoostRegressor
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification

import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.wrappers.scikit_learn import KerasClassifier
from keras.wrappers.scikit_learn import KerasRegressor


import matplotlib.pyplot as plt
import numpy as np
import math

X_all, y_all = make_classification(n_samples=1000, n_features=50,
                           n_informative=20, n_redundant=0,
                           random_state=0, shuffle=False, class_sep=1)

X, X_test, y, y_test = train_test_split(X_all, y_all, test_size=0.33, random_state=42)

def simple_model():                                           
    # create model
    model = Sequential()
    model.add(Dense(25, input_dim=50, activation='relu'))
    model.add(Dropout(0.2, input_shape=(50,)))
    model.add(Dense(100, activation='relu'))
    model.add(Dropout(0.2, input_shape=(100,)))
    model.add(Dense(50, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    # Compile model
    model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
    return model

class MyKerasClassifier(KerasClassifier):
  def fit(self, x, y, sample_weight=None, **kwargs):
    y = np.array(y)
    if len(y.shape) == 2 and y.shape[1] > 1:
        self.classes_ = np.arange(y.shape[1])
    elif (len(y.shape) == 2 and y.shape[1] == 1) or len(y.shape) == 1:
        self.classes_ = np.unique(y)
        y = np.searchsorted(self.classes_, y)
    else:
        raise ValueError('Invalid shape for y: ' + str(y.shape))
    self.n_classes_ = len(self.classes_)
    if sample_weight is not None:
        kwargs['sample_weight'] = sample_weight
        print(type(sample_weight))
    return super(MyKerasClassifier, self).fit(x, y, **kwargs)
    #return super(KerasClassifier, self).fit(x, y, sample_weight=sample_weight)

boosted_classifier = AdaBoostClassifier(
    base_estimator=MyKerasClassifier(build_fn=simple_model, epochs=5, batch_size=32, verbose=0),
    n_estimators=2,
    random_state=0,
    algorithm="SAMME")

boosted_classifier.fit(X,y)

我为自己找到了一个简单的解决方案。我刚刚将以下预测函数添加到我的 MyKerasClassifier Class 并且它有效:)

  def predict(self, x, **kwargs):
    kwargs = self.filter_sk_params(Sequential.predict_classes, kwargs)
    classes = self.model.predict_classes(x, **kwargs)
    return self.classes_[classes].flatten()