Description
When using SKLearnClassifier
or SKLearnRegressor
wrappers with no other scikit-learn imports (such as make_classification
) the following error is raised:
AttributeError: module 'sklearn.utils' has no attribute 'multiclass'
This happens because sklearn.utils.multiclass
is used internally, but not explicitly imported by Keras, and it's not guaranteed to be present unless certain sklearn components are invoked prior.
Minimal Reproducible Example
from keras.layers import Dense, Input
from keras.models import Model
from keras.wrappers import SKLearnClassifier, SKLearnRegressor
def dynamic_model(X, y, loss, layers):
# Creates a basic MLP model dynamically choosing the input and
# output shapes.
n_features_in = X.shape[1]
inp = Input(shape=(n_features_in,))
hidden = inp
for layer_size in layers:
hidden = Dense(layer_size, activation="relu")(hidden)
n_outputs = y.shape[1] if len(y.shape) > 1 else 1
out = Dense(n_outputs, activation="softmax")(hidden)
model = Model(inp, out)
model.compile(loss=loss, optimizer="rmsprop")
return model
X = [[0.1, 0.2], [0.2, 0.3], [0.3, 0.4], [0.4, 0.5]]
y = [[1], [0], [1], [0]]
est = SKLearnClassifier( # Or SKLearnRegressor
model=dynamic_model,
model_kwargs={
"loss": "categorical_crossentropy",
"layers": [20, 20, 20],
},
)
est.fit(X, y, epochs=5)
Expected Behaviour
The code should run without requiring implicit imports from sklearn.utils.multiclass
.
Actual Behaviour
Fails with an AttributeError
if no other sklearn functionality has triggered an implicit import of sklearn.utils.multiclass
.
Suggested Fix
Explicitly import sklearn.utils.multiclass
in the relevant wrapper module to ensure correct functioning regardless of prior sklearn usage.
I'll open a PR shortly to address this. While investigating, I found other similar cases of implicit sklearn imports. The PR will include those as well.