You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用sklearn MultiOutputClassifier遇类别数不足两类的报错求助

问题描述

使用sklearn的MultiOutputClassifier结合SVC进行多标签分类时,触发报错:ValueError: The number of classes has to be greater than one; got 1 class。

已完成以下验证:

  • 为无标签数据添加了「Free」类别
  • 确认y_train为400×31矩阵,无全零行:np.any(np.all(y_train == 0, axis=1))返回False
  • len(np.unique(y_train))结果为2,自定义atleast_one(y_train)返回True

相关代码:

texts = [element['text'] for element in train_data]
labels = [element['labels'] if element['labels'] else ['Free'] for element in train_data]

mlb = MultiLabelBinarizer(classes=G.nodes)
y_bin = mlb.fit_transform(labels)

# texts was turned in X_reduced cause i did some other changes there
X_train, X_test, y_train, y_test = train_test_split(X_reduced, y_bin, test_size=0.2, random_state=42)

multi_label_classifier = MultiOutputClassifier(SVC(kernel='linear', probability=True))
y_train=y_train.astype(np.uint8)  # i saw this in a precedent post but it didn't worked
multi_label_classifier.fit(X_train, y_train)

报错栈信息:

ValueError                                Traceback (most recent call last)
<ipython-input-14-cb7366c3ac07> in <cell line: 55>()
     53 multi_label_classifier = MultiOutputClassifier(SVC(kernel='linear', probability=True))
     54 y_train=y_train.astype(np.uint8)
---> 55 multi_label_classifier.fit(X_train, y_train)
     56 
     57 def concatenate_row_elements(matrix):

/usr/local/lib/python3.10/dist-packages/sklearn/svm/_base.py in _validate_targets(self, y)
    747         self.class_weight_ = compute_class_weight(self.class_weight, classes=cls, y=y_)
    748         if len(cls) < 2:
---> 749             raise ValueError(
    750                 "The number of classes has to be greater than one; got %d class"
    751                 % len(cls)
ValueError: The number of classes has to be greater than one; got 1 class
原因分析与解决办法

原因

MultiOutputClassifier的核心逻辑是为每个标签列单独训练一个SVC分类器。你之前的验证仅检查了整个y_train矩阵的整体类别分布,未针对单个标签列做校验——报错本质是某一个(或多个)标签列的样本只有单一类别(全0或全1),导致对应的SVC无法完成训练(SVC要求至少2个类别)。

解决步骤

  1. 定位异常标签列
    运行以下代码找出存在问题的标签列:

    # 遍历每个标签列,检查类别数
    for idx in range(y_train.shape[1]):
        unique_classes = np.unique(y_train[:, idx])
        if len(unique_classes) < 2:
            print(f"标签列{idx}仅含{len(unique_classes)}个类别: {unique_classes}")
            print(f"对应标签名称: {mlb.classes_[idx]}")
    
  2. 处理异常列

    • 若异常列对应「Free」或无效标签,检查MultiLabelBinarizer的classes参数(即G.nodes)是否错误包含该标签,调整后重新生成二值化标签。
    • 若为有效标签但数据分布极端(所有样本为同一类),可选择:
      • 删除该标签列(模型无法从单一类别中学到有效模式):
        # 筛选正常标签列的索引
        valid_cols = [idx for idx in range(y_train.shape[1]) if len(np.unique(y_train[:, idx])) >=2]
        # 过滤训练/测试集标签
        y_train = y_train[:, valid_cols]
        y_test = y_test[:, valid_cols]
        # 更新标签映射(若后续需要逆转换)
        mlb.classes_ = mlb.classes_[valid_cols]
        
      • 检查数据标注逻辑,补充该标签对应类别的样本数据。
  3. 重新训练模型
    完成异常列处理后,重新执行multi_label_classifier.fit(X_train, y_train)即可。

内容的提问来源于stack exchange,提问作者Luca Luca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:53:17