Python中返回概率的多类别线性支持向量机

3
如何实现一个线性SVM来处理多类问题,并返回测试样本的概率矩阵。 训练样本:mxn 训练标签:mxc 测试标签:mxc,其中每列都有每个类别的概率。
在sklearn中执行“一对其余”LinearSVC的函数不像SVC那样为每个样本返回概率数组。
        print X_train.shape,y.shape
        svc = LinearSVC()
        clf = CalibratedClassifierCV(svc, cv=10)
        clf.fit(X_train, y)

输出:

(7112L, 32L) (7112L, 6L)
Traceback (most recent call last):
  File "SVC_Calibirated_Probability.py", line 171, in <module>
    clf.fit(X_train, y)
  File "C:\Anaconda\lib\site-packages\sklearn\calibration.py", line 110, in fit
    force_all_finite=False)
  File "C:\Anaconda\lib\site-packages\sklearn\utils\validation.py", line 449, in check_X_y
    y = column_or_1d(y, warn=True)
  File "C:\Anaconda\lib\site-packages\sklearn\utils\validation.py", line 485, in column_or_1d
    raise ValueError("bad input shape {0}".format(shape))
ValueError: bad input shape (7112L, 6L)
1个回答

4
LinearSVC不支持概率估计,因为它是基于liblinear的,但是liblinear仅支持逻辑回归的概率估计。
如果您只需要置信度分数,但它们不必是概率,则可以使用decision_function代替。
如果不需要选择线性SVM的惩罚和损失函数,则还可以通过将内核设置为'linear'来使用SVC,然后您可以使用predict_proba
更新#1:
您可以使用SVCOneVsRestClassifier一起支持一对多方案,例如
from sklearn import datasets
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import SVC
iris = datasets.load_iris()
X, y = iris.data, iris.target
clf = OneVsRestClassifier(SVC(kernel='linear', probability=True, class_weight='auto'))
clf.fit(X, y)
proba = clf.predict_proba(X)

更新2:

使用LinearSVC分类器还有另一种估计概率的方法。

from sklearn.svm import LinearSVC
from sklearn.calibration import CalibratedClassifierCV
from sklearn.datasets import load_iris

iris = load_iris()
X = iris.data
Y = iris.target
svc = LinearSVC()
clf = CalibratedClassifierCV(svc, cv=10)
clf.fit(X, Y)
proba = clf.predict_proba(X)

然而,对于另一个问题(如何使Python中的SVM运行更快),这个解决方案也不太可能提高性能,因为它涉及到额外的交叉验证,而且不支持并行化。

更新#3:

对于第二个解决方案,由于LinearSVC不支持多标签分类,所以你需要将其包装在OneVsRestClassifier中,以下是一个示例:

from sklearn.svm import LinearSVC
from sklearn.calibration import CalibratedClassifierCV
from sklearn.multiclass import OneVsRestClassifier
from sklearn.datasets import make_multilabel_classification

X, Y = make_multilabel_classification(n_classes=2, n_labels=1,
                                      allow_unlabeled=True,
                                      return_indicator=True,
                                      random_state=1)
clf0 = CalibratedClassifierCV(LinearSVC(), cv=10)
clf = OneVsRestClassifier(clf0)
clf.fit(X, Y)
proba = clf.predict_proba(X)

谢谢回复。在SVC中实现一对多是否可行? - Abhishek Bhatia
您可以通过设置n_jobs来并行化OneVsRestClassifier。有关更多详细信息,请参见文档 - yangjie
有没有办法让校准过程更快一些,请解释一下。如果不进行并行处理,速度会非常慢。 - Abhishek Bhatia
@yangje 非常感谢您的答复!请问您能否解释一下它是否适用于二进制标签,我尝试了一下但出现了错误。 - Abhishek Bhatia
嗨,我在这里谈论第二个。请查看我在问题中的编辑,它提供了更多细节。 - Abhishek Bhatia
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接