Машинное обучение: с чего начать, или как построить первую модель
Никогда не задумывались, что влияет на цену недвижимости? Рассказываем, как построили первую модель машинного обучения и проанализировали ее качество.
В качестве первой задачи для машинного обучения возьмем что-то понятное и простое, например прогноз стоимости жилья. Готовый датасет можно найти на сайте kaggle. На первых шагах обучения не стоит брать датасеты с большим количеством переменных, например «House Prices: Advanced Regression Techniques» состоит из 80 переменных и advanced regression, остановимся на «House Sales in King County, USA» с 21 параметром.
Скачиваем данные и анализируем предоставленное описание. В наличии: дата, цена, количество спален, ванных комнат, общая и жилая площадь, этажность, оценка вида, вид на море, оценка общего состояния, грейд (оценка строительства и дизайна), площадь над и под уровнем земли, год постройки, год последнего ремонта, код зоны, координаты (долгота и широта), данные о площади домов 15 соседей.
Итак, мы выбрали задачу и готовы приступить к ее решению. Решение будет включать два этапа: анализ данных и построение моделей.
1. Работа с данными
Сделаем отступление и отдельно отметим важность анализа данных. В настоящий момент все более-менее популярные алгоритмы уже написаны в виде библиотек и непосредственное построение модели сводится к нескольким строкам кода, например, k-ближайших соседей из sklearn в python:
Всего четыре строчки кода для получения результата. Так в чем же сложность? Сложность заключается в получении того самого X_train — данных, которые подаются на вход модели. Известный принцип «мусор на входе» = «мусор на выходе» (англ. garbage in — garbage out (GIGO)) в моделировании работает более чем на 100%, и именно от работы с данными во многом будет зависеть качество полученного решения задачи машинного обучения.
А теперь в бой!
Для анализа данных мы будем использовать pandas, для понимания и оценки «на глаз» используем простые графики из seaborn.
Импортируем библиотеки, читаем данные, выведем несколько записей из массива данных, посмотрим на типы данных и пропуски в них.
Код и Out
Массив данных состоит из 21 613 записей без пропусков в данных и содержит только одно текстовое поле date.
С каждым признаком поработаем подробнее и начнем с самого простого — откинем id (не несет полезной информации), zipcode (код зоны, где расположен дом) и координаты (lat & long), так как мы только знакомимся c machine learning, а корректное преобразование географических данных слишком специфично для начинающего специалиста.
Теперь посмотрим на дату объявления. Формат даты задан yyyymmddt000000, в целом ее тоже можно было бы удалить из датасета, но у нас есть поля год постройки (yr_built) и год последнего ремонта (yr_renovated), которые заданы в в формате года (YYYY), что не очень информативно.
Оперируя датой объявления, можно преобразовать год в возраст вычитанием (год объявления — год постройки / год ремонта). Отметим по части домов год ремонта стоит 0, и, предположив, что это означает отсутствие ремонта с постройки, заменим нули в году ремонта на год постройки, предварительно убедившись, что в данных отсутствуют некорректные записи, где год ремонта меньше года постройки:
Следующим параметром проанализируем цену и воспользуемся для этого «Ящиком с усами» (Box plot). Ящик с усами — простой и удобный график, показывающий одномерное распределение вероятностей, или, проще говоря, концентрацию данных.
Отрисовывает медиану (линия в центре), верхний и нижний квартили (стороны ящика), края статистически значимой выборки («усы») и выбросы (точки за «усами»). Легко понять по картинке на нормальном распределении (справа).
График позволяет быстро оценить где располагается большая часть данных (50% находятся внутри ящика), их симметричность (смещение медианы к одной из сторон ящика и/или длина «усов») и степень разброса — дисперсию (размеры ящика, размеры усов и количество точек-выбросов).
Можно построить распределение только этого признака по всему массиву, но информативнее будет использовать две оси, например цену и количество спален, что в свою очередь также покажет наличие связи между признаками:
Out price & bedrooms:
Из графика сразу видно наличие экстремальных значений price и bedrooms (только представьте дом с 33 спальнями! J). Наличие таких значений (иначе называемых как выбросы) в целевом признаке price часто приводит к переобучению модели, так именно они будут давать большую ошибку, которую алгоритмы стараются минимизировать.
Из графика видно, что большая часть (если посчитать — 93,22%) лежит в диапазоне 0-1млн, а свыше 2 млн — всего 198 значений (0,92%). От 1% датасета можно избавиться практически безболезненно, поэтому вызвав простой просмотр 217 записей предварительно отсортировав по цене, увидим искомую отметку price в 1 965 000 и удалим все, что выше этой цены.
Подумаем немного над признаком bedrooms. Мы видим 13 домов с bedrooms = 0, а также странную запись о доме с 33 bedrooms. Поступим также как и с price, удалив нули из bedroms (а заодно и bathrooms):
Касательно дома с 33 спальнями — учитывая цену, можно предположить что это опечатка и спален на самом деле 3. Сравним жилую площадь этого дома (1620) со средней жилой площадью домов с 3 спальнями (1798,2), что ж, вероятно, наша догадка верна, поэтому просто изменим это значение на 3 и еще раз построим предыдущий box plot:
Что ж, значительно лучше. Аналогично bedrooms посмотрим и на bathrooms. Нулевые значения мы удалили, другие экстремальные значения в поле отсутствуют:
В полях sqft_living, floors, waterfront, view, condition, grade, sqft_living15 также все значения более-менее реальны, их трогать не будем:
А вот с sqft_lot и sqft_lot15 нужно что-то придумать, и из-за больших значений вполне подойдет логарифмирование:
sqft_lot до и после:
sqft_above и sqft_basement — составные части sqft_living, поэтому также трогать их не будем.
На этом с предварительным анализом мы закончим и посмотрим на тепловую карту корреляций:
Изучив карту корреляций видим, что иногда признаки сильно коррелированы между собой, поэтому удалим часть признаков с высокой корреляцией: sqft_lot15 (оставим sqft_lot), yr_built (оставим yr_renovated), sqft_above (sqft_living)
На этом закончим работу с данными и перейдем к созданию модели.
2. Моделирование
В данной части мы построим две модели: линейную регрессию и дерево решений.
Все необходимые нам модели содержаться в библиотеке sklearn.
Для начала отделим целевую переменную от остальных данных для обучения, а также разделим выборки на обучающую (70%) и тестовую (30%, на которой мы проверим как работает модель):
Также из sklearn для оценки модели загрузим три метрики — mean_absolute_error (средняя абсолютная ошибка), mean_squared_error (Среднеквадратическое отклонение), r2_score (коэффициент детерминации):
Начнем с линейной регрессии:
MAE: 124477.452
√MSE 175205.645
R2_score: 0.627
Дерево решений:
MAE: 151734.906
√MSE 220856.721
R2_score: 0.407
Исходя из метрик можно сделать вывод о том, что Линейная регрессия показала лучший результат, поэтому логичнее выбрать ее. Однако мы не задавались вопросами, из чего состоит ошибка модели, не является ли модель переобученной.
Вполне вероятно, что к ухудшению результата DecisionTreeRegressor приводит именно переобучение, так как мы даже не ограничивали глубину дерева в параметрах модели. Можем легко проверить это перебирая глубину деревьев в коротком цикле:
Очевидно, что лучший показатель при max_depth=7, и, посмотрев, на метрики (MAE: 124861.441, √MSE 175322.737, R2_score: 0.626) становиться понятно, что модель с таким ограничением аналогична линейной регрессии по качеству.
Также мы можем попробовать оценить какие признаки оказались наиболее важны для модели для прогноза стоимости:
Исходя из графика видно, что на стоимость больше всего влияет grade — общая субъективная оценка дома риелторской компанией (что, кстати, говорит о компетентности оценки), на втором месте — площадь дома, а на третьем — год последнего ремонта. Показатели количества спален, ванных комнат, этажей же модель посчитала незначимыми для прогноза.
Для лучшего понимания результатов, посчитаем среднюю ошибку в процентах — по линейной регрессии средняя ошибка 27,5%, то есть модель ошибается чуть больше, чем на четверть при прогнозе стоимости дома, что довольно много.
Можно ли улучшить результаты? Да, несомненно, на текущем этапе мы получили только базовое решение — некую отправную точку для сравнения лучше или хуже будут модели, которые мы можем создать более сложными методами или применяя более сложную обработку данных.
Мы только чуть-чуть затронули вопрос переобучения и совсем не прикасались к тому, из чего состоит ошибка модели и многим другим аспектам создания модели. Как правило, для ответов на эти вопросы и нахождения оптимального решения используют разнообразные методы валидации моделей, но об этом мы напишем в следующих статьях.
А не могли бы вы в статье указать ссылки на базы данных?
Кирилл, добрый день! Спасибо за совет, добавим ссылки в статьи
Статья интересная, спасибо, но что касается предиктов - мне кажется, эту часть лучше было бы вообще не описывать, чем описывать действия, которые дают предикт с ошибкой больше 100к.
мы напишем в следующих статях
как найти эти статьи???
Добрый день! Все материалы размещены в сообществе NTA https://vc.ru/newtechaudit