В тази статия ще се съсредоточа върху изграждането на много прост алгоритъм на дървото на решенията за прогнозиране на коефициентите за оцеляване на Титаник [вижте „Състезанието на Kaggle”]. Бързо ме доведе до 0,79904 точност на тестовия набор от данни, което беше най-високото ниво от 13% по това време.

Настройвам

Импортиране на подходящи библиотеки

Импортирайте набора от данни за обучение от предоставения от Kaggle .csv файл и го разгледайте:

Бързо проучване на данните

Преглед на набора от данни тук.

Колко реда и колони има в този набор от данни?

Още изследвания:

Веднага виждаме, че в категориите възраст, кабина и качване липсват някои данни (те имат по-малко от 891 записа).

(Виждаме също, че някои записи са категорични, но повече за това по-късно.)

Адресиране на липсващи данни

Ето един лесен начин за количествено определяне на липсващите данни:

Добре, така че липсват много записи в каюта, някои записи в възраст и само няколко вписвания качени. Ще трябва да се справим с това по-късно.

Нека опитаме и това:

////////В идеалния случай това е мястото, където правим проучвателна визуализация на данните, но тъй като има доста неща, които могат да се направят, това наистина е тема за друга публикация. Така или иначе няма да правя никакви сложни предположения в публикацията по-долу, така че нека засега пропуснем визуализацията.////////

Трябва да се справим с 3 функции, за които липсват данни: Кабина, Възраст и Качен:

  • Embarked е най-лесният, тъй като само 2 записа от 891 (0,2%) липсват. Нека просто ги премахнем.

  • Кабината също е проста. Видяхме по-горе, че ни липсват 687 от 891 (77%) данни. Дори тези данни да са значими, твърде много от тях липсват, така че нека просто да изтрием тази колона:

(Ако проучим данните, можем също така да видим, че данните за кабината не са добре структурирани, така че има вероятност да са безсмислени така или иначе.)

  • Това ни оставя с Възраст. 177 стойности, нашите от 891 липсват (~20%). Трябва ли да игнорираме цялото поле или да се опитаме да направим нещо с него? Интуитивно можем да предположим, че възрастта може да корелира с процентите на оцеляване (жените и децата са по-склонни да успеят, нали?), така че нека се опитаме да запазим тази функция.

Не можем да обучим нашия модел с NaN данни, присъстващи в колоната Възраст, така че трябва да го заменим с действителна стойност (импутиранеако ви харесва). Замених липсващите данни със средна (средна) възраст за всички пътници и проработи; но трябва да мисля, че може би замяната му със средна възраст за пол и класа на кабината би била по-успешна. Можем да стигнем до това в крайна сметка, но точно сега се опитваме да не премисляме нещата.

Добре, сега се справихме с липсващите данни, но все още имаме едно препятствие, преди да изградим нашия модел: някои данни са категорични (както в Пол == Жена или Пол == Мъж) и това няма да работи. Трябва да го преобразуваме в нещо, което нашият модел ще може да използва.

Кодиране на категорични характеристики

Нека проверим къде сме с този набор от данни в момента:

Сега е добър момент да направите бърз избор на функции:

  • Не се нуждаем от PassengerId — това е просто кардинален номер, който вероятно няма никакво влияние върху това дали пътникът е оцелял (освен ако пътниците не са се качили на спасителните лодки по начин „първи влязъл, първи излязъл“).
  • Засега ще игнорираме Име (разумно е да се предположи, че самото име не е повлияло на шансовете за оцеляване)
  • Ще пренебрегнем и Билета. Можете да изследвате сами, но има смисъл номерът на билета да не влияе на шансовете за оцеляване на пътника. Това е просто число.

Премахване на тези колони:

Това ще ни остави с две нечислови променливи, Sex и Embarked:

  • Полът има само 2 опции в този набор от данни (можете да изследвате сами): мъжки и женски.
  • Embarked има 3 опции: Q, C и S. (C = Шербур, Q = Куинстаун, S = Саутхемптън. Засега нека не се притесняваме какво могат да означават (напр. е едно от тези къде ще се качи персоналът на кораба? Единият по-добър ли е от другите два? и т.н.))

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

Кодиране на категорични характеристики

Използвах метода Pandas get_dummies. „Съответна документация“.

Това промени някои полета в сравнение с предишните:

  • Sex беше преобразуван в Sex_male (което означава, че Sex_male тук е или мъж, 1, или не, 0)
  • Embarkedбеше преобразуван2 колони: Embarked_Q и Embarked_S (което означава, че ако и двете са 0, тогава пътникът качен в C, Шербур.)

Добре, след като приключихме с това...

…Но какво да кажем за мащабирането на характеристиките?

Ще пропусна мащабирането на функции тук, защото го направих бързо като тест и не видях никакво положително въздействие върху крайните резултати. Ако все пак искате да опитате, опитайте minmaxscalerотsklearn.preprocessing(docs). Кажете ми дали работи за вас!

Можем ли най-накрая да изградим модел сега? почти.

Добре, добре, данните изглеждат добре и имат смисъл, нека всъщност направим малко машинно обучение.

Първо, нека разделим нашия набор от данни на целева променлива (това, което се опитваме да предвидим, в този случай съдържанието на колоната „Оцелели“) и функции (данните ще се използват за прогнозира нашата целева променлива). Съгласно стандартната практика, ние обозначаваме целевата променлива като y, а характеристиките като X.

Сега нека разделим нашите данни на набор от данни за обучение и тестване:

Поиграх си малко с test_size и получих най-добрия резултат от 0,3 (или 30%), но ме уведомете дали друга стойност работи по-добре. Стойността по подразбиране ще бъде 0,25.

Добре, но сега можем ли да изградим този модел?

И накрая, нека осъществим този модел:

Това всъщност е най-лесната част. Но:

  • Поиграх си малко с max_depth. 2 е твърде плитко, а 4 и повече води до пренатоварване, така че 3 е така.
  • Без да ограничавам min_samples_leaf, завърших с някои мостри с размер 1, което е наистина прекомерно, така че го ограничих до 10. Имах подобен късмет и с 15.

И така, как се отразява това върху данните за обучение и тестове?

Готино. Нека да видим как всъщност изглежда дървото на решенията:

Ето нашия резултат:

Както можете да видите, жените в клас 1 и 2 имаха най-голям шанс за оцеляване.

Можем да преминем към правенето на прогнози за тестовия набор от данни сега, но нека първо създадем матрица на объркване, просто защото се чувстваме фантастични:

И така, кой живее и кой умира?

Нека въведем нашия тестов набор от данни:

Изглежда много подобен на нашия оригинал, но без полето Survived (което има смисъл, тъй като точно това се опитваме да предвидим). Използване на df_predict.head():

Нека разгледаме накратко тези данни:

Наблюдения:

  • Някои записи в Cabin липсват, но тъй като не използвахме това поле при изграждането на нашето дърво, просто ще го изтрием заедно с друго поле, което не сме използвали, като PassengerId.
  • Някои записи за Възраст липсват (86/418 = ~20% точно както в набора от данни за обучение). Тук също ще трябва да вменим липсващите данни.
  • 1 Липсва запис за тарифа. Не можем да го изпуснем, защото голмайсторът на Kaggle очаква да види всички редове, така че ще трябва да го заменим с нещо. Избрах средно.

Сега ще трябва отново да използваме метода get_dummies, за да се справим с категоричните променливи:

Добре – сега това изглежда така, както направи нашият набор от данни за обучение:

Сега, нека създадем нашия набор от данни за прогнози, за да можем да го качим обратно в Kaggle:

Ще изглежда така:

Нека създадем експортируем .csv файл:

Всичко, което направих след това, беше да преименувам колоните, да изтрия индексната колона и да я кача в Kaggle. Воаля.