Ответ 1
Чтобы решить эту задачу для линейного SVM, сначала нужно понять формулировку SVM в sklearn и различия, которые она имеет для MultinomialNB.
Причина, по которой most_informative_feature_for_class
работает для MultinomialNB, состоит в том, что вывод coef_
является, по существу, логарифмической вероятностью признаков, заданных классом (и, следовательно, будет иметь размер [nclass, n_features]
, из-за формулировки наивного но если мы проверим документацию для SVM, coef_
не так просто. Вместо coef_
для (линейного) SVM [n_classes * (n_classes -1)/2, n_features]
, потому что каждая из двоичных моделей привязана ко всем возможным классам.
Если мы обладаем некоторыми знаниями о том, какой конкретный коэффициент нам интересен, мы могли бы изменить функцию следующим образом:
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
Это будет работать по назначению и распечатывать ярлыки и верхние n-функции в соответствии с вектором коэффициентов, который вы используете.
Что касается получения правильного вывода для определенного класса, это будет зависеть от предположений и того, что вы хотите вывести. Я предлагаю прочитать документацию по многоуровневому документу в документации SVM, чтобы понять, что вам нужно.
Таким образом, используя train.txt
файл, который был описан в этом question, мы можем получить какой-то выход, хотя в этой ситуации он не является особенно описательным или полезным для интерпретации. Надеюсь, это поможет вам.
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)
с выходом:
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