Здравствуйте, в данной статье я постараюсь разобрать основные шаги и методы решения соревнований на Kaggle на примере решения обучающего соревнования от DeepLearningSchool МФТИ по предсказанию оттока пользователей.  Итак, для начала давайте загрузим наш датасет и посмотрим на 5 случайных строк в нем.  ClientPeriod MonthlySpending TotalSpent Sex IsSeniorCitizen HasPartner HasChild HasPhoneService HasMultiplePhoneNumbers HasInternetService HasOnlineSecurityService HasOnlineBackup HasDeviceProtection HasTechSupportAccess HasOnlineTV HasMovieSubscription HasContractPhone IsBillingPaperless PaymentMethod Churn 4650 66 20.35 1359.5 Male 0 Yes Yes Yes No No No internet service No internet service No internet service No internet service No internet service No internet service One year Yes Electronic check 0 29 25 89.70 2187.55 Female 1 No No Yes Yes Fiber optic No Yes No No No Yes Month-to-month Yes Electronic check 1 1688 36 76.35 2606.35 Female 0 No No Yes No DSL Yes Yes Yes Yes Yes No One year Yes Mailed check 0 2946 20 19.60 356.15 Male 0 No No Yes No No No internet service No internet service No internet service No internet service No internet service No internet service Month-to-month Yes Credit card (automatic) 0 4865 13 98.00 1237.85 Male 1 Yes No Yes No Fiber optic No Yes Yes No Yes Yes Month-to-month Yes Electronic check 1 Как видим, у нас есть 20 колонок, в которых записана информация о пользователях. Нам нужно понять, какие пользователи чаще всего уходят к другому оператору, а какие остаются. Для начала на будущее разметим колонки, часть из них нам нужно обозначить как категориальные(текстовые), а часть - как числовые. Колонку Churn обозначим как цель наших предсказаний.  Затем давайте проверим, есть ли повторяющиеся записи Duplicated rows: 28  Duplicated rows without target: 41  Видим, что у нас 28 одинаковый строк, если учитывать целевую Chern и 41 одинаковая строка, если не учитывать. Это значит, что у нас есть некоторое количество одинаковых записей с разным результатом. Такие строчки вредны для моделей, поскольку не дают четкого разделения классов, поэтому мы их удаляем. Далее нам нужно посмотреть, есть ли пропущенные значения в датасете. В нашем случае кроме NaN на месте пропусков был еще и пробел: " ". Давайте найдем, где именно они были Получаем 9 NaN в столбце TotalSpent. Рассмотрим этих клиентов подробнее.  ClientPeriod MonthlySpending TotalSpent Sex IsSeniorCitizen HasPartner HasChild HasPhoneService HasMultiplePhoneNumbers HasInternetService HasOnlineSecurityService HasOnlineBackup HasDeviceProtection HasTechSupportAccess HasOnlineTV HasMovieSubscription HasContractPhone IsBillingPaperless PaymentMethod Churn 1157 11 94.20 999.9 Female 0 No No Yes No Fiber optic No Yes Yes Yes No Yes Month-to-month Yes Electronic check 0 1048 0 25.75 NaN Male 0 Yes Yes Yes Yes No No internet service No internet service No internet service No internet service No internet service No internet service Two year No Mailed check 0 1707 0 73.35 NaN Female 0 Yes Yes Yes Yes DSL No Yes Yes Yes Yes No Two year No Mailed check 0 2543 0 19.70 NaN Male 0 Yes Yes Yes No No No internet service No internet service No internet service No internet service No internet service No internet service One year Yes Mailed check 0 3078 0 80.85 NaN Female 0 Yes Yes Yes No DSL Yes Yes Yes No Yes Yes Two year No Mailed check 0 3697 0 20.00 NaN Female 0 Yes Yes Yes No No No internet service No internet service No internet service No internet service No internet service No internet service Two year No Mailed check 0 4002 0 61.90 NaN Male 0 No Yes Yes Yes DSL Yes Yes No Yes No No Two year Yes Bank transfer (automatic) 0 4326 0 25.35 NaN Male 0 Yes Yes Yes Yes No No internet service No internet service No internet service No internet service No internet service No internet service Two year No Mailed check 0 4551 0 52.55 NaN Female 0 Yes Yes No No phone service DSL Yes No Yes Yes Yes No Two year Yes Bank transfer (automatic) 0 4598 0 56.05 NaN Female 0 Yes Yes No No phone service DSL Yes Yes Yes Yes Yes No Two year No Credit card (automatic) 0 Очевидно, это новые клиенты, которые еще не внесли первый платеж. Заполним их нулями.   Затем давайте посмотрим, как у нас распределены данные  На графике Churn в правом нижнем углу видно, что класс 1 представлен четвертью данных. Это означает, что люди в три раза чаще остаются, чем уходят. Многие столбцы имеют значения «No internet service» и «No Phone service». Поскольку у нас уже есть функции «HasPhoneService» и «HasInternetService» эта информация избыточна. Мы можем объединить их с опцией «No».  PaymentMethod Churn Churn (%)   sum count  0 Credit card (automatic) 165 1143 14.435696 1 Bank transfer (automatic) 195 1159 16.824849 2 Mailed check 230 1194 19.262982 3 Electronic check 794 1786 44.456887 Видим, что разница между электронным чеком и другими способами оплаты гораздо больше, чем между автоматическим и неавтоматическим.  HasContractPhone Churn Churn (%)   sum count  0 Two year 33 1280 2.578125 1 One year 120 1082 11.090573 2 Month-to-month 1231 2920 42.157534 Иначе говоря, люди редко разрывают долгосрочные телефонные контракты  HasInternetService Churn Churn (%)   sum count  0 No 82 1141 7.186678 1 DSL 342 1800 19.000000 2 Fiber optic 960 2341 41.008116 Люди с Fiber optic чаще недовольны услугами провайдера, чем остальные  Видно, что новые пользователи часто уходят после первого месяца пользования, а постоянные клиенты остаются верны привычкам.  Преобразуем категориальные признаки в тип int согласно наблюдениям. Т.е. значения «No internet service» и «No phone service» получают 0, так же, как и «No». Значения в «PaymentMethod» и «HadContractPhone» будут пронумерованы в соответствии с их корреляцией с Chern. Двоичным значениям будут присвоены 0 и 1. Теперь мы можем построить тепловую корреляционную матрицу Наконец, давайте визуализируем данные после уменьшения их размерности с помощью PCA. Мы видим, что возможно грубо разделить классы прямой линией. Так что старая добрая логистическая регрессия, вероятно, подойдет. Давайте проверим его и сравним результаты с другими алгоритмами. Для того чтобы какая-либо модель давала наилучший результат, необходимо правильно подобрать параметры модели. Обычно для этого используют GridSearchCV, который автоматически перебирает варианты параметров в некотором диапазоне. Затем мы можем посмотреть лучшие параметры для данной модели и использовать их в дальнейшем best score: 0.8451031617037706  best params: {'model__C': 1.734} Неплохой результат для прямой линии :) , давайте же посмотрим, что нам ответит Kaggle! Мдаааа, для этого соревнования явно недостаточно, давайте попробуем другие модели. KNN - это метод классификации, который основан на принципе поиска ближайших соседей, его часто применяют в различных задачах машинного обучения. Посмотрим, как он справится с задачей. и смотрим на лучшие best score: 0.8347721646087625  best params: {'model__metric': 'manhattan', 'model__n_neighbors': 44} Результат похуже, чем у логистической регрессии, посмотрим, что скажет Kaggle Да, себя мы не превзошли, но ничего, модель может нам пригодиться при использовании Stacking в будущем. Случайный лес уже представляет из себя серьезный алгоритм машинного обучения, при котором множество деревьев решений строятся на разных частях данных и их прогнозы объединяются в один окончательный прогноз. Код получился совсем небольшой, по традиции смотрим на лучшие параметры  Best score: 0.8433171488881694 Best params: {'min_samples_leaf': 18, 'min_samples_split': 9} Странно, на трейновых данных мы логистическую регрессию не превзошли А вот на Kaggle результат стал гораздо лучше! Мы даже преодолели порог 0.85! Самой сильной моделью на сегодня будет модель градиентного бустинга catboost. Модели градиентного бустинга всегда можно встретить на соревнованиях, зачастую все именно ими и ограничивается. Однако чтобы catboost показывал отличный результат, необходимо потратить тучу времени на подбор его гиперпараметров (поскольку обучаться catboost будет уже гораздо дольше остальных моделей). У модели для этого есть свой отдельный метод grid_search. И также смотрим на лучшие из них Best score: {'learn': {'AUC': 0.8542032782485164, 'Logloss': 0.39144271235447}} Best params: {'depth': 4, 'grow_policy': 'Lossguide', 'iterations': 250, 'l2_leaf_reg': 10, 'learning_rate': 0.05, 'metric_period': 1000, 'min_data_in_leaf': 100, 'random_seed': 0, 'random_strength': 5, 'subsample': 0.6} Результат даже лучше, чем у Random Forest! Посмотрим что скажет Kaggle Как говорил Павел Плесков (гранд мастер Kaggle) если вы научитесь пользоваться стейкингом, будете выигрывать любые соревнования. Суть метода заключается в том, что мы объединяем результаты работы нескольких моделей вместе, улучшая наш общий результат. Ну и, наконец, финальный результат. Барабанная дробь... Супер! Отличный результат! Лидерборд доступен по ссылке. Полный ipynb ищите тут.