tutorial tfidfvectorizer stable scikit org machine logistic learning learn index idf forest auto_examples python pandas machine-learning nlp scikit-learn

python - tfidfvectorizer - ¿Problemas para obtener la mayoría de las características informativas con scikit aprender?



text classification machine learning (1)

Estoy tratando de obtener las características más informativas de un corpus textual . De esta question bien respondida, sé que esta tarea se podría hacer de la siguiente manera:

def most_informative_feature_for_class(vectorizer, classifier, classlabel, n=10): labelid = list(classifier.classes_).index(classlabel) feature_names = vectorizer.get_feature_names() topn = sorted(zip(classifier.coef_[labelid], feature_names))[-n:] for coef, feat in topn: print classlabel, feat, coef

Entonces:

most_informative_feature_for_class(tfidf_vect, clf, 5)

Para esta clase:

X = tfidf_vect.fit_transform(df[''content''].values) y = df[''label''].values from sklearn import cross_validation X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.33) clf = SVC(kernel=''linear'', C=1) clf.fit(X, y) prediction = clf.predict(X_test)

El problema es la salida de most_informative_feature_for_class :

5 a_base_de_bien bastante (0, 2451) -0.210683496368 (0, 3533) -0.173621065386 (0, 8034) -0.135543062425 (0, 10346) -0.173621065386 (0, 15231) -0.154148294738 (0, 18261) -0.158890483047 (0, 21083) -0.297476572586 (0, 434) -0.0596263855375 (0, 446) -0.0753492277856 (0, 769) -0.0753492277856 (0, 1118) -0.0753492277856 (0, 1439) -0.0753492277856 (0, 1605) -0.0753492277856 (0, 1755) -0.0637950312345 (0, 3504) -0.0753492277856 (0, 3511) -0.115802483001 (0, 4382) -0.0668983049212 (0, 5247) -0.315713152154 (0, 5396) -0.0753492277856 (0, 5753) -0.0716096348446 (0, 6507) -0.130661516772 (0, 7978) -0.0753492277856 (0, 8296) -0.144739048504 (0, 8740) -0.0753492277856 (0, 8906) -0.0753492277856 : : (0, 23282) 0.418623443832 (0, 4100) 0.385906085143 (0, 15735) 0.207958503155 (0, 16620) 0.385906085143 (0, 19974) 0.0936828782325 (0, 20304) 0.385906085143 (0, 21721) 0.385906085143 (0, 22308) 0.301270427482 (0, 14903) 0.314164150621 (0, 16904) 0.0653764031957 (0, 20805) 0.0597723455204 (0, 21878) 0.403750815828 (0, 22582) 0.0226150073272 (0, 6532) 0.525138162099 (0, 6670) 0.525138162099 (0, 10341) 0.525138162099 (0, 13627) 0.278332617058 (0, 1600) 0.326774799211 (0, 2074) 0.310556919237 (0, 5262) 0.176400451433 (0, 6373) 0.290124806858 (0, 8593) 0.290124806858 (0, 12002) 0.282832270298 (0, 15008) 0.290124806858 (0, 19207) 0.326774799211

No está devolviendo la etiqueta ni las palabras. ¿Por qué sucede esto y cómo puedo imprimir las palabras y las etiquetas? Chicos, esto está ocurriendo ya que estoy usando pandas para leer los datos? Otra cosa que probé es la siguiente, formule esta question :

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))) print_top10(tfidf_vect,clf,y)

Pero me sale este rastro:

Rastreo (llamadas recientes más última):

File "/Users/user/PycharmProjects/TESIS_FINAL/Classification/Supervised_learning/Final/experimentos/RBF/SVM_con_rbf.py", line 237, in <module> print_top10(tfidf_vect,clf,5) File "/Users/user/PycharmProjects/TESIS_FINAL/Classification/Supervised_learning/Final/experimentos/RBF/SVM_con_rbf.py", line 231, in print_top10 for i, class_label in enumerate(class_labels): TypeError: ''int'' object is not iterable

¿Alguna idea de cómo resolver esto, para obtener las características con los valores de coeficiente más altos?


Para resolver esto específicamente para SVM lineal, primero tenemos que entender la formulación de SVM en sklearn y las diferencias que tiene con MultinomialNB.

La razón por la que most_informative_feature_for_class funciona para MultinomialNB es porque la salida de coef_ es esencialmente la probabilidad de registro de características dadas una clase (y por lo tanto sería de tamaño [nclass, n_features] , debido a la formulación del problema naive bayes. Pero si verificamos la documentation para SVM, el coef_ no es tan simple, en su lugar coef_ para (lineal) SVM es [n_classes * (n_classes -1)/2, n_features] porque cada uno de los modelos binarios se ajusta a cada clase posible.

Si poseemos algún conocimiento sobre qué coeficiente particular nos interesa, podríamos modificar la función para que se parezca a lo siguiente:

def most_informative_feature_for_class_svm(vectorizer, classifier, classlabel, n=10): labelid = ?? # this is the coef we''re interested in. feature_names = vectorizer.get_feature_names() svm_coef = classifier.coef_.toarray() topn = sorted(zip(svm_coef[labelid], feature_names))[-n:] for coef, feat in topn: print feat, coef

Esto funcionaría según lo previsto e imprimirá las etiquetas y las principales n características de acuerdo con el vector de coeficiente que está buscando.

En cuanto a obtener la salida correcta para una clase en particular, eso dependería de las suposiciones y de lo que pretende obtener. Sugiero leer la documentación en varias clases dentro de la documentación de SVM para tener una idea de lo que está buscando.

Entonces, al utilizar el file train.txt que se describió en esta question , podemos obtener algún tipo de resultado, aunque en esta situación no es particularmente descriptivo o útil de interpretar. Esperemos que esto te ayude.

import codecs, re, time from itertools import chain import numpy as np from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB trainfile = ''train.txt'' # Vectorizing data. train = [] word_vectorizer = CountVectorizer(analyzer=''word'') trainset = word_vectorizer.fit_transform(codecs.open(trainfile,''r'',''utf8'')) tags = [''bs'',''pt'',''es'',''sr''] # Training NB mnb = MultinomialNB() mnb.fit(trainset, tags) from sklearn.svm import SVC svcc = SVC(kernel=''linear'', C=1) svcc.fit(trainset, tags) def most_informative_feature_for_class(vectorizer, classifier, classlabel, n=10): labelid = list(classifier.classes_).index(classlabel) feature_names = vectorizer.get_feature_names() topn = sorted(zip(classifier.coef_[labelid], feature_names))[-n:] for coef, feat in topn: print classlabel, feat, coef def most_informative_feature_for_class_svm(vectorizer, classifier, n=10): labelid = 3 # this is the coef we''re interested in. feature_names = vectorizer.get_feature_names() svm_coef = classifier.coef_.toarray() topn = sorted(zip(svm_coef[labelid], feature_names))[-n:] for coef, feat in topn: print feat, coef most_informative_feature_for_class(word_vectorizer, mnb, ''pt'') print most_informative_feature_for_class_svm(word_vectorizer, svcc)

con salida:

pt teve -4.63472898823 pt tive -4.63472898823 pt todas -4.63472898823 pt vida -4.63472898823 pt de -4.22926388012 pt foi -4.22926388012 pt mais -4.22926388012 pt me -4.22926388012 pt as -3.94158180767 pt que -3.94158180767 no 0.0204081632653 parecer 0.0204081632653 pone 0.0204081632653 por 0.0204081632653 relación 0.0204081632653 una 0.0204081632653 visto 0.0204081632653 ya 0.0204081632653 es 0.0408163265306 lo 0.0408163265306