Решение реальной проблемы науки о данных от kaggle, которое входит в 1% лучших в конкурсе

1. Постановка проблемы

Ничто так не испортит острые ощущения от покупки нового автомобиля, как просмотр нашего нового страхового счета. Укус становится еще более болезненным, когда ты знаешь, что хороший водитель. Кажется несправедливым, что вам нужно платить так много, если вы годами осторожничали в дороге.

С этим полностью согласна одна из крупнейших бразильских компаний по страхованию автомобилей и домовладельцев Porto Seguro. Неточности в прогнозах страховых компаний по страхованию автомобилей увеличивают стоимость страховки для хороших водителей и снижают цену для плохих.

В этом соревновании вам предстоит построить модель, которая прогнозирует вероятность того, что водитель подаст иск о автостраховании в следующем году. Более точный прогноз позволит им еще больше адаптировать свои цены и, надеюсь, сделает автострахование более доступным для большего числа водителей.

2. Сопоставление реальной проблемы с проблемой машинного обучения.

2.1 Тип задачи машинного обучения

  • Есть два разных класса, по которым нам нужно классифицировать данную точку данных. Следовательно, проблема заключается в проблеме двоичной классификации вероятностей того, что отдельное лицо подаст иск.

2.2 Показатели производительности

  • Показатель: нормализованный коэффициент Джини
  • Во время подсчета очков наблюдения сортируются от самых больших до самых маленьких прогнозов. Прогнозы используются только для упорядочивания наблюдений; поэтому относительная величина прогнозов не используется во время оценки. Затем алгоритм подсчета очков сравнивает совокупную долю положительных наблюдений за классом с теоретической однородной долей.
  • Коэффициент Джини колеблется от приблизительно 0 для случайного предположения до приблизительно 0,5 для высшей оценки. Теоретический максимум для дискретного расчета (1 - frac_pos) / 2.
  • Нормализованный коэффициент Джини регулирует оценку на теоретический максимум, так что максимальная оценка равна 1.

Интуитивное объяснение коэффициента Джини:

  • Мы берем прогнозы и фактические значения и сортируем их в порядке убывания:
