🤖 Введение в машинное обучение: решаем Titanic на платформе Kaggle

Знакомим читателей с основами Machine Learnng и платформой Kaggle, а также пробуем решить учебный датасет Titanic.

Что такое Kaggle?

Kaggle – площадка, объединяющая соревновательную систему по исследованию данных, образовательный ресурс по искусственному интеллекту и машинному обучению, а также соцсеть специалистов в указанных областях.

Перед тем, как начать работать, необходимо зарегистрироваться на сайте. Заходим по ссылке, находим кнопку Register и заполняем поля. Уверен, что вы сами с этим отлично справитесь. После регистрации, подтверждения и логина попадаем на главную страницу ресурса.

Интерфейс Kaggle

Слева в столбце мы видим разделы:

  • Home – новостная лента, в которую попадают публикации, которые могут вас заинтересовать. Чем выше активность пользователя на сайте, тем точнее рекомендации.
  • Competitions – соревнования в области анализа данных. Здесь же находятся учебные соревнования, которые помечены словом Knowledge.
  • Datasets – различные наборы данных, с которыми можно поиграться. Также можно выкладывать собственные датасеты.
  • Code – раздел, в котором можно создать Jupyter Notebook или посмотреть чужой.
  • Discussions – местный аналог форумов.
  • Courses – учебные курсы. Довольно приличный объем и приемлемое качество. Раскрыты основные базовые разделы ML.

Отвлечемся пока от Kaggle и поговорим о машинном обучении, а также о решаемых с его помощью задачах.

Теоретический минимум о Machine Learning

Машинное обучение – набор математических, статистических и вычислительных методов, с помощью которых возможно решить задачу путем поиска закономерностей в представленных данных.

Существует огромное количество методов машинного обучения. Здесь я покажу всего несколько самых базовых, а остальные вы сможете найти самостоятельно, пройдя по рекомендованным ссылкам в конце.

Все методы ML можно разделить на несколько крупных групп:

  • Обучение с учителем (от англ. Supervised learning) – алгоритмы из этой группы обучаются с помощью заранее подготовленных данных, которые содержат как наборы входных исследуемых признаков, так и “ответы” на эти наборы. “Ответом” является выходное значение, которое должен выдать алгоритм в результате своей работы, т.е. алгоритм “обучается”. К этой группе, например, можно отнести задачи классификации и регрессии.
  • Обучение без учителя (от англ. Unsupervised learning) – группа алгоритмов, в которых система спонтанно обучается на входных данных без вмешательства извне. К этой группе можно отнести задачи кластеризации, понижения размерности.
  • Обучение с подкреплением (от англ. Reinforcement learning) – группа алгоритмов, в которых система обучается с помощью взаимодействия со средой, в которой она находится. Подробнее можно ознакомиться хотя бы в вики. В моей статье алгоритмы этой группы не рассматриваются.

Задачи машинного обучения

Классификация

Вероятно, это самая популярная задача машинного обучения. Ее суть состоит в присвоении какому-то набору признаков (т.е. свойств объекта) какому-то классу. Например, стоит задача автоматической модерации токсичных комментариев на сайте. Алгоритм получает на вход текст комментария, а на выходе присваивает ему метку: токсичный или нетоксичный. Это пример бинарной классификации. К этому же типу классификации можно отнести задачу выявления сердечно-сосудистых проблем по анализам человека, определение спама в письмах и т.п. Второй тип классификации – множественная (многоклассовая). В ней классов больше двух. Примером может служить классификация жанра книги.

Для демонстрации посмотрим графической решение задачи бинарной классификации. Алгоритм разделяет пространство признаков на две группы.

Задача классификации

Для решения задачи обычно используются следующие алгоритмы: логистическая регрессия, KNN, SVM, деревья решений.

Регрессия

Задача регрессии – предсказание (прогнозирование) целевого признака по входным параметрам. Например, предсказание загруженности дороги в зависимости от времени суток, дня недели, погоды, предсказание цены квартиры от количества комнат, этажа, района. Предсказание времени на путь из пункта А в пункт Б в зависимости от пробок и т.п. Т.е. задача регрессии это задача получения неизвестного числа по известным параметрам.

