В тази статия ще се съсредоточа върху изграждането на много прост алгоритъм на дървото на решенията за прогнозиране на коефициентите за оцеляване на Титаник [вижте „Състезанието на 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. Воаля.