Керівництво по машинному навчанню для початківців: модель прогнозу тих, хто вижили на “Титаніку”


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

Початок роботи

Багато керівництв по машинному навчанню розраховані на те, що учень вже є кандидатом математичних наук або провідний фахівець зі статистики. Це керівництво написане для тих, хто раніше не був ознайомлений з машинним навчанням.

Формат роботи. Ви розпочнете зі вступу в машинне навчання на основі написання алгоритму, який передбачатиме, скільки людей виживе за краху “Титаніка”. Потім послідують дві тренувальні сесії. Керівництво направлятиме Вас у подальшій роботі, але код Ви повинні писатими самостійно.

Необхідні знання. Передбачається, що Ви вже маєте досвід роботи з Python або знаєте його на рівні вище базового. Також важливо, щоб Ви були ознайомлені з Pandas на базовому рівні. Якщо бажаєте поглибити знання з Pandas, пропонуємо ознайомитися зі спеціальною статтею. Також пропонуємо Вам подивитися курс із засад Pandas.

Розробка виконуватиметься з використанням Ipython (якщо Ви раніше не працювали з цією оболонкою, можете подивитися ввідний відеоурок і ознайомитися з командною оболонкою для інтерактивних обчислень Jupyter Notebook у нашій статті). Через певні причини рекомендуємо використати пакет Anaconda з Python 3.

Вступ у машинне навчання

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

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

Машинне навчання з Python

Вихідний код, з яким Ви працюватимете, доступний на платформі Github. Для його завантаження реєстрація не потрібна. Titanic_Machine_Learning.ipynb – назва файлу, з яким Вам належить працювати.

Розпочнемо з імпорту основних бібліотек: Pandas і Numpy.

import numpy as npimport pandas as pd

Для машинного навчання використовуватиметься алгоритм Random Forest. На даний момент Вам не треба знати, як він працює (для подальшої роботи обов’язково вивчіть!), але Вам треба знати, як його слід застосовувати у справі.

#Алгоритм машинного обученияfrom sklearn.ensemble import RandomForestClassifier

Якщо Ви подивилися презентацію (що дійсно варто було зробити, інакше не зможете наслідувати половину коду), Ви знаєте, що треба розділяти дані для тесту і для тренування, щоб не сталося перенавчання. Тому треба імпортувати функцію train_test_split ().

#Імпорт функції
from sklearn.cross_validation import train_test_split

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

# Відключення попереджень Pandaspd.options.mode.chained_assignment = None

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

#Використовується для запису моделі у файлfrom sklearn.externals import joblib

Тепер треба відкрити файл з розширенням csv у Pandas. (Ви можете зробити це за допомогою Excel або OpenOffice.)

data = pd.read_csv ("titanic_train.csv") data.head ()

Ви побачите щось подібне у таблиці, наведеній вище (звертаємо увагу, що деякі колонки не відображені через надмірну ширину таблиці).

Подивіться на колонку age. На зображенні вище у таблиці немає осередків зі значенням NaN, це означає, що немає даних. У нашому випадку є просто порожні осередки. Зверніть увагу на те, що NaN і порожній осередок – те саме.

У презентації Вам було дано завдання: треба було знайти корисні, на Ваший погляд, вхідні дані для алгоритму.

Очікувані вихідні дані – дані, які ми отримаємо в колонці survived (ті, хто вижили). Як щодо вхідних даних?

Ви ж дивилися фільм “Титанік”? (Якщо ні, то зараз буде спойлер: він потоне). Коли прийшов час розподілу людей по шлюпках, більше шансів на порятунок мали володарі квитків першого класу. Також перевага віддавалася жінкам і дітям.

Таким чином ми можемо визначити, що найбільш важливі моменти, які визначають шанс порятунку, це клас квитка, вік і стать.

Якщо Ви жінка солідного віку з дітьми і з квитком першого класу, то Вам пощастило – вірогідність вижити збільшується.

Якщо ж йдеться про чоловіка середнього віку з квитком третього або другого класу, то шансів на виживання стає набагато менше. Все як у фільмі. Попри те, що в таблиці також вказана ціна квитка, нам важливіше знати, до якого класу відноситься цей квиток. Якщо до першого, то шанси на виживання помітно підвищуються.

Давайте повернемося до порожніх осередків. Ми не можемо їх залишити порожніми, тому що нам потрібна інформація в них для виконання обчислень.

Розв’язання проблеми. Замінюємо порожні поля медіаною.

Перед тим, як продовжити читання, переконаєтеся, що розумієте наступні терміни:

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

