Die Klassifizierer in Paketen für maschinelles Lernen wie liblinear und nltk bieten eine Methode show_most_informative_features()
, die für das Debuggen von Funktionen sehr hilfreich ist:
viagra = None ok : spam = 4.5 : 1.0
hello = True ok : spam = 4.5 : 1.0
hello = None spam : ok = 3.3 : 1.0
viagra = True spam : ok = 3.3 : 1.0
casino = True spam : ok = 2.0 : 1.0
casino = None ok : spam = 1.5 : 1.0
Meine Frage ist, ob etwas Ähnliches für die Klassifikatoren in Scikit-Learn implementiert ist. Ich habe die Dokumentation durchsucht, aber nichts dergleichen gefunden.
Wenn es noch keine solche Funktion gibt, kennt jemand eine Problemumgehung, um zu diesen Werten zu gelangen?
Vielen Dank!
Antworten:
Die Klassifizierer selbst zeichnen keine Feature-Namen auf, sondern sehen nur numerische Arrays. Wenn Sie jedoch Ihre Funktionen mit einem extrahiert
Vectorizer
/CountVectorizer
/TfidfVectorizer
/DictVectorizer
, und Sie sind ein lineares Modell (zBLinearSVC
oder Naive Bayes) , dann können Sie den gleichen Trick , dass die Anwendung Dokumentenklassifizierung Beispiel Verwendungen. Beispiel ( ungetestet , kann einen oder zwei Fehler enthalten):def print_top10(vectorizer, clf, class_labels): """Prints features with the highest coefficient values, per class""" feature_names = vectorizer.get_feature_names() for i, class_label in enumerate(class_labels): top10 = np.argsort(clf.coef_[i])[-10:] print("%s: %s" % (class_label, " ".join(feature_names[j] for j in top10)))
Dies ist für die Klassifizierung mehrerer Klassen vorgesehen. Für den binären Fall denke ich, dass Sie
clf.coef_[0]
nur verwenden sollten. Möglicherweise müssen Sie die sortierenclass_labels
.quelle
coef_
eher so aus als socoef_[0]
.coef_
wird aus Platzgründen abgeflacht.class_labels=clf.classes_
Mit Hilfe des Larsmans-Codes habe ich diesen Code für den Binärfall erstellt:
def show_most_informative_features(vectorizer, clf, n=20): feature_names = vectorizer.get_feature_names() coefs_with_fns = sorted(zip(clf.coef_[0], feature_names)) top = zip(coefs_with_fns[:n], coefs_with_fns[:-(n + 1):-1]) for (coef_1, fn_1), (coef_2, fn_2) in top: print "\t%.4f\t%-15s\t\t%.4f\t%-15s" % (coef_1, fn_1, coef_2, fn_2)
quelle
coef_
Array hat. Daher glaube ich leider nicht, dass es möglich ist, ihn mit den Entscheidungsbaumklassifikatoren von sklearn zu verwenden.fn_1
undfn_2
stehen für die Feature-Namen.RandomForestClassifier
Unterstützt jetzt das.feature_importances_
Attribut, um ein Update hinzuzufügen . Dieses Attribut gibt an, wie viel von der beobachteten Varianz durch diese Funktion erklärt wird. Offensichtlich muss die Summe aller dieser Werte <= 1 sein.Ich finde dieses Attribut sehr nützlich, wenn ich Feature-Engineering durchführe.
Vielen Dank an das Scikit-Learn-Team und die Mitwirkenden für die Umsetzung!
Bearbeiten: Dies funktioniert sowohl für RandomForest als auch für GradientBoosting. Also
RandomForestClassifier
,RandomForestRegressor
,GradientBoostingClassifier
undGradientBoostingRegressor
alle unterstützen diese.quelle
Wir haben kürzlich eine Bibliothek veröffentlicht ( https://github.com/TeamHG-Memex/eli5 ), die dies ermöglicht: Sie behandelt verschiedene Klassifizierer aus Scikit-Learn-, Binär- / Mehrklassenfällen und ermöglicht das Hervorheben von Text gemäß Feature-Werten , integriert sich in IPython usw.
quelle
Ich musste tatsächlich die Wichtigkeit von Features in meinem NaiveBayes-Klassifikator herausfinden, und obwohl ich die oben genannten Funktionen verwendet habe, konnte ich die Feature-Wichtigkeit nicht anhand von Klassen ermitteln. Ich habe die Dokumentation von scikit-learn durchgesehen und die oben genannten Funktionen ein wenig optimiert, um festzustellen, dass sie für mein Problem funktionieren. Hoffe es hilft dir auch!
def important_features(vectorizer,classifier,n=20): class_labels = classifier.classes_ feature_names =vectorizer.get_feature_names() topn_class1 = sorted(zip(classifier.feature_count_[0], feature_names),reverse=True)[:n] topn_class2 = sorted(zip(classifier.feature_count_[1], feature_names),reverse=True)[:n] print("Important words in negative reviews") for coef, feat in topn_class1: print(class_labels[0], coef, feat) print("-----------------------------------------") print("Important words in positive reviews") for coef, feat in topn_class2: print(class_labels[1], coef, feat)
quelle
Sie können auch Folgendes tun, um ein Diagramm mit wichtigen Funktionen in der angegebenen Reihenfolge zu erstellen:
importances = clf.feature_importances_ std = np.std([tree.feature_importances_ for tree in clf.estimators_], axis=0) indices = np.argsort(importances)[::-1] # Print the feature ranking #print("Feature ranking:") # Plot the feature importances of the forest plt.figure() plt.title("Feature importances") plt.bar(range(train[features].shape[1]), importances[indices], color="r", yerr=std[indices], align="center") plt.xticks(range(train[features].shape[1]), indices) plt.xlim([-1, train[features].shape[1]]) plt.show()
quelle
RandomForestClassifier
hat noch keinencoef_
attrubute, aber es wird in der Version 0.17, denke ich. Weitere Informationen finden Sie in derRandomForestClassifierWithCoef
Klasse unter Eliminierung rekursiver Features in Random Forest mithilfe von Scikit-Learn . Dies kann Ihnen einige Ideen geben, um die oben genannte Einschränkung zu umgehen.quelle
Nicht genau das, wonach Sie suchen, aber eine schnelle Möglichkeit, die größten Größenkoeffizienten zu erhalten (vorausgesetzt, die Spalten eines Pandas-Datenrahmens sind Ihre Feature-Namen):
Sie haben das Modell wie folgt trainiert:
lr = LinearRegression() X_train, X_test, y_train, y_test = train_test_split(df, Y, test_size=0.25) lr.fit(X_train, y_train)
Erhalten Sie die 10 größten negativen Koeffizientenwerte (oder ändern Sie sie in umgekehrt = True für die größten positiven) wie:
sorted(list(zip(feature_df.columns, lr.coef_)), key=lambda x: x[1], reverse=False)[:10]
quelle
Erst eine Liste erstellen, ich gebe dieser Liste das Namensschild. Danach extrahiere ich alle Features Namen und Spaltennamen, die ich in der Beschriftungsliste hinzufüge. Hier benutze ich naives Bayes-Modell. Im naiven Bayes-Modell gibt feature_log_prob_ die Wahrscheinlichkeit von Features an.
def top20(model,label): feature_prob=(abs(model.feature_log_prob_)) for i in range(len(feature_prob)): print ('top 20 features for {} class'.format(i)) clas = feature_prob[i,:] dictonary={} for count,ele in enumerate(clas,0): dictonary[count]=ele dictonary=dict(sorted(dictonary.items(), key=lambda x: x[1], reverse=True)[:20]) keys=list(dictonary.keys()) for i in keys: print(label[i]) print('*'*1000)
quelle