Этот Jupyter Notebook содержит вспомогательные указания для выполнения семинарских и домашних заданий. В течение курса мы будем преимущественно работать в подобных "тетрадках", но может быть иногда будем переключаться на другие среды\средства.
(Я использую Python версии 2.x.x, а не 3.x.x)
Самый простой и надежный способ - воспользоваться готовым дистрибутивом Anaconda, включающий в себе практически все необходимые модули и утилиты, которые нам понадобятся - IPython, NumPy, SciPy, Matplotlib и Scikit-Learn. Просто следуйте указаниям установщика для вашей ОС.
Рекомендую ознакомиться с этим постом - там приводятся различные интересные возможности "тетрадок" о которых вы возможно не знали.
Пишите, ради бога. В нашем случае разница будет минимальна, поэтому код можно легко перевести из одной версии в другую.
Данный курс должен дать вам:
Фундамент будет заложен. А дальше нужна практика и ваша собственная мотивация.
Что желательно уметь делать, будучи DS:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = (16,8)
!ls
US_births_1994-2003_CDC_NCHS.csv seminar3.ipynb US_births_2000-2014_SSA.csv setting_envrmt_old.ipynb Untitled.ipynb sol da_with_matrices.ipynb sol~ hw1_old.ipynb temp.txt intro.ipynb tutorial_dataset.csv seminar1_lns_old.ipynb tutorial_dataset_2.csv seminar2.ipynb
df1 = pd.read_csv('US_births_1994-2003_CDC_NCHS.csv')
df2 = pd.read_csv('US_births_2000-2014_SSA.csv')
df1.tail()
year | month | date_of_month | day_of_week | births | |
---|---|---|---|---|---|
3647 | 2003 | 12 | 27 | 6 | 8646 |
3648 | 2003 | 12 | 28 | 7 | 7645 |
3649 | 2003 | 12 | 29 | 1 | 12823 |
3650 | 2003 | 12 | 30 | 2 | 14438 |
3651 | 2003 | 12 | 31 | 3 | 12374 |
df2.head()
year | month | date_of_month | day_of_week | births | |
---|---|---|---|---|---|
0 | 2000 | 1 | 1 | 6 | 9083 |
1 | 2000 | 1 | 2 | 7 | 8006 |
2 | 2000 | 1 | 3 | 1 | 11363 |
3 | 2000 | 1 | 4 | 2 | 13032 |
4 | 2000 | 1 | 5 | 3 | 12558 |
Чем они отличаются? Соедините 2 таблицы, так, чтобы соблюсти целостность информации.
# 1) Проверьте, что данные за общий период почти
# не отличаются
# 2) Объедините таблицы, чтобы они охватывали период
# 1994-2014
df1 = df1.rename(columns={'date_of_month': 'day'})
df1.loc[:, 'date'] = \
pd.to_datetime(df1.loc[:, ['year', 'month', 'day']])
df1.head()
year | month | day | day_of_week | births | date | |
---|---|---|---|---|---|---|
0 | 1994 | 1 | 1 | 6 | 8096 | 1994-01-01 |
1 | 1994 | 1 | 2 | 7 | 7772 | 1994-01-02 |
2 | 1994 | 1 | 3 | 1 | 10142 | 1994-01-03 |
3 | 1994 | 1 | 4 | 2 | 11248 | 1994-01-04 |
4 | 1994 | 1 | 5 | 3 | 11053 | 1994-01-05 |
df2 = df2.rename(columns={'date_of_month': 'day'})
df2.loc[:, 'date'] = \
pd.to_datetime(df2.loc[:, ['year', 'month', 'day']])
df2.head()
year | month | day | day_of_week | births | date | |
---|---|---|---|---|---|---|
0 | 2000 | 1 | 1 | 6 | 9083 | 2000-01-01 |
1 | 2000 | 1 | 2 | 7 | 8006 | 2000-01-02 |
2 | 2000 | 1 | 3 | 1 | 11363 | 2000-01-03 |
3 | 2000 | 1 | 4 | 2 | 13032 | 2000-01-04 |
4 | 2000 | 1 | 5 | 3 | 12558 | 2000-01-05 |
df1 = df1.set_index('date')
df2 = df2.set_index('date')
df1.head()
year | month | day | day_of_week | births | |
---|---|---|---|---|---|
date | |||||
1994-01-01 | 1994 | 1 | 1 | 6 | 8096 |
1994-01-02 | 1994 | 1 | 2 | 7 | 7772 |
1994-01-03 | 1994 | 1 | 3 | 1 | 10142 |
1994-01-04 | 1994 | 1 | 4 | 2 | 11248 |
1994-01-05 | 1994 | 1 | 5 | 3 | 11053 |
df2.head()
year | month | day | day_of_week | births | |
---|---|---|---|---|---|
date | |||||
2000-01-01 | 2000 | 1 | 1 | 6 | 9083 |
2000-01-02 | 2000 | 1 | 2 | 7 | 8006 |
2000-01-03 | 2000 | 1 | 3 | 1 | 11363 |
2000-01-04 | 2000 | 1 | 4 | 2 | 13032 |
2000-01-05 | 2000 | 1 | 5 | 3 | 12558 |
result = df1.join(df2, how='inner',
lsuffix='_df1', rsuffix='_df2')
result.tail()
year_df1 | month_df1 | day_df1 | day_of_week_df1 | births_df1 | year_df2 | month_df2 | day_df2 | day_of_week_df2 | births_df2 | |
---|---|---|---|---|---|---|---|---|---|---|
date | ||||||||||
2003-12-27 | 2003 | 12 | 27 | 6 | 8646 | 2003 | 12 | 27 | 6 | 8785 |
2003-12-28 | 2003 | 12 | 28 | 7 | 7645 | 2003 | 12 | 28 | 7 | 7763 |
2003-12-29 | 2003 | 12 | 29 | 1 | 12823 | 2003 | 12 | 29 | 1 | 13125 |
2003-12-30 | 2003 | 12 | 30 | 2 | 14438 | 2003 | 12 | 30 | 2 | 14700 |
2003-12-31 | 2003 | 12 | 31 | 3 | 12374 | 2003 | 12 | 31 | 3 | 12540 |
# Сравним рождаемости
result.loc[:, ['births_df1', 'births_df2']]
(result.births_df1 - result.births_df2).mean()
-223.48459958932239
(result.births_df1 - result.births_df2).describe()
count 1461.000000 mean -223.484600 std 68.774771 min -438.000000 25% -271.000000 50% -231.000000 75% -170.000000 max -60.000000 dtype: float64
df3 = df1.append(df2.loc['2004-01-01':, :])
# Проверим, что даты не повторяются
df3.index.value_counts().head()
# Даты уникальны!
2007-09-10 1 2000-09-26 1 2000-09-28 1 1997-12-03 1 1996-08-22 1 2005-09-22 1 2009-11-14 1 2002-06-28 1 2003-01-25 1 1995-10-11 1 1999-03-15 1 2001-06-26 1 2004-11-28 1 2008-05-02 1 1998-07-02 1 2005-12-17 1 2003-06-29 1 1997-05-14 1 1998-12-04 1 2009-12-01 1 2013-11-21 1 2007-08-20 1 2000-01-08 1 2014-07-28 1 1995-06-15 1 2014-12-25 1 2009-04-28 1 1995-05-06 1 1996-07-24 1 2014-06-26 1 .. 1998-01-03 1 1994-08-01 1 2000-10-01 1 2005-07-24 1 2007-11-01 1 1997-08-30 1 1998-09-13 1 1996-10-30 1 2003-11-06 1 1994-07-19 1 1995-01-06 1 1998-06-10 1 2001-11-12 1 2004-02-24 1 2007-07-29 1 2008-09-18 1 2012-02-21 1 1996-06-05 1 1994-02-18 1 2010-09-12 1 2013-08-15 1 2006-10-18 1 2001-05-25 1 2011-05-13 1 2014-04-27 1 2012-10-24 1 2003-08-30 1 2009-11-21 1 2008-03-31 1 2006-03-22 1 Name: date, dtype: int64
Найдите количество детей, рождающихся 6, 13 и 20 числа каждого месяца с учетом дня недели.
Выделяется ли как-то пятница 13?
# Сделаем таблицу для 6 числа
idx = df3.loc[:, 'day'] == 6
b6 = df3.loc[idx, :].groupby('day_of_week').births.mean()
# И для всех остальных
idx = df3.loc[:, 'day'] == 13
b13 = df3.loc[idx, :].groupby('day_of_week').births.mean()
idx = df3.loc[:, 'day'] == 20
b20 = df3.loc[idx, :].groupby('day_of_week').births.mean()
b6-b20
day_of_week 1 -597.400000 2 -448.805556 3 -79.028571 4 -167.131579 5 -237.342857 6 -71.361111 7 -19.189189 Name: births, dtype: float64
b20-b13
day_of_week 1 520.142857 2 491.722222 3 403.742857 4 507.052632 5 911.342857 6 93.805556 7 81.891892 Name: births, dtype: float64
Загрузите датасет с информацией о характеристиках вина и его качестве.
Какие признаки больше всего влияют на целевую переменную?
Создайте новый столбец quality_cat
, которая будет иметь значение "good"
если quality > 5
и "bad"
- иначе.
Нарисуйте гистрограммы признака alcohol в группах с quality_cat == "good"
и quality_cat == "bad"
.
Можете ли вы придумать правило для классификации вина на хорошее и плохое по рисунку выше? Пусть это будет нашей первой моделью)
Напишите функцию brute_clf_train()
которая бы перебирала пороговое значение по признаку alcohol
и находило бы "оптимальное" (кстати, что значит оптимальное?)
Напишите функцию brute_clf_predict()
которая бы по значению признака alcohol
и найденному выше порогу говорила какое качество у вина.
А заодно выводила бы количество "ошибок" на текущем наборе данных
Проверим, как обобщается наша модель на другие данные.
Загрузите файл 1 и файл 2 в папку с тетрадкой. С помощью функции loadtxt
в модуле numpy
загрузите табличные данные одного из файлов. Присвойте y = D[:,0] а X = D[:, 1:].
Сейчас мы воспользуемся одной магической формулой и построим модель линейной регрессии. Откуда эта формула берется мы узнаем на следующих занятиях.
Модель линейной регрессии в матричном виде выглядит так: $\hat{y} = X\hat{\beta}$, где
$$ \hat{\beta} = (X^T X)^{-1} X^T y $$Остатки модели рассчитываются как $$ \text{res} = y - \hat{y} $$
Итак, еще раз:
# load data
D = np.loadtxt('tutorial_dataset_1.csv',
skiprows=1,
delimiter=',')
# Write your code here
#
#
#