Посмотрим на рисунок. По ряду известных значений y(x) была предсказана кривая – линия регрессии. Ее можно продлить, чтобы предсказывать значения y для неизвестных x.

Задача регрессии

Для решения задачи применяются следующие алгоритмы и методы: линейная и полиномиальная регрессии, KNN, деревья решений.

Кластеризация

Задача кластеризации состоит в разделении заданной выборки объектов таким образом, чтобы похожие объекты попали в один кластер, а кластеры сильно бы различались между собой. Кластеризацию применяют для анализа и поиска признаков по которым можно объединить объекты, сжатия данных и поиска новизны (что не входит ни в один кластер).

Возникает логичный вопрос: а чем различаются классификация и кластеризация, ведь они решают похожие задачи? При классификации есть набор предопределенных классов, которым обучается алгоритм на наборе примеров. Далее алгоритм предсказывает, к какому классу принадлежит новый объект. При кластеризации используется алгоритм, который пытается сгруппировать набор объектов и определить, существует ли какая-либо взаимосвязь между объектами, т.е. машина учится сама.

Графическим примером кластеризации может быть следующая иллюстрация.

Задача кластеризации

Для решения задачи применяются следующие алгоритмы и методы: K-Means, DBSCAN.

Метрики качества регрессии

Начнем с регрессии. При оценке качества работают с таблицей, содержащей два столбца (помимо индекса): правильные значения и предсказанные. Для простоты рассмотрим четыре строки, и пусть объектами будет количество килограмм картошки для сети ресторанов. Для простоты расчетов возьмем кратные десяти значения.

Номер Значение из выборки (сколько в реальности потребовалось кг картошки) Предсказанное значение (кг)
1 200 180
2 150 190
3 140 120
4 160 220

При таком количестве данных даже визуально можно оценить качество предсказанных данных. Предсказания под номерами 1 и 3 были достаточно точны, номер 2 показал бОльшую ошибку, а в строке номер 4 ошибка оказалась очень большой.

Для тысяч таких строк визуально оценить качество невозможно, необходимы агрегированные показатели.

Mean Absolute Error (MAE) – средняя абсолютная ошибка

Довольно интуитивный способ – сложить ошибки каждого из предсказаний и разделить на количество предсказаний. Посчитаем для нашей таблицы:

40+20+40+604=35кг

В среднем наш алгоритм ошибается на 35 кг картошки. Где-то в плюс, где-то в минус. Такая метрика называется средней абсолютной ошибкой, mean absolute error или MAE.

MAE=1ni=1n|yixi|=1ni=1n|ei|

где yi – предсказанные значения, а xi – реальные известные значения, ei - ошибка i-го предсказания.

Mean Square Error (MSE) – Средняя квадратичная ошибка

Достаточно часто используется похожая метрика, MSE. Она рассчитывается почти так же, только берется не модуль ошибки ei, а ее квадрат.

MSE=1ni=1n(yixi)2=1ni=1nei2

Для нашего примера:

MSE=400+1600+400+36004=1500кг2

Но мы получили не ошибку в килограммах, а “кг в квадрате”. Чтобы вернуться к исходной величине, необходимо извлечь из MSE квадратный корень:

RMSE=MSE=1500=38.72кг

По сравнению с RMSE, метрика MAE более интуитивна, т.к. усредняются сами отклонения, но RMSE удобнее использовать при обучении алгоритмов. Хотя для MAE обучение тоже успешно выполняется.

Еще одна особенность метрики MAE — она более устойчива к выбросам, чем RMSE. Это означает, что если для одного объекта ошибка очень большая (объект-выброс), а для остальных объектов – маленькая, то значение MAE подскочит от этого одного объекта меньше, чем RMSE, т.к. в RMSE ошибки возводятся в квадрат. В нашем примере объектом-выбросом является четвертое предсказание.

