I have a Keras model and want to boost it using sklearn's AdaBootClassifier. Unfortunately I get the following error message and have no idea how to solve it. I would be very happy about any help!
ValueError Traceback (most recent call last) in () ----> 1 boosted_classifier.fit(X,y)
3 frames /usr/local/lib/python3.6/dist-packages/sklearn/ensemble/_weight_boosting.py in _boost_discrete(self, iboost, X, y, sample_weight, random_state) 602 # Only boost positive weights 603 sample_weight *= np.exp(estimator_weight * incorrect * --> 604 (sample_weight > 0)) 605 606 return sample_weight, estimator_weight, estimator_error
ValueError: non-broadcastable output operand with shape (670,) doesn't match the broadcast shape (670,670)
This is my code:
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)
I found an easy solution for myself. I just added the following prediction function to my MyKerasClassifier Class and it works :)
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()