Руководство по построению прогностических моделей на примерах бинарной классификации (набор данных об оттоке клиентов банка на Kaggle) с использованием библиотеки PyCaret.

1. ВВЕДЕНИЕ

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

В этой первой статье я хочу поделиться с вами своим подходом к достижению целей этого тематического исследования.

В целом в данном случае речь идет о машинном обучении с бинарным типом классификации. Немного отличаясь от общего случая, я структурировал историю с добавлением бизнес-цели. Таким образом, он нуждается в специальном лечении для достижения цели в правильном направлении.

Приятного чтения!

1.1 Предыстория

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

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

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

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

В среднем банк X будет нести комиссию в размере 250 долларов США за каждого клиента банка X с намерением расширить использование продуктов банка X. Если банк X >успешно приглашает клиентовпродлить использование продукта, тогда банк X получит среднюю прибыль в размере 800 долларов США на каждого клиента.

Поэтому меня как специалиста по данным попросили создать модель прогнозирования, чтобы преодолеть эту проблему, учитывая бизнес-цели (прибыли и убытки), которые может получить банк X.

1.2 Цель

Поисклучшей прогностической модели с точки зрения прогнозирования оттока клиентов банка с учетом бизнес-целей.

1.3 Набор данных

В этом уроке я использую набор данных Bank Customer Churn Dataset от Kaggle. Интерпретация каждого столбца (функции и цель) выглядит следующим образом.

customer_id: уникальный идентификатор, предназначенный для идентификации конкретного клиента.

credit_score: оценка, определяющая кредитоспособность клиента.

country: страна проживания клиента.

gender: пол покупателя.

age: возраст клиента.

tenure: количество лет, в течение которых у клиента был банковский счет в этом банке.

balance: сумма денег в банке клиента.

products_number: количество товаров в банке.

credit_card: определить, есть ли у клиента кредитная карта банка или нет.

active_member: является ли клиент активным членом банка.

estimated_salary: общий доход клиента.

churn: определить, перестанет ли клиент использовать продукт или нет.

2. ПОДХОД

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

2.1 Установка и импорт библиотек

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

Почему я использую PyCaret? Я лично использую PyCaret, потому что он прост в использовании и помогает ускорить циклы экспериментов, поэтому я могу работать более продуктивно.

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

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

#Install Pycaret
!pip install pycaret
#Import Libraries
import pandas as pd
import numpy as np
import plotly.express as px

from pycaret.classification import *

2.2 Загрузить набор данных

Во-вторых, загрузите набор данных и установите его как DataFrame.

#Read csv Data
data = pd.read_csv('Bank_Customer_Churn_Prediction.csv')

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

Далее давайте взглянем на образец набора данных, с которым мы будем работать.

#Print Data
data.head()

На изображении выше мы можем видеть несколько рядов наблюдений для каждой функции. Где столбец churn является целевым в этом эксперименте с классом 1 для оттока и 0 для отсутствия оттока.

Давайте проведем дальнейший анализ, чтобы получить более значимую информацию.

2.3.1 Проверка информации в каждом столбце

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

#Print Information Data Type &  # of Missing Values on Each of the Colums
data.info()

Теперь мы знаем тип данных и количество пустых значений наблюдения для каждого признака. Если мы сравним интерпретацию каждого признака с типом получаемых данных, в этом нет ничего плохого, и все результаты имеют смысл. Кроме того, для каждой функции нет пустых наблюдений. Кроме того, мы также можем получить информацию о размере матрицы используемого набора данных, который составляет 10 000 строк и 12 столбцов.

2.3.2 Расчет сводной статистики

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

#Calculates a Few Summary Statistics for Each Column
data.describe()

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

Как и в случае с функцией balance, вы можете видеть, что существует большой диапазон между максимальным и минимальным значениями. Поскольку некоторые функции имеют большой диапазон, один из экспериментов, который можно провести, — это нормализация данных перед моделированием данных.

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

2.3.3 Расчет уникальных значений для каждого столбца

Далее я хочу узнать количество уникальных значений для каждой функции.

#Print # of Unique Values for Each Column
data.nunique()

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

2.3.4 Распределение оттока

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

#Customer Churn Distribution
hist = px.histogram(data,x='churn', color = 'churn', barmode = 'group')

hist.update_layout(
    xaxis_title="Churn or No",
    yaxis_title="Count",
    font=dict(
        family="Courier New, monospace",
        size=24,
        color="RebeccaPurple"
    )
)

hist.show()

Основываясь на приведенной выше гистограмме, мы видим, что распределение классов распределено неравномерно. Класс 0 имеет значение в 3 раза больше, чем класс 1. Итак, в наборе данных наблюдается явление несбалансированных данных.

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

