Skip to content

Commit 10ba0a7

Browse files
authored
Fix label binarize for binary class (#5900)
Closes #5740 Fix for cuml's `label_binarize` to have the same output as scikit-learn's `label_binarize` for binary classes. Note: Unlike scikit-learn's [`scipy.sparse._csr.csr_matrix.getcol()`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.getcol.html), cuml's `cupyx.scipy.sparse.csr_matrix.getcol()` does not support -1 indexing. Authors: - Jinsol Park (https://github.com/jinsolp) Approvers: - Divye Gala (https://github.com/divyegala) URL: #5900
1 parent f16fccc commit 10ba0a7

2 files changed

Lines changed: 40 additions & 3 deletions

File tree

python/cuml/preprocessing/label.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2020-2023, NVIDIA CORPORATION.
1+
# Copyright (c) 2020-2024, NVIDIA CORPORATION.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -64,14 +64,19 @@ def label_binarize(
6464

6565
cp.cuda.Stream.null.synchronize()
6666

67+
is_binary = classes.shape[0] == 2
68+
6769
if sparse_output:
6870
sp = sp.tocsr()
71+
if is_binary:
72+
sp = sp.getcol(1) # getcol does not support -1 indexing
6973
return sp
7074
else:
7175

7276
arr = sp.toarray().astype(y.dtype)
7377
arr[arr == 0] = neg_label
74-
78+
if is_binary:
79+
arr = arr[:, -1].reshape((-1, 1))
7580
return arr
7681

7782

python/cuml/tests/test_preprocessing.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2020-2023, NVIDIA CORPORATION.
1+
# Copyright (c) 2020-2024, NVIDIA CORPORATION.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@
4343
quantile_transform as cu_quantile_transform,
4444
robust_scale as cu_robust_scale,
4545
scale as cu_scale,
46+
label_binarize as cu_label_binarize,
4647
)
4748
from sklearn.preprocessing import (
4849
Binarizer as skBinarizer,
@@ -68,6 +69,7 @@
6869
quantile_transform as sk_quantile_transform,
6970
robust_scale as sk_robust_scale,
7071
scale as sk_scale,
72+
label_binarize as sk_label_binarize,
7173
)
7274
from sklearn.impute import (
7375
MissingIndicator as skMissingIndicator,
@@ -1135,6 +1137,36 @@ def test_kernel_centerer():
11351137
assert_allclose(sk_t_X, t_X)
11361138

11371139

1140+
def test_label_binarize():
1141+
cu_bin = cu_label_binarize(
1142+
cp.array([1, 0, 1, 1]), classes=cp.array([0, 1])
1143+
)
1144+
sk_bin = sk_label_binarize([1, 0, 1, 1], classes=[0, 1])
1145+
assert_allclose(cu_bin, sk_bin)
1146+
1147+
cu_bin_sparse = cu_label_binarize(
1148+
cp.array([1, 0, 1, 1]), classes=cp.array([0, 1]), sparse_output=True
1149+
)
1150+
sk_bin_sparse = sk_label_binarize(
1151+
[1, 0, 1, 1], classes=[0, 1], sparse_output=True
1152+
)
1153+
assert_allclose(cu_bin_sparse, sk_bin_sparse)
1154+
1155+
cu_multi = cu_label_binarize(
1156+
cp.array([1, 6, 3]), classes=cp.array([1, 3, 4, 6])
1157+
)
1158+
sk_multi = sk_label_binarize([1, 6, 3], classes=[1, 3, 4, 6])
1159+
assert_allclose(cu_multi, sk_multi)
1160+
1161+
cu_multi_sparse = cu_label_binarize(
1162+
cp.array([1, 6, 3]), classes=cp.array([1, 3, 4, 6]), sparse_output=True
1163+
)
1164+
sk_multi_sparse = sk_label_binarize(
1165+
[1, 6, 3], classes=[1, 3, 4, 6], sparse_output=True
1166+
)
1167+
assert_allclose(cu_multi_sparse, sk_multi_sparse)
1168+
1169+
11381170
def test__repr__():
11391171
assert cuBinarizer().__repr__() == "Binarizer()"
11401172
assert cuFunctionTransformer().__repr__() == "FunctionTransformer()"

0 commit comments

Comments
 (0)