#!/usr/bin/env python
# coding: utf-8
#
#
# Методы машинного обучения
# Семинар: методы сжатия признаков
# Введение в NLP
# In[1]:
get_ipython().run_line_magic('matplotlib', 'inline')
# In[2]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = (12,8)
# # Методы понижения размерности
# In[3]:
# Load data
df_wine = pd.read_csv('data/winequality-red.csv', sep=';')
# Make classification target feature
df_wine.loc[:, 'quality_cat'] = (df_wine.quality > 5).astype(int)
df_wine = df_wine.drop('quality', axis=1)
# Get descriptive and target features
X = df_wine.iloc[:, :-1].values
y = df_wine.iloc[:, -1].values
# ## PCA
# Попробуем получить PCA разными способами
# ## PCA через sklearn
# In[4]:
from sklearn.decomposition import PCA
# In[6]:
X.shape
# In[5]:
pca = PCA(n_components=5, random_state=123)
# In[7]:
pca.fit(X)
# In[8]:
Z = pca.transform(X)
# In[9]:
Z.shape
# In[11]:
pca.components_.shape
# In[12]:
Z[:5]
# In[17]:
X.mean(axis=0)
# In[15]:
pca.mean_
# In[18]:
X_ = X - X.mean(axis=0)
# In[19]:
Z_ = X_.dot(pca.components_.T)
# In[20]:
Z_[:5]
# In[21]:
# А теперь еще и шкалируем признаки
X = (X - X.mean(axis=0))/X.std(axis=0)
# In[22]:
pca.fit(X)
# In[27]:
pca.explained_variance_ratio_
# ## PCA через ковариационную матрицу
# In[29]:
from numpy.linalg import eig
# In[28]:
C = X.T.dot(X)
# In[31]:
lambd, W = eig(C)
# In[32]:
lambd
# In[40]:
W.T[:2]
# In[41]:
W = W.T[:5, :]
# In[39]:
pca.components_[:2]
# In[42]:
Z = pca.transform(X)
# In[43]:
Z_ = X.dot(W.T)
# In[45]:
Z[:3]
# In[46]:
Z_[:3]
# In[47]:
pca.explained_variance_ratio_
# In[49]:
exp_var = lambd/lambd.sum()
exp_var
# ## Оценка качества при разных количествах компонент
#
# Реализуйте 2 пайплайна:
# * StandartScaler + LogisticRegression
# * StandartScaler + PCA + LogisticRegression
#
# Оцените качество пайплайна с PCA при разных количествах компонент и сравните его с первым
# In[50]:
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import StratifiedKFold, cross_val_score
# In[51]:
model1 = Pipeline([
('scaler', StandardScaler()),
('clf', LogisticRegression())
])
# In[52]:
cv = StratifiedKFold(n_splits=5, random_state=123, shuffle=True)
# In[55]:
score_model1 = cross_val_score(model1, X, y, cv=cv, scoring='roc_auc').mean()
score_model1
# In[58]:
from sklearn.model_selection import validation_curve
# In[59]:
k_range = range(1, 12)
scores = []
for k in k_range:
model2 = Pipeline([
('scaler', StandardScaler()),
('pca', PCA(n_components=k)),
('clf', LogisticRegression())
])
scores.append(cross_val_score(model2, X, y, cv=cv, scoring='roc_auc').mean())
# In[62]:
plt.plot(k_range, scores)
plt.hlines(score_model1, 1,11)
# ## Singular Value Decomposition
#
# Для любой матрицы $A$ размера $n \times m$ и ранга $r$ можно найти разложение вида:
# $$ A = U \Sigma V^\top ,$$
# где
# * $U$ - унитарная матрица, состоящая из собственных векторов $AA^\top$
# * $V$ - унитарная матрица, состоящая из собственных векторов $A^\top A$
# * $\Sigma$ - диагональная матрица с сингулярными числами $s_i = \sqrt{\lambda_i}$
#
#
# ## SVD via PCA
# Матрицы $U$ и $V$ ортогональны и могут быть использованы для перехода к ортогональному базису:
# $$ AV = U\Sigma $$
#
#
# In[ ]:
from numpy.linalg import svd
# In[ ]:
# ## Рационы питания в странах
# * Загрузите набор данных о пищевом рационе в разных странах мира `diet.csv`
# * Примените на данных PCA с 2 компонентами
# * Изобразите объекты в сжатом пространстве
# In[63]:
df = pd.read_csv('data/diet.csv', sep=';')
# In[64]:
df.head()
# In[68]:
X = df.iloc[:, 1:-1].values
# In[70]:
X_ = (X - X.mean(axis=0))/X.std(axis=0)
pca = PCA(n_components=2, random_state=123)
# In[74]:
# pca.fit(X_)
# Z = pca.transform(X_)
Z = pca.fit_transform(X_) # Сразу fit на X а потом его transform
# In[73]:
plt.scatter(Z[:,0], Z[:,1])
# In[75]:
idx = Z[:, 1] > 20
# In[110]:
strange = df.loc[idx].values[0,1:-1]
# In[111]:
field_names = df.columns[1:-1].values
# In[120]:
df.loc[:, 'Alcoholic Beverages (kcal/day)'].plot(kind='box')
# In[117]:
field_names
# In[112]:
d = X - strange
# In[116]:
pd.Series(index=field_names, data=d.mean(axis=0)).sort_values()
# * Скорее всего вы обнаружите некоторые выбросы, с этим ничего не поделать - PCA чувствителен к выбросам
# * Удалите объекты-выборосы и повторите процедуру
# # PCA для текстов
# #### Он же Latent Semantic Index или Latent Semantic Allocation
# * Когда мы работаем с текстами, бы обычно переходим к модели мешка слов
# * Что если мы ходим применить для текстов PCA?
# * Центрировать данные мы не можем, так как тогда наша огромная матрица с признаками будет плотной, а значит будет очень много весить
# * Давайте не будем центрировать! =D
# In[121]:
from sklearn.decomposition import TruncatedSVD
# In[122]:
df = pd.read_csv('data/sentiment/imdb_labelled.txt', sep='\t', header=None, names=['text', 'label'])
# In[123]:
df.head()
# In[124]:
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.pipeline import Pipeline
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import RandomizedSearchCV, GridSearchCV
# In[125]:
text = df.text.values
# In[126]:
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(text)
# In[128]:
text.shape
# In[129]:
X
# In[127]:
X.shape
# In[135]:
pcaish = TruncatedSVD(n_components=3, random_state=123)
pca = PCA(n_components=3, random_state=123)
Z = pcaish.fit_transform(X)
# Z = pca.fit_transform(X)
# In[136]:
Z
# In[138]:
model = Pipeline([
('vect', CountVectorizer(max_df=0.95, stop_words='english', ngram_range=(1,1))),
('pca', TruncatedSVD(n_components=3, random_state=123)),
('clf', LogisticRegression())
])
# In[139]:
label = df.label.values
# In[140]:
model.fit(text, label)
# # T-SNE
# #### Задание
# Сожмите признаковое пространство данных с цифрами с помощью tsne.
# In[141]:
from sklearn.datasets import load_digits
# In[142]:
data = load_digits()
# In[144]:
labels = data['target']
# In[146]:
imgs = data['images']
# In[ ]:
plt.imshow(imgs[1], cmap=plt.cm.gray_r)
# In[151]:
X = data['data']
# In[152]:
X.shape
# In[153]:
from sklearn.manifold import TSNE
# In[166]:
tsne = TSNE(perplexity=5,)
# In[167]:
tsne.fit(X)
# In[168]:
Z = tsne.embedding_
# In[169]:
plt.scatter(Z[:, 0], Z[:, 1], c=labels)
# In[165]:
plt.scatter(Z[:, 0], Z[:, 1], c=labels)