Quantile loss

Иногда ошибка в меньшую или большую сторону может иметь разное влияние на бизнес. Например, если мы предскажем на одну тысячу единиц товара меньше, чем реально потребуется, то потеряем прибыль: некоторым клиентам не достанется товара. А если мы предскажем на одну тысячу единиц больше товара, чем реально потребуется, то появятся дополнительные издержки на хранение товара.

Предположим, что товар занимает мало места (т.к. площади хранения в ресторанах велики) и расходы на хранение невелики, тогда лучше ошибиться в большую сторону, чем в меньшую. В этом случае отрицательную и положительную разницу домножают на разные коэффициенты, например, возьмем 0.5 и 1.5.

В нашем примере, коэффициент 1.5 будет применен к предсказаниям 1 и 3 (180 < 200 и 120 < 140), а коэффициент 0.5 к остальным. Тогда значение метрики будет равно:

1,520+0,540+1.520+0.5604=27.5кг

Данная метрика называется квантильной ошибкой.

Само по себе значение метрик MSE или MAE можно сравнивать со средним значением целевой переменной: например, нам нужно предсказывать десятки, при этом допустимы ошибки порядка единиц. Если хочется получать значения ошибки в процентах («алгоритм в среднем ошибается на столько-то процентов»), можно использовать метрики с нормировками.

К примеру, метрика MAPE (mean average percentage error) усредняет значения ошибок, деленных на значение целевой переменной:

MAPE=20200+40150+20140+601604=22.1

В нашем случае, алгоритм в среднем ошибается на 22.1%.

Важно понимать, что идеальных алгоритмов, как и нулевых значений метрик ошибок, в машинном обучении не бывает: такова суть этой области, что она помогает выполнять приблизительные предсказания. Величину метрик обычно определяет заказчик.

Метрики качества классификации

Accuracy – доля правильных ответов

В задаче классификации самой простой метрикой качества является доля правильных ответов (accuracy). Она показывает, в каком проценте случаев алгоритм правильно указал класс объекта.

Для примера будет рассматривать задачу предсказания токсичности комментариев. Т.е. имеем задачу бинарной классификации, где 0 – комментарий нетоксичен, 1 – комментарий токсичен. Возьмем для простоты пять комментариев и сведем все в таблицу.

ID комментария Значение в данных (токсичен ли комментарий в действительности) Предсказанное значение
1 1 1
2 1 1
3 0 0
4 0 1
5 0 0

В нашем примере, алгоритм выдал правильные ответы для комментариев 1,2,3,5, т.е. в 80% случаев. Это и есть значение accuracy.

Accuracy – простая и интерпретируемая метрика, но она не отражает полную картину, в частности, в какую сторону алгоритм ошибается чаще. Кроме того, использовать эту метрику может быть неудобно в ситуации с несбалансированными классами, то есть, когда объектов одного класса много больше, чем объектов другого. К примеру, если в данных 95% объектов из класса 0 и 5% из класса 1, а алгоритм всегда предсказывает, что объект относится к классу 0, то его accuracy будет равно 95%, хотя алгоритм совершенно бесполезный! В таких случаях часто используют другие метрики.

Precision and Recall – Точность и полнота

Чтобы понять, что такое точность и полнота, разберемся сначала с возможными типами ошибок. Для этого отлично подходит картинка из википедии.

Ошибки первого и второго рода

В нашем примере, если алгоритм пометит нормальный комментарий как токсичный, то ничего особо страшного не произойдет. Этот коммент будет в дальнейшей проверен модератором. Такая ошибка называется ошибкой первого рода (false positive). Если же комментарий будет распознан как нормальный, но он токсичный, то такая ошибка называется ошибкой второго рода (false negative). На мой взгляд, в нашем примере ошибка второго рода страшнее, чем ошибка первого. Но бывает и наоборот.

