[МУЗЫКА]
[МУЗЫКА] В
данном видео мы рассмотрим задачу восстановления регрессии.
Это открытый свободный датасет, достаточно популярный — это
сведения о стоимости на жилье в районе Бостон Масс, собственно, в городе Бостон.
Это достаточно старые данные, предоставленные где-то в 80-х годах.
Подробное описание датасета и отдельных его признаков можно найти по ссылке.
Импортируем некоторые, уже знакомые вам модули, и считаем наш датасет.
Он представлен уже в формате tsv, подготовленный.
И отобразим первые 10 колонок.
Как вы видите, наши объекты описаны некоторым количеством признаков,
а целевым является признак MEDV — median value,
средняя цена дома, в тысячах долларах.
Вы можете заметить, объекты представлены некоторыми признаками.
Это различные признаки,
описывающие характеристики района: уровень криминальной опасности,
средний возраст жильцов и некоторые признаки, отвечающие за экологию.
Давайте с вами обратимся к одному из очень важных
инструментов в понимании данных — к визуализации и к библиотеке Seaborn.
С помощью Seaborn можно вот так вот, буквально в одну строчку,
нарисовать специальный график
— график распределения величин,
причем соответственно по x и по y у нас различные величины,
а на пересечении стоит график совместных распределений,
а, соответственно, на диагонали у нас представлены гистограммы.
Мы выбрали некоторый поднабор наших величин,
потому что сам датасет достаточно большой, а этот график, а этот график,
соответственно, увеличивается квадратично, и он просто бы не поместился.
Наша целевая переменная — median value, она крайняя.
Как вы видите, некоторые переменные имеют весьма яркую выраженную линейную
зависимость от переменной median value.
Так, например, переменная RM — если я правильно помню,
это количество комнат в доме.
Очевидно, что количество комнат в доме прямым образом влияет на цену дома.
Или, скажем, переменная LSTAT.
Давайте посмотрим, так ли это.
Обучим некоторую простенькую регрессию от одной переменной к нашей
целевой и нарисуем ее красным.
На оси x отложим ту самую переменную,
одну из трех, которых мы выбрали: PTRATIO (рейтинг учитель-ученик),
LSTAT (процент представителей рабочего класса) и RM (количество комнат).
На оси y, соответственно, будет наша целевая переменная.
Таким вот простеньким циклом и использованием библиотеки Mathplotlib мы
получаем следующий график.
Как вы видите, наиболее явные зависимости,
даже на глаз — от переменных LSTAT и RM.
Рейтинг учитель-ученик влияет на цену дома в меньшей степени.
Давайте же попробуем собрать, действительно, серьезную модель.
Для этого сначала разделим уже знакомым вам способом нашу выборку на train test.
Здесь мы используем параметр test_size, который отвечает за размер тестовой
выборки, в случае когда мы передаем ему double, меньше 1, то это процент,
то есть 33 %, одна треть, у нас пойдет в тестовую выборку, а две трети — в train.
И random_state, random_state — это случайное ядро,
оно нужно для воспроизводимости результатов.
Разбиваем.
Обучаем модель SGD-регрессор — линейную регрессию,
основанную на стохастическом градиентном спуске.
Обучаем ее и просим предсказать наши значения.
В качестве метрики будем использовать mean_absolute_error — среднюю ошибку.
Как вы видите, ошибка достаточно велика.
Если вернуться к нашим данным, то вы помните примерный порядок цены дома — 20,
30, 40 тысяч долларов, — то это число все-таки несопоставимо.
Почему же так вышло?
Давайте посмотрим на конкретные значения нашей целевой переменной.
Да, действительно, в среднем наши значения в пределах сотни, а те предсказания,
которые выдает нам модель, имеют примерно 13–14 знак после запятой.
Почему же так вышло?
В уроке, посвященному градиентному бустингу, вы узнаете, что модели,
основанные на градиентном бустинге, крайне сильно зависят от шкалирования,
то есть от размерности величин, которые подаются им на вход.
Если опять же вернуться к нашей табличке, то вы увидите,
что наши величины крайне разноразмерные.
Так, например, возраст человека измеряется годами,
а показатель краем очевидно меньше 1.
Понятное дело,
что при попытке найти локальный минимум наша модель крайне серьезно ошибается.
Решение этой проблемы тоже достаточно простое.
Мы можем воспользоваться скейлингом,
то есть нормировать наши признаки.
Для этого в модуле sklearn.preprocessing имеет инструмент StandardScaler,
обладающий функционалом трансформера.
Мы просто зафитим в него нашу трейновую выборку и преобразуем трейный тест.
И на новых масштабированных данных уже обучим линейную регрессию.
Как вы видите, порядок несколько изменился,
теперь мы ошибаемся всего на 3.5 тысячи долларов, что чуть более приемлемо.
И в сравнении с реальными порядками цен на дома, вы видите,
что наша ошибка не настолько критична.
Однако в действительности насколько это плохо, хорошо, чем на это грозит?
3.5 тысячи долларов — мало или много?
Можем попробовать оценить это с помощью некоторого механизма,
некоторой визуализации — так называемым residual plots.
Как это делается?
Мы рисуем график, причем по оси y мы откладываем те цены,
которые предсказал наш алгоритм, а по оси x — те цены,
которые были заложены в обучающую выборку, те, которые мы пытались угадать.
Естественно, что для идеального регрессора этот график будет диагональным,
то есть стремится к диагональной прямой.
Действительно, наш график близок к диагональному.
Посмотрим, что еще мы сможем сделать с этой моделью.
Соберем pipeline — действительно, мы используем сначала scaling,
а потом регрессор, а вызывать из каждый раз последовательно неудобно.
Для этих целей у sklearn есть распределенный механизм,
он называется pipeline.
Pipe — это труба, соответственно, pipeline — это некоторая труба,
через которую проходят наши данные.
Мы указываем набор шагов, соответственно, scaler и регрессор.
И pipeline можно фитить точно так же, как обычный estimator, только при этом
наши данные сначала прогоняются через scaler, а потом через регрессор.
Обучим его и посчитаем нашу метрику.
Да, действительно, наша ошибка не изменилась,
мы обучили ровно ту же самую модель.
Однако при всем при этом помимо тех параметров, которые есть непосредственно в
нашей модели, мы можем увидеть, что есть также [НЕРАЗБОРЧИВО] и метапараметры —
параметры, которые не обучаются в процессе моделей, которые являются данными свыше,
заданными нами, а в данном случае заданные дефолтными значениями.
Давайте посмотрим, сможем ли мы как-нибудь покачать наши гиперпараметры и
попытаться что-то от этого выиграть.
В действительности, sklearn предоставляет некоторый механизм,
позволяющий нам обучать еще и гиперпараметры.
Давайте зададим некоторый словарь.
В качестве ключа будем использовать следующую конструкцию.
Первое слово — это название нашего шага в рамках pipeline, нижнее подчеркивание,
название конкретного параметра.
А также некоторый список возможных принимаемых значений.
На основе этих списков генерируется многомерная сетка,
GridSearchCV — это некоторый механизм, который берет нашу сетку, нашу метрику,
которую мы ему подаем, и наш pipeline, и проходится по этой сетке,
и говорит, в какой точке с какими метапараметрами наш pipeline работает
лучше всего с точкой зрения той метрики, которую мы ему передали.
Кроме того, я указываю,
что сравнивать необходимо с помощью кросс-валидации на четыре фолда.
Давайте создадим наш GridSearchCV и обучим его.
Это может занять некоторое время.
Засечем его с помощью встроенной функции time [НЕРАЗБОРЧИВО].
Да, действительно, это заняло целых две секунды.
Посмотрим, насколько улучшилась наша ошибка.
Да, наша ошибка стала несколько меньше — мы стали ошибаться на 300,
300 долларов, чуть менее, чем на 300 долларов.
И нарисуем наш residual plot.
Сходу сложно сказать, изменился ли он.
Давайте нарисуем два графика, два residual plot: один — для
нашего необученного pipeline, а второй — для нашего pipeline с
подобранными метапараметрами, причем второй обозначен красным цветом.
И если присмотреться, можно заметить,
что каждая из точек в среднем сместилась немного в сторону диагонали.
Однако я бы не сказал,
что это является качественным прорывом или качественным скачком.
Зачастую в задачах анализа данных некоторые данные могут быть лишними,
некоторые признаки могут даже мешать работе нашего алгоритма.
Зачастую нам могут мешать признаки, которые линейно зависимы друг от друга.
Давайте попробуем степень линейной зависимости с помощью
коэффициента корреляции Пирсона.
Воспользуемся для этого встроенной в этот фрейм функцией corr и передадим ей
значение параметра method = "pearson", а также нарисуем некоторую матрицу.
Это тепловая карта, которая позволяет нам наглядно оценить,
насколько зависимы некоторые из наших переменных.
Да, действительно, некоторые переменные достаточно сильно зависят друг от друга.
Например, переменные RAD и TAX, NOX и INDUS.
Давайте удалим некоторые из этих переменных, например переменную AGE,
которая достаточно сильно антикоррелирует с переменной DIS, и переменную INDUS,
которая достаточно сильно перекоррелирует с переменной с переменной NOX.
Посмотрим, улучшит ли это работу нашего алгоритма.
Да, действительно, совсем немного, но качество нашей работы изменилось,
однако опять же это не представляет качественный скачок.
О чем, в принципе, и говорит и residual plot.
То есть, действительно, по сравнению с предыдущей,
наша модель не сильно изменилась.
Точки всего лишь немного приблизились к диагональной.
Можно ли добиться качественного скачка на этих данных?
Зачастую ошибкой оказывается сам выбор модели.
Давайте попробуем какую-нибудь другую, например случайный лес.
И да, действительно, случайный лес показывает себя намного
лучше — его ошибка значительно меньше, и что самое важно,
заметьте: residual plot имеет совсем другой вид.
[БЕЗ_ЗВУКА]