2

Ich versuche, den OneVsRestClassifier verwenden, um Multilabel-Klassifizierung auf eine Reihe von Kommentaren zu tun. Mein Ziel ist es, jeden Kommentar zu einer möglichen Liste von Themen zu taggen. Mein benutzerdefinierter Klassifikator verwendet eine manuell ausgewählte Liste von Wörtern und die entsprechenden Tags in einem CSV, um jeden Kommentar zu markieren. Ich versuche, die Ergebnisse der Bag of Words-Technik und meinen benutzerdefinierten Klassifikator mit dem VotingClassifier zu kombinieren. Hier ist ein Teil meiner vorhandenen Code:Verwenden benutzerdefinierten Klassifizierer für Mutibel Klassifizierung mit GridSearchCV und OneVsRestClassifier

import numpy as np 

from sklearn.base import BaseEstimator, ClassifierMixin 
from sklearn.ensemble import VotingClassifier 
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer 
from sklearn.grid_search import GridSearchCV 
from sklearn.linear_model import SGDClassifier 
from sklearn.multiclass import OneVsRestClassifier 
from sklearn.pipeline import Pipeline 
from sklearn.preprocessing import MultiLabelBinarizer 

class CustomClassifier(BaseEstimator, ClassifierMixin): 
    def __init__(self, word_to_tag): 
     self.word_to_tag = word_to_tag 

    def fit(self, X, y=None): 
     return self 

    def predict_proba(self, X): 
     prob = np.zeros(shape=(len(self.word_to_tag), 2)) 

     for index, comment in np.ndenumerate(X): 
      prob[index] = [0.5, 0.5] 
      for word, label in self.word_to_tag.iteritems(): 
       if (label == self.class_label) and (comment.find(word) >= 0): 
        prob[index] = [0, 1] 
        break 

     return prob 

    def _get_label(self, ...): 
     # Need to have a way of knowing which label being classified 
     # by OneVsRestClassifier (self.class_label) 

bow_clf = Pipeline([('vect', CountVectorizer(stop_words='english', min_df=1, max_df=0.9)), 
        ('tfidf', TfidfTransformer(use_idf=False)), 
        ('clf', SGDClassifier(loss='log', penalty='l2', alpha=1e-3, n_iter=5)), 
        ]) 
custom_clf = CustomClassifier(word_to_tag_dict) 

ovr_clf = OneVsRestClassifier(VotingClassifier(estimators=[('bow', bow_clf), ('custom', custom_clf)], 
               voting='soft')) 

params = { 'estimator_weights': ([1, 1], [1, 2], [2, 1]) } 
gs_clf = GridSearchCV(ovr_clf, params, n_jobs=-1, verbose=1, scoring='precision_samples') 

binarizer = MultiLabelBinarizer() 

gs_clf.fit(X, binarizer.fit_transform(y)) 

Meine Absicht ist es, diese manuell kuratierte Liste von Wörtern durch mehrere Heuristiken zu verwenden, erhalten die Ergebnisse von nur Anwendung Tasche von Wörtern erhalten zu verbessern. Zur Zeit habe ich Schwierigkeiten, einen Weg zu finden, um zu wissen, welches Label während der Vorhersage klassifiziert wird, da eine Kopie von CustomClassifier für jedes Etikett mit OneVsRestClassifier erstellt wird.

+0

self.class_label mir nicht definiert zu sein scheint. Ich bin mir nicht sicher, was Sie mit "welches Etikett wird klassifiziert" meinen, Etiketten werden aus den Daten vorhergesagt. – Manoj

+0

Ja, meine Frage ist im Grunde, wie zu bestimmen, was das 'self.class_label' ist? Wenn OneVsRestClassifier die Daten anpasst, wird der Schätzer (https://github.com/scikit-learn/scikit-learn/blob/51a765a/sklearn/multiclass.py#L73) für jedes zu klassifizierende Label geklont (https: // github.com/scikit-learn/scikit-learn/blob/51a765a/sklearn/multiclass.py#L283) wenn Sie eine Multilabel-Klassifizierung vornehmen. Was ich also brauche, ist eine Möglichkeit für mich zu bestimmen, welcher Label dem geklonten CustomClassifier bei der Berechnung von 'predict_proba' entspricht. – dshah

+0

Um weiter zu beschreiben, lassen Sie mich Ihnen ein Beispiel geben. Sagen wir, der Kommentar ist "Das Essen in diesem Restaurant war großartig. Der Service in diesem Restaurant war auch phänomenal." Und lasst uns sagen, dass ich mit den Labels '[" food "," personal "," location "," other ", ...] gearbeitet habe. Dann erstellt OneVsRestClassifier in diesem Fall für jedes Label einen Klon des 'VotingClassifier'. Dies erzeugt rekursiv auch eine Kopie von 'CustomClassifier' für jedes Etikett. Aber ich weiß nicht, wie ich bestimmen würde, welcher Bezeichnung die spezifische Instanz von 'CustomClassifier' entspricht. – dshah

Antwort

1
+0

'ovr_clf.classes_' scheint nur das numpy Array von 0 zu' n_classes-1' zu sein, wie von 'shape = [n_classes]' beschrieben. Ich suche, um festzustellen, welche Bezeichnung einer der Instanzen von 'VotingClassifier' in dem Array" ovr_clf.estimators_ "entspricht, wenn ich versuche, die Daten zu" passen ". – dshah

+0

entweder dieses Array ist die Antwort oder ich verstehe Ihre Frage nicht. Der erste Schätzer ist Klasse 0 gegenüber dem Rest, der zweite Schätzer ist Klasse 1 gegenüber dem Rest. Wenn Sie Ihre Klassen anders benennen, finden Sie dort ihre Namen. –

+0

Also, wenn ich versuche, die Daten auf 'gs_clf' anzupassen, konvertiert der Multilabel-Binarizer die 'y'-Etiketten von' food', 'staff', 'location', 'other', ...] in ein Array von 1s und 0s '[0 1 0 0 ...]'. Also, was entsprechen die 0 bis 15 in den ovr_clf.classes_? Bedeutet dies, dass jede Reihenfolge der Liste "ovr_clf.estimators_" mit der Reihenfolge der Beschriftungen identisch ist, die die Spalten in "[0 1 0 0 ...]" darstellen? (was im Grunde dasselbe bedeutet wie die Reihenfolge der Klassen in der 'binarizer.classes'-Liste) – dshah