#!/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[ ]: