Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 63f2abf

Browse files
FIX Raise error for categorical features with criterion='absolute_error' (#34594)
Co-authored-by: Stefanie Senger <[email protected]>
1 parent 76e8196 commit 63f2abf

4 files changed

Lines changed: 36 additions & 2 deletions

File tree

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
- :class:`tree.DecisionTreeRegressor`, :class:`tree.DecisionTreeClassifier`
22
now have native support for categorical features for binary classification and
3-
single-output regression. Categorical features can be specified with the
4-
`categorical_features` parameter. Up to 256 categories per features are supported.
3+
single-output regression. All criteria are supported except for `'absolute_error'`.
4+
Categorical features can be specified with the `categorical_features` parameter.
5+
Up to 256 categories per features are supported.
56
By `:user:`Adam Li <adam2392>`, `:user:`Arthur Lacote <cakedev0>`,
67
:user:`Adrin Jalali <adrinjalali>` and :user:`Christian Lorentzen <lorentzenchr>`

sklearn/tree/_classes.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,11 @@ def _fit(
510510
"Categorical features are only supported for binary classification. "
511511
f"Found {self.n_classes_.max()} classes."
512512
)
513+
if has_categorical and self.criterion == "absolute_error":
514+
raise ValueError(
515+
"Categorical features are not supported with "
516+
"criterion='absolute_error'."
517+
)
513518

514519
SPLITTERS = SPARSE_SPLITTERS if issparse(X) else DENSE_SPLITTERS
515520
splitter = SPLITTERS[self.splitter](
@@ -1456,6 +1461,8 @@ class DecisionTreeRegressor(RegressorMixin, BaseDecisionTree):
14561461
represented by ``np.nan``; unknown categories at prediction time are
14571462
also treated as missing values.
14581463
1464+
Categorical features are not supported with `criterion="absolute_error"`.
1465+
14591466
.. versionadded:: 1.10
14601467
14611468
Attributes

sklearn/tree/tests/test_split.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ def test_split_impurity(
247247

248248
if categorical and "Extra" in Tree.__name__:
249249
pytest.skip("Categorical features not implemented for the random splitter")
250+
if categorical and criterion == "absolute_error":
251+
pytest.skip(
252+
"absolute_error is not supported with categorical features in "
253+
"DecisionTreeRegressor"
254+
)
250255
rng = np.random.default_rng(global_random_seed)
251256

252257
ns = [5] * 5 + [10] * 5 + [20, 30, 50, 100]

sklearn/tree/tests/test_tree.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,6 +2469,11 @@ def test_missing_values_best_splitter_on_equal_nodes_no_missing(
24692469
criterion, categorical_features
24702470
):
24712471
"""Check missing values goes to correct node during predictions."""
2472+
if categorical_features is not None and criterion == "absolute_error":
2473+
pytest.skip(
2474+
"absolute_error is not supported with categorical features in "
2475+
"DecisionTreeRegressor"
2476+
)
24722477
X = np.array([[0, 1, 2, 3, 8, 9, 11, 12, 15]]).T
24732478
y = np.array([0.1, 0.2, 0.3, 0.2, 1.4, 1.4, 1.5, 1.6, 2.6])
24742479
node_value_func = np.median if criterion == "absolute_error" else np.mean
@@ -3136,6 +3141,22 @@ def test_fit_categorical_with_monotonic_constraint(Tree):
31363141
Tree(categorical_features=[0], monotonic_cst=[1], random_state=0).fit(X, y)
31373142

31383143

3144+
def test_fit_categorical_with_absolute_error():
3145+
# Non-regression test: the categorical split-finding algorithm is not
3146+
# valid for criterion="absolute_error" (see gh-34578), so it should be
3147+
# rejected rather than silently return a possibly suboptimal split.
3148+
X = np.array([[0.0], [1.0], [0.0], [1.0]], dtype=np.float64)
3149+
y = np.array([0.0, 1.0, 0.0, 1.0])
3150+
3151+
with pytest.raises(
3152+
ValueError,
3153+
match="Categorical features are not supported with criterion='absolute_error'",
3154+
):
3155+
DecisionTreeRegressor(categorical_features=[0], criterion="absolute_error").fit(
3156+
X, y
3157+
)
3158+
3159+
31393160
def test_predict_sparse_int64_indices_raises():
31403161
X = np.array([[0.0], [1.0]], dtype=np.float64)
31413162
y = np.array([0, 1])

0 commit comments

Comments
 (0)