Поэтому для преодоления этого необходимо дальнейшее лечение.

2.4 Моделирование данных

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

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

Прежде чем перейти к тому, как это сделать. Я объясню, как создаются эти подразделы. На этапе EDA мы получили некоторую информацию.

Во-первых, имел место дисбаланс данных из-за нечетного количества каждого класса в целевом объекте.

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

Основываясь на этих двух выводах, мы можем построить 2 модели прогнозирования, а именно модель, построенную путем балансировки данных, и модель, построенную путем балансировки данных и их нормализации в первую очередь.

Я надеюсь, вы понимаете, почему на этом этапе есть другие подразделы.

2.4.1 Моделирование данных с методом исправления дисбаланса

setup — это первый и единственный обязательный шаг в любом эксперименте по машинному обучению, проводимом в PyCaret. Эта функция обрабатывает всю подготовку данных, необходимую перед обучением моделей.

В setup функция принимает 2 обязательных параметра: data и target. Я напишу дополнительный код для других нужд.

Сначала я активирую параметр fix_imbalance для решения проблем, обнаруженных на предыдущем этапе.

Во-вторых, я включаю параметр ignore_features, чтобы игнорировать функции, которые считаются бесполезными при моделировании данных.

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

Чтобы узнать больше о функциях предварительной обработки PyCaret, перейдите здесь.

#Init Setup w/ Fix Imbalance
s = setup(data, target = 'churn', fix_imbalance = True, ignore_features = ['customer_id'], session_id = 26)

После запуска приведенного выше кода PyCaret автоматически профилирует набор данных и определяет типы данных для всех входных переменных. На этом этапе вы можете проверить, верна ли отображаемая информация. Если все верно, вы можете нажать Enter, чтобы продолжить процесс моделирования данных. Вы также можете увидеть информацию о том, что для обработки дисбаланса данных PyCaret по умолчанию будет использовать метод SMOTE. Посмотрим, что будет дальше.

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

Далее я начну процесс обучения с помощью функции compare_models. Эта функция обучает и оценивает производительность всех алгоритмов, доступных в библиотеке моделей, используя перекрестную проверку.

#Compare Models
bm_fi_p = compare_models(sort = 'Recall')

Впечатляющий! К настоящему времени у вас есть несколько моделей прогнозирования с 14 различными алгоритмами. Проанализируем эти результаты.

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

Лучшей моделью, основанной на отзыве, является классификатор хребта со средним 10-кратным перекрестным подтверждением отзыва 0,7492.

На этом этапе я сортирую по максимальному значению отзыва. Я использую отзыв по двум причинам.

  1. Главный приоритет заключается в том, что машина может правильно предсказывать отток клиентов.
  2. Модель может свести к минимуму ошибки прогнозирования, когда есть подозрение, что клиенты не уходят, но факты другие.

Вопрос: «Правильный ли это путь?»

Ответ не всегда.

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

На основе упомянутого фона мы можем получить 2 важные части информации:

  1. Банк X будет платить комиссию в размере 250 долларов США за каждого клиента банка X с намерением расширить использование продуктов банка X.
  2. Если банку X удастся привлечь клиентов к расширению использования продукта, то банк X получит среднюю прибыль в размере 800 долларов США на каждого клиента.

На основе этих двух фактов я хочу составить дополнительную матрицу, а именно P&L (прибыли и убытки) с дополнительными предположениями. Эта матрица будет оценивать, сколько прибыли или убытка можно получить для каждой модели прогнозирования. Но перед этим поговорим немного о случае бинарной классификации. Результаты прогнозирования в случае бинарной классификации будут разделены на четыре возможности.

  • Истинно положительный результат ➡ Прогноз: отток, Факт: отток
  • Верно отрицательно ➡ Прогноз: оттока нет, Факт: оттока нет
  • Ложноположительный результат ➡ Прогноз:отток, Факт: отток отсутствует
  • Ложноотрицательный результат ➡ Прогноз: Нет оттока, Факт: отток

На данный момент я хочу связать два факта с возможностью в случае бинарной классификации.

Во-первых, банк X выдаст 250 долларов США при возникновении событий True-Positive и False-Negative. Это, конечно, имеет смысл.

Во-вторых, я добавлю предположения, чтобы можно было добавить 2-й факт. Предполагается, что все клиенты, которые были правильно предсказаны, будут уходить (истинно-положительный), эти клиенты не будут уходить, потому что они получают привлекательные предложения от банка X. Таким образом, банк X получит среднюю прибыль в размере 800 долларов США, потому что ему удастся удержать клиенты.

