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

使用scikit-learn learning_curve时单类别错误的成因排查咨询

解决ValueError: The number of classes has to be greater than one; got 1的问题

嘿,这个问题我之前也碰到过!虽然你确认标签包含R和N两类,但错误的根源其实出在交叉验证的子集划分上——某个交叉验证fold的训练子集(或者验证集)里只抽到了单一类别。

为什么会出现这种矛盾的情况?

learning_curve针对分类任务默认用StratifiedKFold来划分交叉验证集,它会尽量让每个fold的类别比例和整体数据一致,但你指定了很小的训练样本量(train_sizes=[50,80,110]),如果你的数据本身类别不平衡,或者随机抽样时运气不好,就会出现某一个fold的小训练子集里只有一类标签的情况。比如假设你的R占比90%,抽50个样本时,完全有可能某一次全抽到R,这时候SVM就没法做分类训练了,直接抛出这个错误。

怎么验证这个猜想?

你可以手动跑一段代码,检查每个交叉验证fold里小训练子集的标签分布:

from sklearn.model_selection import StratifiedKFold
import numpy as np

skf = StratifiedKFold(n_splits=5)
for fold_idx, (train_idx, test_idx) in enumerate(skf.split(X, y), 1):
    train_y = y[train_idx]
    print(f"第{fold_idx}个fold的训练集类别:{set(train_y)}")
    # 检查不同训练样本量下的类别情况
    for size in [50, 80, 110]:
        subset_y = train_y[:size]
        print(f"  取前{size}个样本的类别:{set(subset_y)},样本数:{len(subset_y)}")

如果输出里出现某一行的类别只有一种,那就实锤了问题所在。

可行的解决方案

  • 调大训练样本量:把train_sizes里的50换成更大的数值,比如100,确保小样本子集也能覆盖两类标签。
  • 开启分层抽样+打乱:给learning_curve加上shuffle=True和stratify=y参数,强制抽样时保持类别比例:
train_sizes, train_scores, valid_scores = learning_curve(
    SVC(kernel='linear'), X, y, 
    train_sizes=[50, 80, 110], 
    cv=5,
    shuffle=True,
    random_state=42,  # 固定随机种子,结果可复现
    stratify=y
)
  • 先做数据平衡:如果你的数据类别不平衡特别严重(比如一类占比95%以上),可以先用过采样(SMOTE)或欠采样平衡数据,再跑学习曲线。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:50:31