Для отслеживания двух видов ошибок используют метрики точность (Precision) и полнота (Recall).
  • Точность измеряет, какой процент объектов, для которых алгоритм предсказал класс 1, действительно относится к классу 1. В нашем примере, точность – это отношение количества реально токсичных комментариев к количеству помеченных как токсичные. И эта метрика составляет ⅔ = 66%.
  • Полнота измеряет, для какого процента объектов класса 1 алгоритм предсказал класс 1. Для нашего примера полнота составляет 100%. Для простоты понимания, в вики формулы расчеты показаны визуально.
Расчет точности и полноты

Отслеживать обе метрики сразу может быть неудобно, и может понадобиться скомбинировать их в одной. Для этого используют F-меру – среднее гармоническое точности P и полноты R:

F=2PRP+R

Такой способ усреднения был выбран потому, что F-мера принимает высокие значения, только когда обе метрики принимают высокие значения. Иными словами, если хотя бы одна из двух метрик близка к 0, F-мера тоже будет близка к 0. Это свойство не выполняется, например, для среднего арифметического из точности и полноты.

Ансамблевые методы

В этом разделе поговорим про ансамбли – методы, наиболее часто используемые в машинном обучении при работе с табличными данными. Ансамбли обычно применяют в задачах классификации и регрессии, но они годятся и для других задач, которые сводятся к этим двум. Стоит сказать, что это только вершина айсберга и методов машинного обучения очень много. Их обзор можно найти в этой статье.

Вспомним постановку задач регрессии и классификации. В обеих требуется набор табличных данных: по строкам таблицы заданы объекты (например, клиенты), а по столбцам – признаки, то есть некоторые характеристики объектов (возраст, заработная плата, стаж работы клиента и т. д.). Кроме того, нужна разметка данных: для каждого объекта должно быть известно значение целевой переменной (класс в задаче классификации или число в задаче регрессии). Имея набор размеченных данных, мы обучаем алгоритм, который будет предсказывать значение целевой переменной для новых объектов на стадии внедрения.

Ансамблирование чаще всего используют применительно к решающим деревьям, поэтому начнем блок с разбора этого метода.

Решающее дерево – это алгоритм, который делает предсказания на основе серии вопросов об объекте.

Например, покажем решающее дерево, которое определяет возможность проставления оценки по какому-то предмету студенту.

Пример решающего дерева

Ансамблирование заключается в том, чтобы обучить несколько алгоритмов и усреднять их предсказания.

Например, строится несколько разных решающих деревьев, и берется среднее результатов их работы. Подробно про ансаблирование в машинном обучении можно почитать тут.

Решаем Titanic на Kaggle

Для начала неплохо было бы ознакомиться с задачей и данными, которые нам предоставляют. Идем на kaggle.com/c/titanic/overview. Изучив описание, узнаем, что нам предстоит решить задачу классификации: по заданным признакам необходимо определить, выживет ли пассажир при крушении Титаника или нет. Предлагаемые данные (раздел Data) состоят из трех файлов .csv: train.csv – обучающая выборка, в которой содержатся метки, выжил ли каждый конкретный пассажир или нет; test.csv – собственно данные для решения, именно в этом файле нам нужно определить выживаемость; gender_submission.csv – пример того, как должен выглядит файл-ответ.

Что нужно делать – понятно. Начинаем смотреть наши данные. Переходим на вкладку Code и нажимаем New notebook.

Таким образом, мы получаем продвинутый jupyter notebook. Чтобы активировать систему, нажмем на значок Play слева от верхней ячейки ноутбука. Система будет запущена и в результате, под ячейкой увидим пути до csv файлов.

Можно приступать. Если вы не знакомы с jupyter notebook и pandas, то рекомендую сначала прочитать данный материал.

Чтение и анализ датасета Titanic

Первым делом, загружаем в датафреймы файлы .csv.

train_data = pd.read_csv('/kaggle/input/titanic/train.csv')
test_data = pd.read_csv('/kaggle/input/titanic/test.csv')

Проверим, что все у нас удачно и взглянем на эти датафреймы. Для примера приведу train_data.

train_data.head()

Первым делом оценим размеры датафрейма. Для этого используем свойство shape.

train_data.shape

В результате получаем (891, 12), т.е. 12 столбцов и 891 строку.

Следующим этапом неплохо было бы оценить количество пустых ячеек в столбцах обучающей выборки. Для этого вызовем:

train_data.isnull().sum()

Получаем, что в столбце Age у нас 177 пропусков, а в Cabin аж 687, что сильно больше половины.

Далее, оценим выживаемость. Для простоты визуализации будем использовать библиотеку seaborn. Для этого подключить ее и matplotlib.

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.countplot(x='Survived', data=train_data)

Как видим, выжило людей меньше, чем погибло.

Теперь посмотрим, как с выживаемостью у мужчин и женщин отдельно.

sns.countplot(x='Survived', hue='Sex', data=train_data)

Видим, что мужчин погибло гораздо больше, чем выжило. И большая часть женщин выжила.

Далее взглянем, как зависела выживаемость от класса каюты.

sns.countplot(x='Survived', hue='Pclass', data=train_data) 

Видим всплеск среди погибших пассажиров 3 класса.

Не закапываясь глубоко в датасет, видим явную зависимость выживаемости от пола и класса каюты.

В качестве признаков кроме выбранных пола и класса каюты, возьмем количество родителей\детей и количество братьев\сестер на борту. Итоговый список признаков будет выглядеть следующим образом:

features = ['Sex', 'Pclass', 'SibSp', 'Parch']

Информацию о выживших и погибших пассажирах поместим в переменную y:

y = train_data['Survived']

Если вы немного отмотаете назад, то увидите, что в столбце Sex находятся не числа, а строки, когда остальные отобранные нами признаки являются числами. Давайте превратим этот столбец в пару фиктивных переменных. Для этого в Pandas есть специальный метод, который называется get_dummies(). Сделаем эту операцию как для обучающей выборки, так и для тестовой.

X = pd.get_dummies(train_data[features])
X_test = pd.get_dummies(test_data[features])

Обратите внимание, что столбец Sex исчез, а вместо него появилось два столбца Sex_female и Sex_male.

Теперь с помощью ансамбля решающих деревьев обучим нашу модель, сделаем предсказание для тестовой выборки и сохраним результат. Ансамбль решающих деревьев называется Random Forest.

from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=1)
model.fit(X, y)  # обучаем модель
prediction = model.predict(X_test)  # делаем предсказание
output = pd.DataFrame({'PassengerId':test_data.PassengerId, 'Survived':prediction})
output.to_csv('my_submission.csv', index=False)  # формируем итоговый датафрейм и сохраняем его в csv файл

Вот и все. Осталось отправить результат в соревнование. Для этого в правом верхнем углу наживаем кнопку Save version. После того, как блокнот сохранится, нажимаем на цифру возле этой кнопки.

Откроется окно Version history. В правом списке, нажимаем на многоточие около только что сохраненной версии и нажимаем Submit to competition.

Появляется окошко, в котором нажимаем submit.

Поздравляю! Вы закончили свое первое соревнование на kaggle. Нажмите на view my submission, чтобы взглянуть на результат.

Чем ближе число к 1, тем лучше. Но 0.775, согласитесь, неплохо для первого раза.

Путями улучшения результата могут быть: введение дополнительных признаков, введение своих новых признаков, выбор другого алгоритма, выбор другим параметров алгоритма RandomForestClassifier. Для начала, попробуйте поиграть с числами в этой строке (называются эти числа гиперпараметрами).
model = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=1)

Дополнительные материалы для изучения:

При подготовке были использованы материала из Википедии и Летней школы Сбера.

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

admin
11 декабря 2018

ООП на Python: концепции, принципы и примеры реализации

Программирование на Python допускает различные методологии, но в его основе...
admin
14 июля 2017

Пишем свою нейросеть: пошаговое руководство

Отличный гайд про нейросеть от теории к практике. Вы узнаете из каких элеме...