Actual Values = [1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Sorted Actual = [1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0]
  • Теперь мы подсчитываем количество замен соседних цифр (как в пузырьковой сортировке), которое потребуется для перехода из состояния «Фактическая сортировка» в состояние «Фактические значения». В этом случае потребуется 10 свопов.
  • Мы также рассчитываем количество свопов, которые в среднем потребуются для перехода из случайного состояния в состояние «Фактические значения». С 6 единицами и 9 нулями получается (6 * 9) / 2 = 27 свопов.
  • Нормализованный коэффициент Джини - это то, насколько далеко наши отсортированные фактические значения от случайного состояния, измеряемого количеством обменов:
  • N_Gini = (swaps_random − swaps_sorted) / (swaps_random) = 63%
  • Более подробные объяснения коэффициента Джини можно найти здесь и здесь.

2.3 Цель ML

  • Учитывая различные сведения о держателе полиса автострахования, необходимо создать модель, которая прогнозирует вероятность того, что держатель подаст иск. Вероятности предсказания - это те, которые необходимы.

2.4 Обзор данных

  • Источник: https://www.kaggle.com/c/porto-seguro-safe-driver-prediction/data
  • В обучающих и тестовых данных функции, принадлежащие к аналогичным группам, помечаются как таковые в именах функций (например, ind, reg, car, calc). Кроме того, имена функций включают постфикс bin для обозначения двоичных функций и cat для обозначения категориальных функций. Элементы без этих обозначений являются либо непрерывными, либо порядковыми. Значения -1 указывают на то, что особенность отсутствовала в наблюдении. Столбцы target показывают, подавалось ли требование для этого держателя полиса.

3. Исследовательский анализ данных

Модель, которую мы построим, будет хороша ровно настолько, насколько хороши данные, которые мы в нее введем. Тщательный анализ данных позволяет глубоко изучить наши данные и извлечь из них ценную информацию. Итак, правильный EDA становится критическим шагом в любой проблеме машинного обучения.

  • Набор данных поезда состоял из 59 переменных, включая «ID» и «Target». Таким образом, в наборе данных всего 57 функций, которые можно использовать для прогнозирования. Все 57 функций анонимны по соображениям конфиденциальности. Названия функций указывают, что это за функции:
  • Функция с «bin» представляет собой двоичную функцию.
  • Характеристика со словом «кошка» представляет собой категориальную характеристику.
  • Функция с «calc» представляет собой дополнительную вычисляемую функцию.
  • Отдых постоянный
  • Значения -1 представляют собой пропущенные значения, о которых уже сообщалось в обзоре данных.

Для облегчения интерпретации и удобочитаемости мы разделим эти функции на разные части и выполним EDA для каждой части отдельно.

  • Набор данных сильно несбалансирован, что говорит о том, что большинство держателей страховых полисов не подают претензии. Таким образом, это становится проблемой несбалансированной двоичной классификации.

3.1 EDA двоичных функций

Матрица корреляции, представленная в виде тепловой карты, становится отличным инструментом визуализации для определения корреляции между переменными. Высокое положительное значение указывает на сильную положительную корреляцию, а низкое отрицательное значение указывает на сильную отрицательную корреляцию.

  • Между бинарными функциями нет заметной корреляции. Функции «ps_ind_18_bin» и «ps_ind_16_bin» имеют наибольшую отрицательную корреляцию, но не вызывают особого беспокойства.

  • Было замечено, что двоичные функции не имеют пропущенных значений.

  • За исключением нескольких расчетных характеристик, в большинстве бинарных функций преобладает одно значение.
  • Некоторые двоичные функции, такие как «ps_ind_10_bin», «ps_ind_11_bin», «ps_ind_12_bin», «ps_ind_13_bin» вообще не учитывают положительный класс, тогда как для большинства функций calc нули и единицы почти одинаково учитывают как положительный, так и отрицательный класс.

3.2 EDA категориальных характеристик

  • Признак «ps_car_11_cat» выделяется среди категориальных характеристик, поскольку он имеет наивысшую мощность. В остальном все функции имеют относительно низкую мощность.

Даже категориальные признаки не имеют между собой заметной корреляции.

  • Category_features содержат некоторые пропущенные значения. Позже можно найти способ восполнить эти недостающие значения.
  • Большая часть функций «ps_car_03_cat» и «ps_car_05_cat» состоит из пропущенных значений. Для этих функций вместо заполнения отсутствующих значений их можно рассматривать как отдельную категорию.

  • Некоторые функции, такие как «ps_ind_05_cat» и «ps_car_04_cat», в основном состоят из одного значения. Поэтому режим этих функций можно использовать для заполнения их пропущенных значений.
  • Пропущенные значения каждого из категориальных признаков можно заполнить следующим образом:

1. ps_ind_02_cat - - ›mean
2. ps_ind_04_cat - -› mean
3. ps_ind_05_cat - - ›режим
4. ps_car_01_cat - -› mean
5. ps_car_02_cat - - › означает
6. ps_car_03_cat - - ›можно рассматривать как отдельную категорию
7. ps_car_05_cat - -› можно рассматривать как отдельную категорию
8. ps_car_07_cat - - ›режим
9. ps_car_09_cat - - ›среднее

  • Для этих функций можно попробовать различные методы кодирования, такие как OHE, целевое кодирование, кодирование меток. Среди них можно выбрать наиболее эффективную кодировку.

3.3 EDA непрерывных функций

Непрерывные функции могут быть далее разделены на calc и остальные. Их обоих можно рассматривать по отдельности.

3.3.1 Непрерывные функции без расчета:

  • Большинство функций, таких как «ps_reg_01», «ps_car_11» и т. Д., Содержат лишь небольшое количество уникальных значений.
  • В таких функциях, как «ps_reg_01», «ps_car_11» и «ps_ind_14» преобладает одно значение.
  • Недостающие значения в этом наборе функций можно заполнить соответствующими средними значениями.

  • Разницу между распределениями значений каждой функции относительно меток классов можно увидеть на приведенном выше графике. Приведенный выше график показывает, насколько хорошо функция может отличать метки классов друг от друга.
  • Хотя особенности, похоже, не демонстрируют сильно различающихся закономерностей для двух классов, есть небольшие различия в асимметрии, которые могут помочь в разделении обоих классов.
  • Например, такие функции, как «ps_ind_01», «ps_reg_02», «ps_ind_03», «ps_car_13», имеют разные перекосы и распределение данных для обоих классов. Эти функции могут оказаться ценными при определении окончательного результата.
  • В частности, «ps_reg_02» имеет заметную разницу в средних значениях и распределении для обоих классов.

3.3.2 Непрерывные функции с calc:

  • Функции «ps_calc_03», «ps_calc_01», «ps_calc_02» распределены равномерно.
  • Некоторые другие функции, такие как «ps_calc_07», «ps_calc_14», «ps_calc_11», «ps_calc_10», похоже, распределены по Гауссу.

  • За исключением «ps_calc_02», нет никакой разницы между двумя распределениями классов ни в одной из функций calc. Никакая ценная информация не предоставляется ни одной из функций calc. Как было предложено в обсуждениях kaggle, эти функции не дают никакой информации для прогноза. Они просто кажутся случайными. Поэтому их можно просто исключить из нашего обучения.

3.4 Добавление слова «отсутствует»

  • Поскольку функции наших данных анонимны по различным причинам конфиденциальности, разработка функций на основе домена в этом случае невозможна. Но все же можно попробовать различные другие преобразования, такие как математические преобразования, для функций, но это просто вопрос удачи, работают они или нет. Я попробовал несколько комбинаций, но они оказались безрезультатными.
  • Но что сработало, так это добавление функции «отсутствует», которая состоит из количества пропущенных значений в соответствующей точке данных. Мы увидим важность этой функции в следующих разделах.

3.5 Разделение на данные Train и CV

  • Теперь мы разделим файл train.csv на 2 части: одну для обучения, а другую - для перекрестной проверки. Наш train.csv содержит 595212 точек данных, поэтому разделение на 80–20 кажется подходящим. С этим разделением у нас все еще будет достаточно данных для обучения и достаточно больших данных для гипер-настройки параметров нашей модели.
  • Поскольку наши данные сильно несбалансированы, мы выполним стратифицированное разделение нашего набора данных. Это сохранит процент сэмплов для нашего разделения. Предсказания нестратифицированного разделения не сохранят исходное распределение нашего целевого класса. Поэтому несбалансированный набор данных следует разбивать стратифицированным образом.

3.6 Обработка категориальных функций

  • Модели машинного обучения могут иметь дело только с числами. Часто наши данные содержат как числовые, так и категориальные данные. Таким образом, категориальные данные должны быть правильно закодированы, чтобы их можно было использовать в модели машинного обучения. Существуют различные методы категориального кодирования, такие как One-Hot-Encoding, целевое кодирование, кодирование меток и т. Д. Мы должны экспериментально определить, какой метод кодирования лучше всего подходит для наших моделей. Все вышеупомянутые методы были опробованы для решения этой проблемы, и было обнаружено, что One-Hot-Encoding является наиболее эффективным. Код Python для всех вышеупомянутых методов можно найти в моем репозитории GitHub, ссылка на который указана в конце этого блога.

ОДНО ГОРЯЧЕЕ КОДИРОВАНИЕ:

  • Тем, кто не знаком с термином OHE, следующий пример пояснит вам:

  • В OHE категориальная функция удаляется, а новые двоичные функции добавляются в зависимости от количества уникальных значений в категориальной переменной. На приведенной выше диаграмме категориальный признак «цвет» состоит из 3 уникальных значений, поэтому требуются 3 новых двоичных признака.
  • «1» помещается в соответствующую строку его цвета, а остальные значения делаются «0».
  • Все методы кодирования выполняются с данными поезда, чтобы избежать проблемы утечки данных. Имейте в виду, что тестовые данные - это то, чего мы раньше не видели, поэтому их следует хранить в таком виде. Теперь я уверен, что вы понимаете, что такое OHE.

3.7 Обработка числовых характеристик

  • Как и категориальные признаки, наши числовые признаки также должны быть должным образом предварительно обработаны. Они могут иметь разную величину, и независимо от их единицы наши модели машинного обучения могут интерпретировать большие значения как более высокие, а меньшие значения как более низкие.
  • Например: модель может считать значение 1000 метров выше и 10 км ниже, что не так.
    Для этой единственной цели Sklearn имеет несколько встроенных библиотек. Их можно использовать для масштабирования наших числовых данных.
  • StandardScaler - одна из тех библиотек, которые масштабируют наши данные до диапазона (-1,1).

4. Моделирование

  • После тщательного EDA и предварительной обработки наши данные готовы для загрузки в модель машинного обучения. Модель также должна быть правильно настроена для получения наилучших результатов. Иногда для решения проблемы требуются сложные модели, но иногда простая модель делает работу за вас. Следовательно, необходимо экспериментально увидеть, какая модель работает лучше всего. Сначала мы начнем с простых моделей, а позже перейдем к другим мощным моделям.
  • Вся настройка гиперпараметров для моделей ниже была выполнена вручную из-за вычислительных затрат GridSearchCV или RandomSearchCV. Также ручная настройка позволила лучше понять, как модель ведет себя при небольших изменениях параметров. Приведенные ниже фрагменты кода - это только заключительные этапы процесса настройки. Доступ ко всему коду можно получить из репозитория GitHub.

4.1 Логистическая регрессия

После настройки гиперпараметров наилучший показатель Джини (CV), который могла получить модель логистической регрессии, был: 0,25822158048351057
, что не было чем-то особенным.

4.2 SVM

SVC произвел индекс Джини (CV): 0,1540707231858662.

4.3 Классификатор случайного леса

Итоговый коэффициент Джини (CV) классификатора РФ: 0,26515156130314593

4.4 Классификатор XGB

XGBoost с правильной настройкой гиперпараметров был одной из лучших моделей для решения этой проблемы. Позже он также оказался ценным дополнением к стеку.

Показатель Джини (CV), полученный XGBClassifier: 0,29294034525041907
, что значительно выше по сравнению с другими моделями.

4.5 Классификатор LightGBM

Оценка Джини (CV), полученная LGBMclassifier: 0,2924098617221834

XGBoost и LightGBM были лучшими моделями из наших экспериментов. Эти две были взяты в качестве базовых моделей для моей индивидуальной реализации стека, которая использовалась для окончательного результата. Посмотрим, как это сделать.

4.6 Выбор функций

  • Этот шаг позволяет нам удалить объекты из набора данных, которые не дают никакой ценности в прогнозировании для конкретной модели. Это, в свою очередь, увеличивает скорость вычислений, а также может повысить производительность нашей модели.
  • Все функции, у которых feature_importance равнялось 0, были удалены, а остальные функции сохранены. Это помогло улучшить общие характеристики модели.

4.6.1 Важность функции XGB:

selected_features_xgb = feature_selection(xgb_model.feature_importances_, features, 0)

4.6.2 Важность функции LightGBM:

selected_features_lgb = feature_selection(lgb_model.feature_importances_, features, 0)

  • После всех этапов предварительной обработки данные имели в общей сложности 208 функций. Исходя из этого, модели XGBoost и LightGBM выбрали 134 и 169 функций соответственно. Как видно из диаграмм, обе модели имели хорошее значение feature_importance для дополнительной «отсутствующей» функции, которую мы добавили. Так что это было хорошим дополнением.

4.7 Пользовательский стек

  • Это последний кусок нашей головоломки. Две базовые модели, которые мы обсуждали выше, использовались для построения стека и модели LogisticRegression в качестве meta_classifier.
  • Для каждой базовой модели использовались только элементы, выбранные в процессе выбора. Это помогло улучшить окончательную оценку модели.
  • Стандартная библиотека не использовалась для этого стека, потому что они не допускают таких настроек.

5. Результаты

  • Из всех моделей LightGBM была лучшей, после XGBoost. Таким образом, эти двое вошли в финальную стопку. Рекомендуется сначала попробовать простые модели, но в данном случае они не сработали.

Окончательная оценка заявки:

  • Этот результат позволяет вам попасть в 1% лидеров турнирной таблицы с точным рейтингом 32.

6. Резюме

  • Наряду с вышеупомянутыми моделями в таблице были также опробованы другие модели, такие как логистическая регрессия, случайные леса, SVM, которые оказались неэффективными для этой проблемы.
  • Различные категориальные кодировки, такие как целевое кодирование, частотное кодирование, кодирование меток, также были опробованы в комбинации. Хотя целевое кодирование вначале выглядело многообещающим, One Hot Encoding дало лучший результат.
  • Отдельный выбор функций для двух базовых моделей еще больше повысил оценку.

7. Улучшения существующих решений

  • Большинство лучших решений этой проблемы включали глубокое обучение или набор из 10–15 моделей. В частности, нейросети дали высокие баллы конкурентам. Я хотел решить эту проблему без использования глубокого обучения. Я не только смог набрать высокий балл, но и использовал всего 2 базовые модели.

8. Будущая работа

  • Как указано выше, для создания этого решения не использовались нейронные сети. Так что в качестве объема будущей работы их можно использовать для получения лучших результатов.
  • Добавление любой другой базовой модели может увеличить оценку.

9. Заключение

  • Да, теоретические знания - это хорошо, но пока вы не примените их на практике, вы не получите представления о том, как все работает в практическом мире. По той же причине для меня это был прекрасный опыт работы над этим проектом. Он провел меня через различные этапы разработки проекта и дал мне настоящее представление о мире машинного обучения. Мне удалось многое узнать на своем пути, и я все еще с нетерпением жду возможности узнать еще много нового в будущем.
  • Вы можете посмотреть полный код этого проекта в моей учетной записи GitHub здесь.

10. Ссылки

  1. Https://www.kaggle.com/bertcarremans/data-preparation-exploration
  2. Https://www.kaggle.com/c/porto-seguro-safe-driver-prediction/discussion/44629
  3. Https://www.kaggle.com/c/porto-seguro-safe-driver-prediction/discussion/44579#250558
  4. Https://www.youtube.com/watch?v=mbxZ_zqHV9c
  5. Https://www.appliedaicourse.com/

Вы также можете связаться со мной в LinkedIn

Надеюсь, вам понравился этот проект. Спасибо за чтение !!