2014-11-24 10 views
11

Sto facendo un compito di classificazione del testo. Ora voglio usare ensemble.AdaBoostClassifier con LinearSVC come base_estimator. Tuttavia, quando provo a eseguire il codicesklearn.ensemble.AdaBoostClassifier non può accludere SVM come base_estimator?

clf = AdaBoostClassifier(svm.LinearSVC(),n_estimators=50, learning_rate=1.0, algorithm='SAMME.R') 
clf.fit(X, y) 

Si è verificato un errore. TypeError: AdaBoostClassifier with algorithm='SAMME.R' requires that the weak learner supports the calculation of class probabilities with a predict_proba method

La prima domanda è Non può il svm.LinearSVC() calcolare le probabilità di classe? Come si fa a calcolare le probabilità?

Then I Modificare il parametro algorithm ed eseguire nuovamente il codice.

clf = AdaBoostClassifier(svm.LinearSVC(),n_estimators=50, learning_rate=1.0, algorithm='SAMME') 
clf.fit(X, y) 

Questa volta si verifica TypeError: fit() got an unexpected keyword argument 'sample_weight'. Come detto in AdaBoostClassifier, Sample weights. If None, the sample weights are initialized to 1/n_samples. Anche se assegno un numero intero a n_samples, si è verificato anche l'errore.

La seconda domanda è Che cosa significa n_samples? Come risolvere questo problema?

Spero che qualcuno possa aiutarmi.

Secondo commento s' @jme, però, dopo aver provato

clf = AdaBoostClassifier(svm.SVC(kernel='linear',probability=True),n_estimators=10, learning_rate=1.0, algorithm='SAMME.R') 
clf.fit(X, y) 

Il programma non può ottenere un risultato e la memoria utilizzata sul server mantiene invariata.

La terza domanda è come posso fare AdaBoostClassifier lavoro con SVC come base_estimator?

+0

in genere si desidera utilizzare un classificatore debole (ancora più debole di uno SVM lineare) nel promuovere, qualcosa di simile a un albero decisionale superficiale (o ceppo). I messaggi di errore che hai ricevuto sono abbastanza semplici: no, non puoi usare 'LinearSVC' qui, poiché la classe non ha un metodo' predicict_proba'. 'SVC' sì, se usi un kernel lineare. – jme

+0

@jme Ho provato 'LinearSVC', ma siccome l'attività è la classificazione del testo, suppongo che potrei usare' SVM' in boosting per migliorare la precisione. Pensi che sia possibile? – allenwang

+0

@jme Sono un principiante nel machine learning, oltre a 'ensemble', conosci altri metodi che possono migliorare l'accuratezza nella classificazione del testo? – allenwang

risposta

9

La risposta giusta dipenderà esattamente quello che stai cercando. LinearSVC non è in grado di prevedere le probabilità di classe (richieste dall'algoritmo predefinito utilizzato da AdaBoostClassifier) ​​e non supporta sample_weight.

È necessario tenere presente che Support Vector Machine non prevede nominalmente probabilità di classe. Sono calcolati usando il ridimensionamento di Platt (o un'estensione del ridimensionamento di Platt nel caso multi-classe), una tecnica che ha problemi noti. Se hai bisogno di meno probabilità "artificiali" di classe, un SVM potrebbe non essere la strada da percorrere.

Con ciò detto, credo che la risposta più soddisfacente data la tua domanda sarebbe quella data da Graham. Cioè,

from sklearn.svm import SVC 
from sklearn.ensemble import AdaBoostClassifier 

clf = AdaBoostClassifier(SVC(probability=True, kernel='linear'), ...) 

Hai altre opzioni. È possibile utilizzare SGDClassifier con una funzione di perdita di cerniera e di impostare AdaBoostClassifier di utilizzare l'algoritmo SAMME (che non richiede una funzione predict_proba, ma richiede il supporto per sample_weight):

from sklearn.linear_model import SGDClassifier 

clf = AdaBoostClassifier(SGDClassifier(loss='hinge'), algorithm='SAMME', ...) 

Forse la risposta migliore sarebbe quella di utilizzare un classificatore con supporto nativo per le probabilità di classe, come Regressione logistica, se si desidera utilizzare l'algoritmo predefinito fornito per AdaBoostClassifier. Puoi farlo usando scikit.linear_model.LogisticRegression o usando SGDClassifier con una funzione di log loss, come usato nel codice fornito da Kris.

Spero che questo aiuti, se sei curioso di sapere cos'è il ridimensionamento di Platt, check out the original paper by John Platt here.

1

è necessario utilizzare uno studente che ha il metodo predict_proba, dal momento che questo non è disponibile in LinearSVC, prova SVC con kernel impostato su 'lineare'

clf = AdaBoostClassifier(svm.SVC(probability=True,kernel='linear'),n_estimators=50,  learning_rate=1.0, algorithm='SAMME') 
clf.fit(X, y) 

, mentre io non sono sicuro se questo sarà produce risultati identici a LinearSVC, dalla documentazione che dice:

simile a SVC con kernel parametro = 'lineare', ma implementato in termini di liblinear piuttosto che libsvm, quindi ha una maggiore flessibilità nella scelta delle sanzioni e la perdita funzioni e dovrebbe scalare meglio (su un gran numero di campioni).

Anche menziona qualcosa su Uno contro Tutto e Uno contro uno in termini di come differiscono.

0

Ho appena avuto un problema simile cercando di utilizzare AdaBoostClassifier con LogisticRegression. I documenti menzionano che il classificatore debole (o base_estimator) deve avere un metodo fit che accetta l'argomento di parola chiave sample_weight=... facoltativo, cfr. domanda #18306416.

Se si desidera utilizzare un SVM o una regressione logistica con AdaBoost, si utilizza il classificatore di discesa del gradiente stocastico di sklearn con loss='hinge' (svm) o loss='log' (logistico), ad es.

from sklearn.linear_model import SGDClassifier 
from sklearn.ensemble import AdaBoostClassifier 

clf = AdaBoostClassifier(SGDClassifier(loss='log'), ...) 

YMMV

+0

grazie per la risposta. ma se SGDClassifier (loss = 'log') è assegnato al primo parametro. Come posso usare il classificatore SVM? Per favore mostrami alcuni dettagli. Ho davvero bisogno del tuo aiuto – allenwang

+0

Hai provato 'loss = 'hinge'' come suggerito? – Kris

1

In realtà, LinearSVC può essere applicato a AdaBoostClassifier senza ridimensionare l'output SVC tramite il ridimensionamento di Platt e l'algoritmo AdaBoost.M1 è stato inizialmente progettato per un classificatore take {-1, 1} come output. La scelta dell'algoritmo predefinito in AdaBoostClassifier è l'algoritmo AdaBoost.SAMME [2] (che specifica "SAMME.R" nell'argomento della parola chiave dell'algoritmo) che è progettato per la classificazione multi-classe.

Tuttavia, il tuo AdearBoost LinearSVC non sarà in grado di fornire predict_proba. Dall'altro lato, se ciò che si desidera è mantenere il segno nell'output anziché inserire l'output SVM nella curva sigmoid per fornire la probabilità. Quindi si modifica l'algoritmo da SAMME.R a SAMME è il modo facile da fare.

[1] Y. Freund, R. Schapire, “A Decision-Theoretic Generalization of on-Line Learning and an Application to Boosting”, 1995.
[2] Zhu, H. Zou, S. Rosset, T. Hastie, “Multi-class AdaBoost”, 2009