У нашому випадку зараз використовуватимемо медіану для визначення віку.

median_age = data['age'].median () print ("Median age is {}".format (median_age)) Median age is 29.0

Можна підрахувати медіану за допомогою функції median () у Pandas, з прикладу вище видно, що медіаною є число 29.

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

data['age'].fillna (median_age, inplace = True) data['age'].head () 0 291 652 593 464 29

Пам’ятайте порожні (NaN) значення? Тепер вони замінені на 29.

Тепер треба витягнути три потрібних нам поля: class (клас), age (вік), sex (стать).

Навіщо це треба робити?

Це робиться для того, щоб не заплутати алгоритм і не створювати зайвий шум.

data_inputs = data[[" pclass", " age", " sex"]]data_inputs.head ()

Очікувані вихідні дані:

expected_output = data[[" survived"]]expected_output.head ()

Як бачите, у нас виникла проблема. Алгоритми у використовуваній бібліотеці Scikit працюють тільки з числами. Інакше кажучи, алгоритм не розуміє, що 1st – перший клас.

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

data_inputs["pclass"].replace ("3rd", 3, inplace = True) data_inputs["pclass"].replace ("2nd", 2, inplace = True) data_inputs["pclass"].replace ("1st", 1, inplace = True) data_inputs.head ()

Тепер проблема з класом виправлена. Вік виставлений правильно. Залишається розв’язати проблему зі статтю.

Використовуватимемо функцію np.where (), яка не є інтуїтивною.

data_inputs["sex"] = np.where (data_inputs["sex"] == "female", 0, 1) data_inputs.head ()

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

Тестування для запобігання перенавчанню

Як Ви могли запам’ятати з презентації, дані були розділені на набір для тестування і на набір для навчання. Навчальний набір використовується для тренування алгоритму, тоді як набір для тесту використовується для виявлення точності алгоритму. (Оскільки у нас є передбачувані вихідні дані, ми можемо порівняти їх з результатами алгоритму і вичислити відсоток неточності).

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

inputs_train, inputs_test, expected_output_train, expected_output_test = train_test_split (data_inputs, expected_output, test_size = 0.33, random_state = 42)

Функція повертає навчальні вхідні та вихідні дані, а також початковий набір даних.

test_size=0.33 означає, що 33 % набору даних використовуватиметься для тестування, решта – для навчання. random_state використовується для запуску вбудованого генератора випадкових вибірок.

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

print (inputs_train.head()) print (expected_output_train.head()) pclass age sex618 3 19 1169 3 29 1830 1 54 1140 3 29 1173 2 28 1 survived618 0169 0830 1140 0173 0

Тепер треба запустити машинне навчання.

rf = RandomForestClassifier (n_estimators=100)

Створюємо зразок алгоритму Random forest.

rf.fit (inputs_train, expected_output_train)

Функція fit () використовується для навчання нашого алгоритму. Він бере частину вихідних даних і намагається наблизити свій результат до них. Тому ми і звузили поля для сканування, тепер в алгоритму немає серйозних перешкод, які могли б з’явитись через іншу інформацію.

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

accuracy = rf.score (inputs_test, expected_output_test) print ("Accuracy ={}%".format (accuracy * 100)) Accuracy = 79.60526315789474%

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

У прикладі вище показана точність, яка становила 79 %. Ми дізнаємося, на скільки це добре, тільки коли зможемо порівняти з чимось.

Останній крок близько. Весь цей час тренувався алгоритм. Проте нам не треба, щоб він увесь час повторював цей процес. (Якщо щодня складати ті самі числа, то розумніше людина не стане, чи не так?) Наступна частина статті не забере у Вас багато часу, оскільки наш набір даних невеликий.

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

joblib.dump (rf, "titanic_model1", compress=9)

Раніше для цього використовувалася бібліотека Pickle, але функція joblib.dump набагато простіше. Застосування compress=9 є необхідною умовою, інакше будуть створені десятки файлів.

Практика

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

Працювати належить з новим файлом, який раніше не використовувався, – titanic_test.csv. Він був створений з використанням оригінальних даних, від яких були відсічені 30 % даних.

Витягніть з набору дані класу і статі, як ми це зробили для першої практики.

rf = joblib.load ("titanic_model2")

Тепер треба взяти вхідні дані і пропустити їх через прогнозну функцію:

pred = rf.predict ()# помістіть сюди Ваші змінні дані

Вище Ви бачите порожню функцію predict (). Вам треба зробити predict (data), щоб запустити прогнозування.

На цьому урок закінчений. Дякую за увагу!

Переклад статті “Machine Learning For Complete Beginners”

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *