如何在 scikit-learn 中为 OneVsRestClassifier 设置类权重?

Posted

技术标签:

【中文标题】如何在 scikit-learn 中为 OneVsRestClassifier 设置类权重?【英文标题】:How to set class weights for OneVsRestClassifier in scikit-learn? 【发布时间】:2013-04-10 21:19:58 【问题描述】:

我需要一个 SVM 作为多标签分类器,所以我决定使用 OneVsRestClassifier 包装器。然而问题出现了,训练集变得高度不平衡:对于给定的类,负样本比正样本多得多。这可以通过 class_weight 参数来解决,但是如果我在封装在 OneVsRestClassifier 中的分类器中使用它,则会出现错误:

from sklearn.svm import LinearSVC
from sklearn.multiclass import OneVsRestClassifier

weights = 'ham': 1, 'eggs': 2
svm = OneVsRestClassifier(LinearSVC(class_weight=weights))

X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
Y = [['ham'], [], ['eggs', 'spam'], ['spam'], ['eggs']]

svm.fit(X, Y)
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/local/lib/python2.7/site-packages/sklearn/multiclass.py", line 197, in fit
    n_jobs=self.n_jobs)
  File "/usr/local/lib/python2.7/site-packages/sklearn/multiclass.py", line 87, in fit_ovr
    for i in range(Y.shape[1]))
  File "/usr/local/lib/python2.7/site-packages/sklearn/externals/joblib/parallel.py", line 514, in __call__
    self.dispatch(function, args, kwargs)
  File "/usr/local/lib/python2.7/site-packages/sklearn/externals/joblib/parallel.py", line 311, in dispatch
    job = ImmediateApply(func, args, kwargs)
  File "/usr/local/lib/python2.7/site-packages/sklearn/externals/joblib/parallel.py", line 135, in __init__
    self.results = func(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/sklearn/multiclass.py", line 56, in _fit_binary
    estimator.fit(X, y)
  File "/usr/local/lib/python2.7/site-packages/sklearn/svm/base.py", line 681, in fit
    self.classes_, y)
  File "/usr/local/lib/python2.7/site-packages/sklearn/utils/class_weight.py", line 49, in compute_class_weight
    if classes[i] != c:
IndexError: index 2 is out of bounds for axis 0 with size 2

【问题讨论】:

【参考方案1】:

问题在于 LinearSVC 需要二进制类 [0, 1]。因此,为非二进制类('ham'、'egg' 甚至 [0,1,2])赋予权重会失败。 但是您可以改用“自动”权重,它会通过选择适当的权重来自动“平衡”您的课程。然后它也适用于您的多类 OneVsRest 分类器。

svm = OneVsRestClassifier(LinearSVC(class_weight='auto'))

X = [[1, 2], [3, 4], [5, 4]]
Y = [0,1,2]

svm.fit(X, Y)

【讨论】:

行得通,谢谢!我没有意识到有一个“自动”选项。 有没有办法在 OneVsRestClassifier 中为每个标签分别提供 sample_weight ?由于 GradientBoostingClassifier 没有 class_weight 选项,所以不平衡数据需要指定 sample_weight。

以上是关于如何在 scikit-learn 中为 OneVsRestClassifier 设置类权重?的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 中为文本分类排列文本数据的标准方法是啥?

有没有办法在 Python 中为具有多个分类的随机森林制作部分依赖图(使用 scikit-learn)?

在 scikit-learn 中为 KNN 使用除 p-norm 之外的其他成对距离度量

如何在 Scikit-Learn 的随机森林分类器中设置子样本大小?特别是对于不平衡的数据

多分类学习方法One vs. RestOne vs. OneMany vs. Many多输出分类

如何在 python 中为 sklearn dump_svmlight_file 指定功能名称?