SMOTENC crashes on documented categorical_features array inputs (bool mask / str-name array) due to == "auto" check
Describe the bug
SMOTENC documents that categorical_features accepts a boolean mask array and a string-name array:
mask array of shape (n_features,) and
booldtype for whichTrueindicates the categorical featuresarray of
strcorresponding to the feature names
Both crash before being used. In _validate_column_types (imblearn/over_sampling/_smote/base.py:561):
if self.categorical_features == "auto":When categorical_features is a NumPy array, array == "auto" returns an element-wise boolean array, so if <array>: raises ValueError: The truth value of an array with more than one element is ambiguous. A Python list compares to "auto" as a scalar (False) and passes — which is why list inputs work while the documented array inputs do not.
Steps/Code to Reproduce
import numpy as np
import pandas as pd
from imblearn.over_sampling import SMOTENC
X = np.hstack([
np.random.default_rng(3).standard_normal((240, 3)),
np.random.default_rng(3).integers(0, 4, size=(240, 2)).astype(float),
])
y = np.array([0] * 200 + [1] * 40)
# 1) documented boolean mask -> crashes
mask = np.array([False, False, False, True, True])
SMOTENC(categorical_features=mask, random_state=7).fit_resample(X, y)
# 2) documented str-name array -> crashes the same way
Xdf = pd.DataFrame(X, columns=["c0", "c1", "c2", "cat0", "cat1"])
SMOTENC(categorical_features=np.array(["cat0", "cat1"]), random_state=7).fit_resample(Xdf, y)
# 3) equivalent Python lists both work fine
SMOTENC(categorical_features=[3, 4], random_state=7).fit_resample(X, y)
SMOTENC(categorical_features=["cat0", "cat1"], random_state=7).fit_resample(Xdf, y)Expected Results
The boolean mask and the str-name array are accepted, identically to their list equivalents, since both are documented input forms.
Actual Results
Traceback (most recent call last):
...
File ".../imblearn/over_sampling/_smote/base.py", line 597, in _fit_resample
self._validate_column_types(X)
File ".../imblearn/over_sampling/_smote/base.py", line 561, in _validate_column_types
if self.categorical_features == "auto":
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()Versions
System:
python: 3.12.10 [MSC v.1943 64 bit (AMD64)]
machine: Windows-11
Python dependencies:
sklearn: 1.9.1
numpy: 2.5.3
scipy: 1.18.1
pandas: 3.0.5
joblib: 1.6.0
imblearn: 0.14.2I'd be happy to open a PR. The fix is to make the sentinel check string-safe, e.g. if isinstance(self.categorical_features, str) and self.categorical_features == "auto":, plus regression tests passing a boolean mask and a str-name array. One question before I do: would you prefer that minimal guard, or normalizing categorical_features to indices up front in _validate_column_types?
Source: scikit-learn-contrib/imbalanced-learn