He implementado la clasificación de texto usando tf-idf y SVM siguiendo el tutorial de este tutorial
La clasificación está funcionando correctamente. Ahora quiero trazar los valores de tf-idf (es decir, las características) y también ver cómo se generó el hiperplano final que clasifica los datos en dos clases.
El código implementado es el siguiente:
import os import numpy as np from sklearn.naive_bayes import MultinomialNB from sklearn.metrics import confusion_matrix from sklearn.svm import LinearSVC from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import StratifiedKFold def make_Corpus(root_dir): polarity_dirs = [os.path.join(root_dir,f) for f in os.listdir(root_dir)] corpus = [] for polarity_dir in polarity_dirs: reviews = [os.path.join(polarity_dir,f) for f in os.listdir(polarity_dir)] for review in reviews: doc_string = ""; with open(review) as rev: for line in rev: doc_string = doc_string + line if not corpus: corpus = [doc_string] else: corpus.append(doc_string) return corpus #Create a corpus with each document having one string root_dir = 'txt_sentoken' corpus = make_Corpus(root_dir) #Stratified 10-cross fold validation with SVM and Multinomial NB labels = np.zeros(2000); labels[0:1000]=0; labels[1000:2000]=1; kf = StratifiedKFold(n_splits=10) totalsvm = 0 # Accuracy measure on 2000 files totalNB = 0 totalMatSvm = np.zeros((2,2)); # Confusion matrix on 2000 files totalMatNB = np.zeros((2,2)); for train_index, test_index in kf.split(corpus,labels): X_train = [corpus[i] for i in train_index] X_test = [corpus[i] for i in test_index] y_train, y_test = labels[train_index], labels[test_index] vectorizer = TfidfVectorizer(min_df=5, max_df = 0.8, sublinear_tf=True, use_idf=True,stop_words='english') train_corpus_tf_idf = vectorizer.fit_transform(X_train) test_corpus_tf_idf = vectorizer.transform(X_test) model1 = LinearSVC() model2 = MultinomialNB() model1.fit(train_corpus_tf_idf,y_train) model2.fit(train_corpus_tf_idf,y_train) result1 = model1.predict(test_corpus_tf_idf) result2 = model2.predict(test_corpus_tf_idf) totalMatSvm = totalMatSvm + confusion_matrix(y_test, result1) totalMatNB = totalMatNB + confusion_matrix(y_test, result2) totalsvm = totalsvm+sum(y_test==result1) totalNB = totalNB+sum(y_test==result2) print totalMatSvm, totalsvm/2000.0, totalMatNB, totalNB/2000.0
He leído cómo trazar los gráficos, pero no pude encontrar ningún tutorial relacionado para trazar las características de tf-idf y también el hiperplano generado por SVM.
Primero, debe seleccionar solo 2 funciones para crear el gráfico de superficie de decisión bidimensional.
from sklearn.svm import SVC import numpy as np import matplotlib.pyplot as plt from sklearn import svm, datasets from sklearn.datasets import fetch_20newsgroups from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer from sklearn.pipeline import Pipeline import matplotlib.pyplot as plt newsgroups_train = fetch_20newsgroups(subset='train', categories=['alt.atheism', 'sci.space']) pipeline = Pipeline([('vect', CountVectorizer()), ('tfidf', TfidfTransformer())]) X = pipeline.fit_transform(newsgroups_train.data).todense() # Select ONLY 2 features X = np.array(X) X = X[:, [0,1]] y = newsgroups_train.target def make_meshgrid(x, y, h=.02): x_min, x_max = x.min() - 1, x.max() + 1 y_min, y_max = y.min() - 1, y.max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) return xx, yy def plot_contours(ax, clf, xx, yy, **params): Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) out = ax.contourf(xx, yy, Z, **params) return out model = svm.SVC(kernel='linear') clf = model.fit(X, y) fig, ax = plt.subplots() # title for the plots title = ('Decision surface of linear SVC ') # Set-up grid for plotting. X0, X1 = X[:, 0], X[:, 1] xx, yy = make_meshgrid(X0, X1) plot_contours(ax, clf, xx, yy, cmap=plt.cm.coolwarm, alpha=0.8) ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors='k') ax.set_ylabel('y label here') ax.set_xlabel('x label here') ax.set_xticks(()) ax.set_yticks(()) ax.set_title(title) ax.legend() plt.show()
RESULTADOS
La ttwig no es agradable ya que seleccionamos al azar solo 2 características para crearla. Una forma de hacerlo agradable es la siguiente: puede usar un univariate ranking method
(p. Ej., Prueba ANOVA de valor F) y encontrar las mejores funciones top-2
. Luego, utilizando estos dos elementos top-2
podría crear una buena gráfica de superficie de separación.