web-dev-qa-db-fra.com

Conversion de la fonction de décision de LinearSVC en probabilités (Scikit learn python)

J'utilise SVM linéaire de scikit learn (LinearSVC) pour un problème de classification binaire. Je comprends que LinearSVC peut me donner les étiquettes prédites et les scores de décision, mais je voulais des estimations de probabilité (confiance dans l'étiquette). Je souhaite continuer à utiliser LinearSVC en raison de la vitesse (par rapport à sklearn.svm.SVC avec noyau linéaire) Est-il raisonnable d'utiliser une fonction logistique pour convertir les scores de décision en probabilités?

import sklearn.svm as suppmach
# Fit model:
svmmodel=suppmach.LinearSVC(penalty='l1',C=1)
predicted_test= svmmodel.predict(x_test)
predicted_test_scores= svmmodel.decision_function(x_test) 

Je veux vérifier s'il est logique d'obtenir des estimations de probabilité simplement comme [1/(1 + exp (-x))] où x est le score de décision.

Sinon, existe-t-il d'autres options par rapport aux classificateurs que je peux utiliser pour le faire efficacement?

Merci.

28
chet

J'ai jeté un œil aux API de la famille sklearn.svm. *. Tous les modèles ci-dessous, par exemple,

  • sklearn.svm.SVC
  • sklearn.svm.NuSVC
  • sklearn.svm.SVR
  • sklearn.svm.NuSVR

avoir un commun interface qui fournit un

probability: boolean, optional (default=False) 

paramètre au modèle. Si ce paramètre est défini sur True, libsvm entraînera un modèle de transformation de probabilité au-dessus des sorties du SVM basé sur l'idée de Platt Scaling . La forme de transformation est similaire à une fonction logistique comme vous l'avez souligné, cependant deux constantes spécifiques A et B sont apprises dans une étape de post-traitement. Voir également ce stackoverflow post pour plus de détails.

enter image description here

En fait, je ne sais pas pourquoi ce post-traitement n'est pas disponible pour LinearSVC. Sinon, vous appelleriez simplement predict_proba(X) pour obtenir l'estimation de probabilité.

Bien sûr, si vous appliquez simplement une transformation logistique naïve, elle ne fonctionnera pas aussi bien qu'une approche calibrée comme Platt Scaling . Si vous pouvez comprendre l'algorithme de soulignement de la mise à l'échelle de plateaux, vous pouvez probablement écrire le vôtre ou contribuer à la famille svm de scikit-learn. :) N'hésitez pas non plus à utiliser les quatre variantes SVM ci-dessus qui prennent en charge predict_proba.

11
greeness

scikit-learn fournit CalibratedClassifierCV qui peut être utilisé pour résoudre ce problème: il permet d'ajouter une sortie de probabilité à LinearSVC ou à tout autre classificateur qui implémente la méthode decision_function:

 svm = LinearSVC()
 clf = CalibratedClassifierCV(svm) 
 clf.fit(X_train, y_train)
 y_proba = clf.predict_proba(X_test)

Le guide de l'utilisateur a un bon section à ce sujet. Par défaut, CalibratedClassifierCV + LinearSVC vous donnera une mise à l'échelle Platt, mais il fournit également d'autres options (méthode de régression isotonique), et il n'est pas limité aux classificateurs SVM.

81
Mikhail Korobov

Si vous voulez de la vitesse, alors juste remplacez le SVM par sklearn.linear_model.LogisticRegression. Cela utilise exactement le même algorithme d'apprentissage que LinearSVC, mais avec une perte de journal au lieu d'une perte de charnière.

L'utilisation de [1/(1 + exp (-x))] produira des probabilités, dans un sens formel (nombres compris entre zéro et un), mais elles n'adhéreront à aucun modèle de probabilité justifiable.

15
Fred Foo

Si ce que vous voulez vraiment, c'est une mesure de confiance plutôt que des probabilités réelles, vous pouvez utiliser la méthode LinearSVC.decision_function(). Voir documentation .

1
Syncrossus