#!/usr/bin/env python
# coding: utf-8
#
#
# Методы машинного обучения
# Семинар: введение
# 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)
# # Вспоминаем Pandas
# ### Удотребление ЛСД и успеваемость
# В 1968 году была [опубликована](http://www.ncbi.nlm.nih.gov/pubmed/5676802) статья под интригующем названием Correlation of Performance Test Scores with Tissue Concentration of Lysergic Acid Diethylamide in Human Subjects.
#
# К статье приложен небольшой набор [данных](https://www.dropbox.com/s/ui14yeeckbc6z7c/drugs-and-math.csv?dl=0), состоящий из 7 наблюдений
# In[3]:
df = pd.read_csv('./data/drugs-and-math.csv',
index_col=0,
sep=',')
# Таблица уже отсортирована по колонке Drugs - отсортируем по колонке Score
# In[4]:
df = df.sort_values('Score',
ascending=False)
# In[5]:
df.head()
# Визуализируйте данные с помощью scatter plot. Видна ли тенденция, как можно ее измерить?
# In[6]:
df.plot(x='Drugs', y='Score', kind='scatter')
# In[7]:
df.corr()
# ### Рождаемость в США
# Загрузите два набора данных с информацией о рождаемости в США: [Набор 1](https://www.dropbox.com/s/4v743y3e25lz0an/US_births_1994-2003_CDC_NCHS.csv?dl=0), [Набор 2](https://www.dropbox.com/s/3aoulbiuomamay6/US_births_2000-2014_SSA.csv?dl=0)
# In[8]:
df1 = pd.read_csv('./data/US_births_1994-2003_CDC_NCHS.csv')
df2 = pd.read_csv('./data/US_births_2000-2014_SSA.csv')
# `Pandas` обладает мощным функционалом для работы с временными рядами. Самое главное, пожалуй правильно задать столбец с датой в DataFrame. Вернемся к данным:
# In[9]:
df1.head()
# Функция `pd.to_datetime()` преобразовывать сырые данные с специальный тип Timestamp. Делать это можно одним из нескольких способов:
# * Задан столбец, в котором дата записана в виде строчки произвольного формата (например 2016-03-01, 01032016, 01.03.16 ...)
#
# В этом случае вам надо указать в `pd.to_datetime()` [формат](http://strftime.org/) даты
#
# In[11]:
print(pd.to_datetime('2016-03-01', format='%Y-%m-%d'))
print(pd.to_datetime('01032016', format='%d%m%Y'))
print(pd.to_datetime('01-mar-2016', format='%d-%b-%Y'))
# * Задано несколько столбцов, скаждый из которых содержит элемент даты (столбец под день, месяц, год)
#
# Тогда, `pd.to_datetime()` подается 3 столбца из таблицы, которые должны **обязательно** именоваться `['year', 'month', 'day']`
# In[12]:
# переименовываем столбец
df1 = df1.rename(columns={'date_of_month': 'day'})
df1.loc[:, 'date'] = \
pd.to_datetime(df1.loc[:, ['year', 'month', 'day']])
df1.head()
# Довольно часто информация о дате передается в формате [unix-timestamp](http://www.onlineconversion.com/unix_time.htm).
#
# В этом случае можно воспользоваться функцией `pd.Timestamp.fromtimestamp()`
# In[17]:
pd.Timestamp.fromtimestamp(1453766400)
# Давайте сделаем дату индексом в нашей таблице.
# In[18]:
df1 = df1.set_index('date')
df1.head()
# Это дает нам возможность выбирать строчки по нужным датам...
# In[19]:
df1.loc['1994-01-01', :]
# In[21]:
# df1.loc['1994-01-01':'1995-01-01', :]
# .. и не только, например
# In[22]:
# Аггрегация с нужной частотой
df_aggr = df1.resample(rule='AS')\
.sum()
B business day frequency
C custom business day frequency (experimental)
D calendar day frequency
W weekly frequency
M month end frequency
SM semi-month end frequency (15th and end of month)
BM business month end frequency
CBM custom business month end frequency
MS month start frequency
SMS semi-month start frequency (1st and 15th)
BMS business month start frequency
CBMS custom business month start frequency
Q quarter end frequency
BQ business quarter endfrequency
QS quarter start frequency
BQS business quarter start frequency
A year end frequency
BA business year end frequency
AS year start frequency
BAS business year start frequency
BH business hour frequency
H hourly frequency
T minutely frequency
S secondly frequency
L milliseonds
U microseconds
N nanoseconds
# In[24]:
df_aggr.head()
# In[25]:
# Визуализация
df1.births.plot(label=u'Исходный ряд')
# In[27]:
# Визуализация
df1.births.plot(label=u'Исходный ряд')
df1.births.rolling(window=14).mean().plot(label=u'Rolling Mean')
# **Задание**
# Преобразуйте дату в таблице df2 аналогично df1. Становится ясно, что периоды данных в этих файлах пересекаются.
#
# Необходимо проверить, что показатели рождаемости слабо отличаются между двумя файлами.
#
# Сравните показатели рождаемости на датах на общих датах
# In[31]:
# переименовываем столбец
df2 = df2.rename(columns={'date_of_month': 'day'})
df2.loc[:, 'date'] = \
pd.to_datetime(df2.loc[:, ['year', 'month', 'day']])
df2 = df2.set_index('date')
# In[32]:
df2.head()
# In[35]:
df_diff = \
df1.loc[:, ['births']].join(df2.loc[:, ['births']], how='inner', rsuffix='_2', lsuffix='_1')
# In[39]:
abs(df_diff.births_1 - df_diff.births_2).describe()
# **Задание**
# Теперь надо аккуратно объединить таблицы, так чтобы соблюсти целостность информации (то есть чтобы на одну дату было по одному наблюдению - из одной из таблиц или среднее по обеим)
#
# **HINT**
# `join`, `concat`
# In[ ]:
## Your code here
# **Задание**
# Найдите количество детей, рождающихся 6, 13 и 20 числа каждого месяца с учетом дня недели.
#
# Выделяется ли как-то пятница 13?
# In[ ]:
## Your code here
# ### Качество вина
# Загрузите [датасет](https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv) с информацией о характеристиках вина и его качестве.
# In[ ]:
## Your code here
# **Задание**
# * Что из себя представляет объект в этом наборе данных? Сколько их?
# * Какие признаки описывают объекты? Сколько их?
# * Какой признак является целевым?
# * Каковы их области значений?
# * Есть ли пропуски?
# In[ ]:
## Your code and answers here
# **Задание**
# Какие признаки больше всего влияют на целевую переменную?
# In[ ]:
## Your code here
# # Вспоминаем NumPy
# ## Линейная регрессия (для нас пока черный ящик)
# Загрузите [файл 1](https://www.dropbox.com/s/kg9px9v3xfysak9/tutorial_dataset.csv?dl=0) и [файл 2](https://www.dropbox.com/s/f87gm612o144emx/tutorial_dataset_2.csv?dl=0) в папку с тетрадкой. С помощью функции `loadtxt` в модуле `numpy` загрузите табличные данные одного из файлов. Присвойте y = D[:,0] а X = D[:, 1:].
#
# Сейчас мы воспользуемся одной магической формулой и построим модель линейной регрессии. Откуда эта формула берется мы узнаем на следующих занятиях.
#
# Модель линейной регрессии в матричном виде выглядит так: $\hat{y} = X\hat{\beta}$, где
#
# $$ \hat{\beta} = (X^\top X)^{-1} X^\top y $$
# Остатки модели рассчитываются как
# $$ \text{res} = y - \hat{y} $$
#
# Итак, еще раз:
#
# **Задание**
# 1. Загрузите данные
# 2. Оцените веса $\beta$ с помощью формулы
# 3. Постройте график, на котором по оси Y: остатки, а по оси X: $\hat{y}$
# In[41]:
# load data
D = np.loadtxt('./data/tutorial_dataset_2.csv',
skiprows=1,
delimiter=',')
# In[44]:
y = D[:, 0]
X = D[:, 1:]
# In[50]:
Beta = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
# In[52]:
Beta
# In[56]:
y_hat = X.dot(Beta)
res = y - y_hat
# In[57]:
plt.scatter(y_hat, res)
# # Попробуем что-то из sklearn
# ## Sentiment analysis
# В папке `/data/sentiment` лежат файлы, связанные с
# * imdb.com
# * amazon.com
# * yelp.com
#
# Формат файла:
# \t\n
#
#
# ### Task
# 1. Загрузите данные из файла
# 2. Обучите линейный классификатор (для нас пока черный ящик)
# 3. Попробуем проинтерпретировать результат
# 4. Как будем оценикать качество?
# In[60]:
imdb = pd.read_csv('./data/sentiment/imdb_labelled.txt', sep='\t', names=['text', 'label'])
# In[61]:
imdb.head()
# In[63]:
from sklearn.feature_extraction.text import CountVectorizer
# In[65]:
vect = CountVectorizer()
X = vect.fit_transform(imdb.text.values)
# In[67]:
imdb.shape
# In[66]:
X
# In[68]:
from sklearn.linear_model import LogisticRegression
# In[69]:
model = LogisticRegression()
# In[70]:
y = imdb.label.values
# In[71]:
model.fit(X, y)
# In[72]:
coef = model.coef_[0]
# In[75]:
words = vect.get_feature_names()
# In[76]:
weights = pd.Series(index=words, data=coef)
# In[78]:
weights.sort_values()
# In[ ]: