Руководство по машинному обучению для начинающих: модель прогноза выживших на «Титанике»

Начало работы

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

Формат работы: вы начнёте с введения в машинное обучение на основе написания алгоритма, который будет предсказывать, сколько человек выживет при крушении «Титаника». Затем последуют две тренировочные сессии. Руководство будет направлять вас в дальнейшей работе, но код вы должны будете писать самостоятельно.

Требуемые знания: предполагается, что вы уже имеете опыт работы с Python или знаете его на уровне выше базового. Также предполагается, что вы знакомы с Pandas на базовом уровне. Если вы желаете подтянуть знания по Pandas, предлагаем ознакомиться со специальной статьёй. Также предлагаем вам посмотреть курс по основам Pandas.

Разработка будет выполняться с использованием Ipython (если вы раньше не работали с этой оболочкой, можете посмотреть вводный видеоурок и ознакомиться с командной оболочкой для интерактивных вычислений Jupyter Notebook в нашей статье). По определённым причинам рекомендуется использовать пакет Anaconda с Python 3.

Введение в машинное обучение

Презентация к уроку

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

Машинное обучение с Python

Исходный код, с которым вы будете работать, доступен на платформе Github. Для его загрузки регистрация не требуется. Titanic_Machine_Learning.ipynb — название файла, с которым вам предстоит работать.

Начнём с импорта основных библиотек: Pandas и Numpy.

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

Если вы посмотрели презентацию (что действительно стоило сделать, иначе вы не сможете следовать половине кода), вы знаете, что нужно разделять данные для теста и для тренировки, чтобы не произошло переобучение. Поэтому нужно импортировать функцию train_test_split().

Теперь давайте отключим предупреждения от Pandas.

Пришло время импортировать функцию joblib. Она будет использоваться для написания модели в файле для повторного использования.

Теперь нужно открыть файл с расширением csv в Pandas. (Вы можете сделать это с помощью Excel или OpenOffice.)

Вы увидите что-то вроде таблицы сверху (обращаем внимание, что некоторые колонки не отображены из-за чрезмерной ширины таблицы).

Посмотрите на колонку age. В таблице на изображении выше нет ячеек со значением NaN, что означает, что нет данных. В нашем случае есть просто пустые ячейки. Но обратите внимание, что NaN и пустая ячейка — одно и то же.

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

Ожидаемые выходные данные — данные, которые мы получим в колонке survived (выжившие). Как насчёт входных данных?

Вы ведь смотрели фильм «Титаник»? (Если нет, то сейчас будет спойлер: он утонет.) Когда пришло время распределения людей по шлюпкам, больше шансов на спасение имели обладатели билетов первого класса. Также предпочтение отдавалось женщинам и детям.

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

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

Если же речь идёт о мужчине среднего возраста с билетом третьего или второго класса, то шансов на выживание становится в разы меньше. Всё как в фильме. Несмотря на то, что в таблице также указана цена билета, нам важнее знать, к какому классу относится этот билет. Если к первому, то шансы на выживание заметно возрастают.

Давайте вернёмся к пустым ячейкам. Мы не можем их оставить пустыми, потому что нам нужна информация в них для выполнения вычислений.

Решение проблемы: заменяем пустые поля медианой.

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

  • Среднее арифметическое — сумма чисел вы выборке, делённая на количество чисел в выборке. Пример: вы написали 5 строк кода, ваш друг написал 9 строк кода, ваша подруга написала 7 строк кода. В среднем вы все написали по 7 строк: 5 + 9 + 7 = 21, 21 / 3 = 7.
  • Медиана (серединное число) — это такое число выборки, при котором половина значений выборки больше него, а другая половина меньше него. Пример: 1, 2, 5, 10, 21, 33, 57. Медианой в данном случае будет 10, так как числа слева меньше, а числа справа больше и с обеих сторон расположено одинаковое количество чисел.
  • Мода — самое повторяющееся число из всех повторяющихся.

В нашем случае сейчас будем использовать медиану для определения возраста.

Можно подсчитать медиану с помощью функции median() в Pandas, из примера выше видно, что медианой является число 29.

Теперь нужно заменить пустые значения в колонке age на значение медианы. Для этого следует использовать функцию fillna().

Помните пустые (NaN) значения? Теперь они заменены на 29.

Теперь нужно извлечь три нужных нам поля: class (класс), age (возраст), sex (пол).

Для чего это нужно делать?

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

Ожидаемые выходные данные:

Как видите, у нас возникла проблема. Алгоритмы в библиотеке Scikit, которая используется, работают только с числами. Иначе говоря, алгоритм не понимает, что 1st — первый класс.

Давайте исправим проблему. Просто заменим 1st на 1, 2nd на 2, 3d на 3. Элементарно!

Теперь проблема с классом исправлена. Возраст выставлен правильно. Остаётся поправить проблему с полом.

Будем использовать функцию np.where(), которая не является интуитивной.

Функция заменила female на 0 и male на 1.

Тестирование для предотвращения переобучения

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

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

Функция возвращает учебные входные и выходные данные, а также выходной набор данных.

test_size=0.33 значит, что 33% набора данных будет использоваться для тестирования, остальное — для обучения. random_state используется для запуска встроенного генератора случайных выборок.

Давайте выведем несколько значений:

Теперь нужно запустить машинное обучение.

Создаём образец алгоритма Random forest.

Функция fit() используется для обучения нашего алгоритма. Он берёт часть выходных данных и пытается приблизить свой результат к ним. Поэтому мы и сузили поля для сканирования, теперь у алгоритма нет серьёзных помех, которые могли бы быть из-за прочей информации.

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

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

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

Последний шаг близок. Всё это время тренировался алгоритм. Но нам ведь не нужно, чтобы он всё время повторял этот процесс. (Если каждый день складывать одни и те же числа, то умнее человек не станет, верно?) Следующая часть статьи не отнимет у вас много времени, так как наш набор данных невелик.

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

Раньше для этого использовалась библиотека Pickle, но функция joblib.dump намного проще. Применение compress=9 является необходимым условием, в противном случае будут созданы десятки файлов.

Практика

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

Работать предстоит с новым файлом, который раннее не использовался — titanic_test.csv. Он был создан с использованием оригинальных данных, от которых были отсечены 30% данных.

Извлеките из набора данные класса и пола, как мы это сделали для первой практики.

Теперь нужно взять входные данные и пропустить их через прогнозирующую функцию:

Сверху вы видите пустую функцию predict(). Вам нужно сделать predict(data), чтобы прогнозирование запустить.

На этом урок закончен. Спасибо за внимание!

Перевод статьи «Machine Learning For Complete Beginners»