Физтех.Статистика
Скачать ipynb
Phystech@DataScience¶
Домашнее задание 12¶
Правила, прочитайте внимательно:
- Выполненную работу нужно отправить телеграм-боту
@miptstats_pds_bot
. Для начала работы с ботом каждый раз отправляйте/start
. Работы, присланные иным способом, не принимаются. - Дедлайн см. в боте. После дедлайна работы не принимаются кроме случаев наличия уважительной причины.
- Прислать нужно ноутбук в формате
ipynb
. - Выполнять задание необходимо полностью самостоятельно. При обнаружении списывания все участники списывания будут сдавать устный зачет.
- Решения, размещенные на каких-либо интернет-ресурсах, не принимаются. Кроме того, публикация решения в открытом доступе может быть приравнена к предоставлении возможности списать.
- Для выполнения задания используйте этот ноутбук в качестве основы, ничего не удаляя из него. Можно добавлять необходимое количество ячеек.
- Комментарии к решению пишите в markdown-ячейках.
- Выполнение задания (ход решения, выводы и пр.) должно быть осуществлено на русском языке.
- Если код будет не понятен проверяющему, оценка может быть снижена.
- Никакой код из данного задания при проверке запускаться не будет. Если код студента не выполнен, недописан и т.д., то он не оценивается.
- Код из рассказанных на занятиях ноутбуков можно использовать без ограничений.
Правила оформления теоретических задач:
- Решения необходимо прислать одним из следующих способов:
- фотографией в правильной ориентации, где все четко видно, а почерк разборчив,
- отправив ее как файл боту вместе с ноутбуком или
- вставив ее в ноутбук посредством
Edit -> Insert Image
(фото, вставленные ссылкой, не принимаются);
- в виде $\LaTeX$ в markdown-ячейках.
- фотографией в правильной ориентации, где все четко видно, а почерк разборчив,
- Решения не проверяются, если какое-то требование не выполнено. Особенно внимательно все проверьте в случае выбора второго пункта (вставки фото в ноутбук). Неправильно вставленные фотографии могут не передаться при отправке. Для проверки попробуйте переместить
ipynb
в другую папку и открыть его там. - В решениях поясняйте, чем вы пользуетесь, хотя бы кратко. Например, если пользуетесь независимостью, то достаточно подписи вида "X и Y незав."
- Решение, в котором есть только ответ, и отсутствуют вычисления, оценивается в 0 баллов.
Баллы за задание:
Легкая часть (достаточно на "хор"):
- Задача 1 — 40 баллов
- Задача 2 — 60 баллов
Сложная часть (необходимо на "отл"):
- Задача 3 — 20 баллов
- Задача 4 — 40 баллов
# Bot check
# HW_ID: phds_hw12
# Бот проверит этот ID и предупредит, если случайно сдать что-то не то.
# Status: not final
# Перед отправкой в финальном решении удали "not" в строчке выше.
# Так бот проверит, что ты отправляешь финальную версию, а не промежуточную.
# Никакие значения в этой ячейке не влияют на факт сдачи работы.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
Импорты из sklearn:
from sklearn.metrics import mean_squared_error, mean_absolute_error, mean_absolute_percentage_error
<...>
Задача 1¶
Реализуйте функции:
- скользящего среднего
- экспоненциального сглаживания
- двойного эскпоненциального сглаживания (метод Хольта)
Визуализируйте результаты работы функций.
0. Загрузка данных¶
Профиль физика¶
В этой задаче мы будем работать с данными по электропотреблению. Данные можете скачать с сайта.
file_path = <...> # путь до файла с данными
data = pd.read_csv(file_path, index_col=[0], parse_dates=[0])
data.head()
Мы будем работать с колонкой nat_demand
. Проверьте, есть ли в этом столбце пропуски. Если да - удалите эти строки.
<...>
Визуализируйте, как изменяется таргет с течением времени. Какие зависимости вы можете увидеть?
<...>
data = pd.read_csv('hrb_sample_1.csv')
data
Формат данных достаточно специфичен. Очистим нашу таблицу от ненужной информации.
data = pd.DataFrame(data.values, columns=data.loc[1])
data = data.drop(0)
data = data.drop(1)
data.tail()
Уберем лишние колонки.
data = data[['Time', 'HR (bpm)']]
Колонку Time
преобразуем к правильному типу данных и поставим вместо индексов.
data["Time"] = pd.to_datetime(data['Time'])
data = data.set_index('Time')
Посмотрим, в каком формате хранятся данные о сердцебиении.
type(data['HR (bpm)'][0])
Переведите значения HR (bpm)
к целым числам.
<...>
Визуализируйте, как изменяется таргет с течением времени. Какие зависимости вы можете увидеть?
<...>
1. Скользящее среднее¶
def moving_average(series:pd.Series, n:int)->pd.Series:
'''
series:pd.Series - исходные данные
n:int - величина скользящего окна
output:pd.Series - сглаженные данные
'''
<...>
return <...>
Нарисуйте на одном графике исходные данные и обработанные скользящим средним. Рассмотрите минимум два разных n
и обоснуйте свой выбор этих значений.
Замечание: при корректной реализации функции первые элементы превратятся в NaN, поэтому рисовать график нужно для series[n:]
<...>
2. Экспоненциальное сглаживание¶
def exponential_smoothing(series:pd.Series, alpha:float)->pd.Series:
'''
series:pd.Series - исходные данные
alpha:float - сглаживающий фактор
'''
<...>
return <...>
Нарисуйте на одном графике исходные данные и обработанные функцией экпоненциального сглаживания. Рассмотрите минимум два разных alpha
. Следите за аккуратностью графика.
<...>
3. Двойное экспоненциальное сглаживание (метод Хольта)¶
def double_exponential_smoothing(series, alpha:float, beta:float)->pd.Series:
'''
series:pd.Series - исходные данные
alpha:float - сглаживающий фактор
beta:float - сглаживающий фактор
'''
<...>
return <...>
Нарисуйте на одном графике исходные данные и обработанные функцией двойного экпоненциального сглаживания. Рассмотрите минимум три разных пары alpha
и beta
. Следите за аккуратностью графика.
<...>
Задача 2.¶
Продолжайте работать с выбранными данными. Разбейте их таким образом, чтобы в тесте остались последние 20% измерений.
<...>
1. Baseline¶
В любой задаче машинного обучения сначала полезно строить простые модели, так называемые baseline
. Сгенерируйте фичи из даты. Поясните свой выбор.
<...>
Ответ:
Обучите линейную регрессию с регуляризацией и случайный лес на ваших данных.
<...>
Визуализируйте полученные прогнозы.
<...>
Посчитайте метрики.
<...>
2. Рекурсивная стратегия¶
Обучите линейную регрессию с регуляризацией и случайный лес используя рекурсивную стратегию.
<...>
Визуализируйте полученные прогнозы.
<...>
Посчитайте метрики.
<...>
3. Временные сдвиги¶
Поработаем еще с признаками. На этот раз добавим сдвиги по времени. Таким образом модель сможет использовать информацию из прошлого, для составления прогноза на будущее. Добавьте новые признаки к вашим данным.
Обучите линейную регрессию с регуляризацией и случайный лес на обновленном датасете.
<...>
Визуализируйте полученные прогнозы.
<...>
Посчитайте метрики.
<...>
Сделайте выводы по задаче.
Вывод:
Задача 3.¶
Используя функции, реализованные в задаче 1, добавьте сглаживание в ваш датасет. Поясните выбор функции сглаживания.
<...>
Обучите линейную регрессию с регуляризацией и случайный лес на обновленном датасете.
<...>
Визуализируйте полученные прогнозы.
<...>
Посчитайте метрики.
<...>
Вывод:
Задача 4.¶
Вспомним, что при построении деревьев в задаче регрессии для каждого листа вычисляется среднее по всем обучающим объектам, которые попали в данный лист. Тем самым значение в листе лежит в пределах области значений таргета на обучении (не превосходит максимального, не меньше минимального). В связи с этим деревья не могут предсказывать значения за пределами этой области. Зависимости в задачах временных рядов не редко имеют некоторый тренд, например, значения на тестовой части временного ряда могут оказаться вне области значений обучающей части ряда. Это означает, что решающее дерево не сможет построить хороший прогноз временного ряда. Проблема также распространяется на случайный лес.
В данной задаче вы реализуете другой способ прогнозирования временных рядов, который может решить эту проблему.
Исследуйте Ridge
, Lasso
и ElasticNet
с различными параметрами на данных из предыдущей задачи. Подберите лучшую линейную модель.
<...>
y_pred = <...>
Посчитайте остатки прогноза вашей модели на тренировочной выборке. Остатком является разность истинного значния и спрогнозированного.
<...>
Теперь сделаем необычный ход — научим случайный лес предсказывать ошибку линейной модели. Для этого за Х
возьмем исходные признаки, а за y
- вектор разностей, который вы посчитали в ячейке выше.
Предскажем ошибку линейной модели на тестовой выборке. Получим вектор предсказанных ошибок.
errors_pred = <...>
Теперь сложим прогноз линейной модели для тестовой выборки и прогноз ошибок случайного леса для этой же тестовой выборки. Посчитайте метрики для полученного вектора.
<...>
Визуализируйте новый прогноз.
<...>
Сделайте вывод.
Вывод:<...>
Процедура, которую вы сейчас провели, называется бустинг. В этой модели последовательно объединяются деревья, которые учатся предсказывать ошибку предыдущего дерева. Благодаря такой схеме модели удается достичь высокого качества. Подробнее с бустингом мы ознакомимся в следующем семестре.