Направете подобрения и изпратете отново

Направихме първото си представяне на Kaggle в Част 3. В последната част от тази поредица ще се опитаме да направим подобрения на нашите прогнози и ще ги изпратим отново, за да видим нашите резултати. Връзка към видео версия на този урок ще бъде в долната част.

Да започваме!

Когато става въпрос за подобряване на нашите прогнози, обикновено има 2 неща, които искаме да вземем предвид:

  • Допълнително инженерство на функциите
  • Настройка на модела

Но преди да продължим по-нататък, нека да погледнем назад какъв беше нашият резултат за подаване, използвайки базовия модел:

Може да сте забелязали известно несъответствие тук. Защо наборът от тестове от нашето разделение 80–20 отбеляза 82,68% точност, докато прогнозите на набора от тестове на Kaggle дадоха само 76% точност?

Една от причините е, че има известна случайност в начините, по които тези модели предвиждат. 80% от данните, върху които тренирахме, може просто да изглеждат по-сходни с 20%, които оставихме като симулиран тестов набор, в сравнение с тестовия набор, предоставен от Kaggle. И в резултат на това моделът, обучен от тези 80% данни, ще се представи по-добре на 20% симулиран набор от тестове. Особено когато наборът ни за обучение е малък, е много вероятно прогнозите да се представят малко по-добре на един произволно избран набор от тестове, отколкото на друг.

Позволете ми да ви покажа какво имам предвид, като пусна някои тестове на различен случаен избор от 20% набор от тестове.

Използвахме произволно състояние 42 в нашата функция за разделяне на теста на влака:

Това число по същество определя кои 20% от данните ще бъдат избрани, така че всеки път, когато изпълняваме този ред, ще използва същото разделяне. Това се нарича произволно семе и е полезно в смисъл, че можем да имаме известен контрол върху произволността, за да получим честни сравнения между различни опити.

Нека да видим какво се случва, когато променим това произволно състояние на 0:

Сравнете това с резултата, когато произволното състояние е 42:

Резултатът ни за точност спада с над 2%.

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

За да получите средния резултат:

Импортирайте библиотеката numpy и използвайте .arange, за да създадете списък от 50 числа като произволни състояния. Използвайте всяко от тези 50 числа като произволно състояние и вземете средна стойност от съответния резултат за точност. Това е средно 78,8% точност.

Сега можем да се върнем към рамката с данни и да видим какви допълнителни функции можем да използваме, за да подобрим това представяне. В основния модел изпуснахме колоните Име, Билет и Кабина, така че може би има полезна информация, която можем да извлечем от тези 3 колони и ги включете обратно в модела.

Знаем, че има много липсващи стойности в колоната Кабина, така че вероятно не си струва да се опитваме да ги попълним всички, както направихме с колоната Възраст. Възможно е обаче да има причини, поради които определен пътник не е влязъл в кабината и тази причина може да бъде свързана с това дали той/тя е оцелял. Можем да проверим дали това е възможно, като разпечатаме коефициента на оцеляване на хора с липсващи записи в Cabin и тези без:

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

df["is missing cabin"] = df["Cabin"].isna()

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

След това стартирайте цикъла отново. Този път средният ни резултат е 78,7%, което предполага, че няма подобрения в модела чрез добавяне на тази функция.

Нека се опитаме да добавим нещо друго.

В секцията за дискусии на Kaggle често има хора, които споделят код, който е бил полезен за подобряване на техния модел. Можете да намерите вдъхновение от тези дискусии и да добавите функции към вашия собствен модел. Например намерих част от кода, който обработва колоната за име тук:



По същество има заглавие, което следва името на всеки пътник в колоната за име. Някои често срещани заглавия са г-н, госпожа, госпожица и тези заглавия винаги са последвани от „.“ характер. За да извлечете заглавие:

df['Title'] = df['Name'].str.extract(' ([A-Za-z]+)\.', expand=False)

И нашата колона Заглавие ще изглежда така:

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

Ако стартираме цикъла отново с функцията Заглавие, ще получим точност от 79,16%, което е малко по-добре от основния ни модел.

Сега експериментирахме с 2 допълнителни функции. Единият от тях изобщо не подобрява резултата ни, а другият го подобрява само с по-малко от 0,5%. Не се обезсърчавайте тук. Това понякога е показателно, че настройката на модела не е подходяща за проблема, което ни отвежда до втория начин за подобряване на производителността: направете корекции на модела. Използвахме хипер параметрите по подразбиране за нашия ExtraTreesClassifier, където параметър, наречен max_depth, е зададен на None. Този параметър ограничава максималната дълбочина, до която едно дърво в гората може да расте, а настройката по подразбиране „Няма“ позволява всяко дърво да расте възможно най-дълбоко, което може да направи модела склонен към пренастройване.

Нека се опитаме да зададем максимално ограничение на дълбочината от 10:

Очаквано, има по-значително увеличение на средния резултат за точност.

Знаейки влиянието на ограничаването на max_depth, нека се върнем към нашия базов модел и да видим какъв би бил средният ни резултат за точност с основните функции и max_depth =10. Ако стартирате нашата базова настройка отново с новата настройка на модела, трябва да получите среден резултат от 81,7%, което е дори по-високо.

За съжаление заключението на този етап е, че нашите базови функции, съчетани с параметрите {n_estimators=100, max_depth=10}, дават най-добра производителност. Това означава ли, че 2-те допълнителни функции, които проучихме, бяха напълно безполезни? Възможно е добавянето на тези 2 функции да не помогне, но на практика обикновено бихме направили много повече оптимизация, преди да стигнем до заключението, че функциите не са полезни (това ще изисква друга статия за обяснение). Набор от функции е с оптимална производителност само когато хиперпараметрите на модела също са подходящи за тези функции. Вече видяхме пример за това: характеристиките на базовата линия дадоха по-висок среден резултат за точност, когато зададохме max_depth на 10 вместо по подразбиране Няма. Ще напиша статия за обичайните начини за настройка на хипер параметри, които съм използвал, с предимствата и предупрежденията на всеки. Останете на линия, ако проявявате интерес!

Тъй като не използвахме допълнителни функции, не се налага да правим повече предварителна обработка на набора от тестове на Kaggle. Просто прогнозирайте с новия модел (max_depth=10) и запазете нашите прогнози в submission.csv и изпратете отново. Трябва да видите, че класирането ви се повишава, като добавите тази промяна!

Сега видеото, както беше обещано преди няколко минути...