Рецензии на imdb


In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

Имеются 25000 рецензий пользователей imdb с бинарными метками, посчитанными по оценкам: 0 при оценке < 5 и 1 при оценке >=7.

Полные данные: https://www.kaggle.com/c/word2vec-nlp-tutorial/data

Загрузим выбоку:


In [2]:
imdb = pd.read_csv('labeledTrainData.tsv', delimiter='\t')
imdb.shape


Out[2]:
(25000, 3)

In [3]:
imdb.head()


Out[3]:
id sentiment review
0 5814_8 1 With all this stuff going down at the moment w...
1 2381_9 1 \The Classic War of the Worlds\" by Timothy Hi...
2 7759_3 0 The film starts with a manager (Nicholas Bell)...
3 3630_4 0 It must be assumed that those who praised this...
4 9495_8 1 Superbly trashy and wondrously unpretentious 8...

Классы сбалансированы:


In [4]:
imdb.sentiment.value_counts()


Out[4]:
1    12500
0    12500
Name: sentiment, dtype: int64

Разобъём выборку на обучение и контроль:


In [5]:
from sklearn.cross_validation import train_test_split
texts_train, texts_test, y_train, y_test = train_test_split(imdb.review.values, imdb.sentiment.values)

Векторизуем тексты рецензий:


In [6]:
from sklearn.feature_extraction.text import TfidfVectorizer
vect = TfidfVectorizer(sublinear_tf=True, use_idf=True)
X_train = vect.fit_transform(texts_train)
X_test = vect.transform(texts_test)

Логистическая регрессия

Настроим на векторизованных данных логистическую регрессию и посчитаем AUC:


In [7]:
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
clf = LogisticRegression()
clf.fit(X_train, y_train)
print metrics.accuracy_score(y_test, clf.predict(X_test))
print metrics.roc_auc_score(y_test, clf.predict_proba(X_test)[:, 1])


0.88448
0.95540516365

Признаков получилось очень много:


In [8]:
X_train.shape


Out[8]:
(18750, 66759)

Попробуем отбирать признаки с помощью лассо:


In [12]:
clf = LogisticRegression(C=0.15, penalty='l1')
clf.fit(X_train, y_train)
print np.sum(np.abs(clf.coef_) > 1e-4)
print metrics.accuracy_score(y_test, clf.predict(X_test))
print metrics.roc_auc_score(y_test, clf.predict_proba(X_test)[:, 1])


113
0.81216
0.896471598776

Ещё один способ отбора признаков — рандомизированная логистическая регрессия:


In [13]:
from sklearn.linear_model import RandomizedLogisticRegression
rlg = RandomizedLogisticRegression(C=0.13)
rlg.fit(X_train, y_train)


Out[13]:
RandomizedLogisticRegression(C=0.13, fit_intercept=True,
               memory=Memory(cachedir=None), n_jobs=1, n_resampling=200,
               normalize=True, pre_dispatch='3*n_jobs', random_state=None,
               sample_fraction=0.75, scaling=0.5, selection_threshold=0.25,
               tol=0.001, verbose=False)

Посмотрим, сколько признаков отбирается:


In [14]:
np.sum(rlg.scores_ > 0)


Out[14]:
121

Настроим логистическую регрессию на отобранных признаках:


In [15]:
X_train_lasso = X_train[:, rlg.scores_ > 0]
X_test_lasso = X_test[:, rlg.scores_ > 0]

In [16]:
clf = LogisticRegression(C=1)
clf.fit(X_train_lasso, y_train)
print metrics.accuracy_score(y_test, clf.predict(X_test_lasso))
print metrics.roc_auc_score(y_test, clf.predict_proba(X_test_lasso)[:, 1])


0.82032
0.905568194979

Метод главных компонент

Сделаем 100 синтетических признаков с помощью метода главных компонент:


In [17]:
from sklearn.decomposition import TruncatedSVD
tsvd = TruncatedSVD(n_components=100)
X_train_pca = tsvd.fit_transform(X_train)
X_test_pca = tsvd.transform(X_test)

Обучим на них логистическую регрессию:


In [18]:
clf = LogisticRegression()
clf.fit(X_train_pca, y_train)
print metrics.accuracy_score(y_test, clf.predict(X_test_pca))
print metrics.roc_auc_score(y_test, clf.predict_proba(X_test_pca)[:, 1])


0.856
0.932861874918

По 100 полученных таким способом признакам качество получается не намного хуже, чем по всем 66702!

Попробуем обучить на них обучить случайный лес:


In [19]:
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=100)
clf.fit(X_train_pca, y_train)
print metrics.accuracy_score(y_test, clf.predict(X_test_pca))
print metrics.roc_auc_score(y_test, clf.predict_proba(X_test_pca)[:, 1])


0.828
0.903574861645

Признаки, которые даёт метод главных компонент, оптимальны для линейных методов, поэтому логистическая регрессия показывает результаты лучше, чем сложные нелинейные классификаторы.