3

How can I implement a linear SVM for multi-class which returns the proabability matrix for the test samples. Train samples: mxn Train labels: mxc Test labels : mxc, where column has the probability of each class.

The function in sklearn which does "one-vs-the-rest" LinearSVC doesn't return probablity array for each sample like SVC which has predict_proba

Edit

Code:

        print X_train.shape,y.shape
        svc = LinearSVC()
        clf = CalibratedClassifierCV(svc, cv=10)
        clf.fit(X_train, y)

Output:

(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)
Abhishek Bhatia
  • 9,404
  • 26
  • 87
  • 142

1 Answers1

4

LinearSVC does not support probability estimates because it is based on liblinear but liblinear supports probability estimates for logistic regression only.

If you just need confidence scores, but these do not have to be probabilities, you can use decision_function instead.

If it it not required to choose penalties and loss functions of linear SVM, you can also use SVC by setting kernel to be 'linear', then you can have predict_proba.

Update #1:

You can use SVC with OneVsRestClassifier to support one-vs-rest scheme, for example

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)

Update #2:

There is another way to estimate probabilities with LinearSVC as classifier.

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)

However for the other question (Making SVM run faster in python), this solution is not likely to enhance performance either as it involves additional cross-validation and does not support parallelization.

Update #3:

For the second solution, because LinearSVC does not support multilabel classification, so you have to wrap it in OneVsRestClassifier, here is an example:

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)
Community
  • 1
  • 1
yangjie
  • 6,619
  • 1
  • 33
  • 40
  • thanks for the reply. Is possible to implement one vs rest in SVC? – Abhishek Bhatia Jul 25 '15 at 06:03
  • Thanks so much! It works perfect. I am implementing this on train-set with dimensions(1422392,29) and test-set (233081,29). It works very slow. Any suggestions? Can I parallelise, I couldn't find any examples online. – Abhishek Bhatia Jul 27 '15 at 14:54
  • You can parallelize `OneVsRestClassifier ` by setting `n_jobs`. See the [doc](http://scikit-learn.org/stable/modules/generated/sklearn.multiclass.OneVsRestClassifier.html) for more details. – yangjie Jul 27 '15 at 15:00
  • Anyway to run the calibration faster, please explain. Without parallelization it will be extremely slow. – Abhishek Bhatia Aug 09 '15 at 21:24
  • @yangje Thanks so much for your answer! Can you please explain if it works with binary labels, I tried it it gives an error. – Abhishek Bhatia Aug 12 '15 at 08:03
  • Hi, I am talking about the second one here. Please my edit in the question it provides more details. – Abhishek Bhatia Aug 12 '15 at 08:44
  • Sorry I misunderstood your question. It does not support multilabel becuause `LinearSVC` does not. You can wrap it with `OneVsRestClassifier` for multilabel, but you cannot expect high speed either. – yangjie Aug 12 '15 at 09:23
  • Thanks for quick response. Can you please explain what do mean by "wrap" with it. Sorry, I am fairly new to ML and python terminology. – Abhishek Bhatia Aug 12 '15 at 09:34
  • Just like the first solution, pass a `LinearSVC` estimator as the parameter of `OneVsRestClassifier` – yangjie Aug 12 '15 at 09:38
  • Can you please change code if possible to make more clear. – Abhishek Bhatia Aug 12 '15 at 10:18
  • Thanks for the response. I was trying to do this but by doing the `CalibratedClassifierCV` of the `OneVsRestClassifier` instead of the other way around, and I was getting `ValueError: bad input shape (7769, 90)` – Iván Sánchez Feb 27 '20 at 16:55