Repository navigation
[BUG] Multiclass SVC produces incorrect predictions with non-uniform class_weight #8578
Description
Describe the bug
cuml.svm.SVC produces substantially different multiclass predictions when non-uniform class_weight values are supplied.
For the deterministic three-class dataset below, using class_weight={0: 0.1, 1: 10.0, 2: 0.5} and decision_function_shape="ovo", cuML predicts every test point as class 2:
[2 2 2]
The equivalent scikit-learn model predicts:
[1 1 2]
In particular, cuML classifies the training-domain point [3, 3], whose training label is class 1 and whose class has the highest weight, as class 2.
Steps/Code to reproduce bug
cuML reproducer:
import numpy as np
from cuml.svm import SVC
a = np.array([[0, 0],[1, 1],[2, 2],[3, 3],[4, 4],[5, 5]], dtype=float)
b = np.array([0, 0, 1, 1, 2, 2])
weights = {0: 0.1,1: 10.0,2: 0.5}
c = np.array([[0, 0],[3, 3],[5, 5]], dtype=float)
print(SVC(kernel="rbf",decision_function_shape="ovo",class_weight=weights).fit(a, b).predict(c))Output:
[2 2 2]
For comparison, the equivalent scikit-learn code:
import numpy as np
from sklearn.svm import SVC
a = np.array([[0, 0],[1, 1],[2, 2],[3, 3],[4, 4],[5, 5]], dtype=float)
b = np.array([0, 0, 1, 1, 2, 2])
weights = {0: 0.1,1: 10.0,2: 0.5}
c = np.array([[0, 0],[3, 3],[5, 5]], dtype=float)
print(SVC(kernel="rbf",decision_function_shape="ovo",class_weight=weights).fit(a, b).predict(c))Output:
[1 1 2]
Expected behavior
class_weight[i] should scale class i's penalty parameter by class_weight[i] * C for each binary model in the one-vs-one multiclass decomposition.
With class 1 weighted at 10.0, the points near the class-1 training samples [2,2] and [3,3] should not all be reassigned to the lower-weight class 2. For this reproducer, predictions should be compatible with the scikit-learn result:
[1 1 2]
Environment details (please complete the following information):
- Environment location: Docker
- Linux Distro/Architecture: Ubuntu 24.04 / x86_64
- GPU Model/Driver: NVIDIA GeForce RTX 4090 / 595.71.05
- CUDA: 13.2
- Method of cuDF & cuML install: conda
conda list:
conda list
# packages in environment at /opt/conda/envs/rapids-26.08:
#
# Name Version Build Channel
# Name Version Build Channel
python 3.14.6 h242f9ac_102_cp314 conda-forge
numpy 2.4.6 py314h2b28147_0 conda-forge
scipy 1.16.3 py314hf07bd8e_2 conda-forge
scikit-learn 1.9.0 np2py314hf09ca88_0 conda-forge
rapids 26.08.00 cuda13_260806_c2656556 rapidsai
cuml 26.08.00 cuda13_cp311_abi3_260805_265b9da6 rapidsai
libcuml 26.08.00 cuda13_260805_265b9da6 rapidsai
cudf 26.08.00 cuda13_cp311_abi3_260805_ff5b362d rapidsai
libraft 26.08.00 cuda13_260805_ebf92684 rapidsai
libraft-headers 26.08.00 cuda13_260805_ebf92684 rapidsai
pylibraft 26.08.00 cuda13_cp311_abi3_260805_ebf92684 rapidsai
cuvs 26.08.01 cuda13_cp311_abi3_260806_25b1be43 rapidsai
libcuvs 26.08.01 cuda13_260806_25b1be43 rapidsai
cupy 14.1.1 py314hdea9c46_0 conda-forge
cupy-core 14.1.1 py314hcd3b49b_0 conda-forge
numba 0.64.0 py314h8169c2f_0 conda-forge
numba-cuda 0.30.4 py314h42812f9_0 conda-forge
rmm 26.08.00 cuda13_cp311_abi3_260805_42d059f1 rapidsai
librmm 26.08.00 cuda13_260805_42d059f1 rapidsai
cuda-version 13.3 hcbadf70_3 conda-forge
cuda-bindings 13.3.1 py314h42812f9_1 conda-forge
cuda-cudart 13.3.29 hecca717_0 conda-forge
cuda-nvrtc 13.3.33 hecca717_0 conda-forge
libcublas 13.6.0.2 h676940d_0 conda-forge
libcusolver 12.2.6.9 h676940d_0 conda-forge
libcusparse 12.8.2.51 hecca717_0 conda-forge
libcurand 10.4.3.29 h676940d_0 conda-forge
Additional context
The classes occupy consecutive regions along the line x_0 = x_1:
class 0: [0,0], [1,1] weight 0.1
class 1: [2,2], [3,3] weight 10.0
class 2: [4,4], [5,5] weight 0.5
The test points [0,0], [3,3], and [5,5] span those three regions. The discrepancy is therefore easy to observe, and [3,3] is itself present in the training data with label 1.
The cuML SVC documentation states that a class-weight dictionary modifies the penalty as class_weight[i] * C, and documents decision_function_shape="ovo" as a supported multiclass strategy.
This reproducer uses the default deterministic SVC training path (probability=False); random_state is only relevant to probability calibration and does not explain the difference.
Activity
viclafargue commentedon Sep 9, 2026
Thank you for opening the issue. I could reproduce it.
Implement multiclass SVC with non-uniform class weights (#8592)