Исходя из приведенного выше описания, становится ясно, что матрица прибылей и убытков формируется из двух событий, а именно True-Positive и False-Negative. Таким образом, логично предположить, что лучшая прогностическая модель — это та, которая приносит наибольшую прибыль.

Продолжим процесс моделирования данных.

#Create a Custom Function
def calculate_pnl(y, y_pred):
  tp = np.where((y_pred==1) & (y==1), (800-250), 0)
  fp = np.where((y_pred==1) & (y==0), -250, 0)
  return np.sum([tp,fp])

#Add Metric to PyCaret
add_metric('pnl', 'P&L', calculate_pnl)
#Compare Models Fix Imbalance w/ P&L Metric
bm_fi_p = compare_models(sort = 'P&L')

Интересный! В настоящее время модель, построенная с помощью алгоритма Gradient Boosting Classifier, является лучшей моделью с прибылью и убытком в размере 34 265 долларов США. Если мы посмотрим на лучшую стоимость отзыва, полученное значение P&L составит всего 27 960 долларов США. На данный момент нам удалось увеличить прибыль (матрицу P&L) примерно более чем на 6000 долларов США.

Далее давайте построим модель, используя нормализацию данных, и исправим несбалансированные данные.

2.4.2 Моделирование данных с методом исправления дисбаланса и нормализации данных

Этот этап почти такой же, как и предыдущий, только я добавил параметр normalize.

#Init Setup Fix Imbalance & Normalization
s = setup(data, target = 'churn', normalize = True, fix_imbalance = True, ignore_features = ['customer_id'], session_id = 26)
#Create a Custom Function
def calculate_pnl(y, y_pred):
  tp = np.where((y_pred==1) & (y==1), (800-250), 0)
  fp = np.where((y_pred==1) & (y==0), -250, 0)
  return np.sum([tp,fp])

#Add Metric to PyCaret
add_metric('pnl', 'P&L', calculate_pnl)
#Compare Models Normalization & Fix Imbalance w/ P&L Metric
bm_nfi_p = compare_models(sort = 'P&L')

Невероятно, но стоимость прибылей и убытков увеличилась до 36 340 долларов США за счет добавления метода нормализации данных. По сравнению с предыдущей моделью это лучшая прогностическая модель.

2.5 Настройка модели

Далее мы поэкспериментируем с настройкой лучшей прогностической модели в надежде получить новую лучшую модель.

На данном этапе я использую параметр optimize. По умолчанию этот параметр оптимизирует матрицу точности. Удивительно, но вы также можете оптимизировать с помощью созданной матрицы (P&L).

Кроме того, я также использую параметр n_iter, чтобы увеличить количество итераций до 50.

#Tune Best Model
tuned_best_model = tune_model(bm_nfi_p, n_iter = 50, optimize = 'P&L')

Как оказалось, результаты настройки модели оказались не лучше, чем у предыдущей лучшей модели. Эта модель смогла получить только среднюю прибыль (матрица прибылей и убытков) в размере 36 160 долларов США.

2.6 Оценка модели

evaluate_model(bm_nfi_p)

С помощью приведенного выше кода вы можете оценить модель с помощью 20 типов графиков. Однако я буду оценивать только через матрицу путаницы. Основываясь на выводах, приведенных выше, мы можем получить некоторую информацию, в том числе:

  1. Модель успешно предсказывает 2165 клиентов, которые не уйдут.
  2. Модель успешно прогнозирует 379 клиентов, которые могут уйти.
  3. Модель предсказывает, что 250 клиентов уйдут, но на самом деле эти клиенты не уйдут. В этом случае Банк Х может сделать привлекательные предложения не тем людям.
  4. Модель предсказывает, что 207 клиентов не уйдут, но на самом деле они уходят. В этом случае модель не может предсказать клиентов, которые уйдут.

2.6 Сохранить модель

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

#Print Transformation Pipeline & Trained Model Object
save_model(bm_nfi_p, model_name='gbc')

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

3. ВЫВОДЫ

  1. Модель прогнозирования, построенная с использованием метода Gradient Boosting Classifier, является лучшей моделью по сравнению с 13 моделями, использующими другие методы.
  2. Лучшая модель прогнозирования имеет следующие значения точности, AUC, отзыва и точности соответственно: 0,8447, 0,8636, 0,6258 и 0,6254.
  3. Лучшая модель прогнозирования получает прогнозируемую прибыль в размере 36 340 долларов США.

4. ПРЕДЛОЖЕНИЯ

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

Теперь вы достигли конца. Надеюсь, вам понравилась эта статья!

Спасибо, что нашли время прочитать. Пожалуйста, не стесняйтесь поделиться своими выводами и оставить комментарий ниже.

Увидимся позже 👋