Фон

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

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

Цели

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

🛠️Один из способов приблизиться к прогнозированию оттока — использовать алгоритм машинного обучения, такой как машины опорных векторов (SVM), в качестве мощного алгоритма для многих задач машинного обучения. SVM считается эффективным средством прогнозирования оттока, поскольку он может обрабатывать многомерные данные и особенно полезен для наборов данных с большим количеством функций или когда данные не являются линейно разделимыми. Кроме того, SVM могут обрабатывать несбалансированные наборы данных, что часто имеет место при прогнозировании оттока, когда количество клиентов, которые уходят, намного меньше, чем количество клиентов, которые не уходят.

👥 Итак, этот проект также для всех, кто заинтересован в изучении SVM, классификации (неконтролируемого обучения) и т. д.

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

Выполнение

Загрузить пакеты

Ниже приведены основные пакеты, использованные при построении этой модели:

# data processing
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler

# data visualization
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("whitegrid")

# cross validation
from sklearn.model_selection import train_test_split

# import svm model
from sklearn import svm
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier

# import scikit-learn metrics module for accuracy calculation
from sklearn import metrics

# model optimization
from sklearn.model_selection import GridSearchCV

Загрузка данных

Источник данных, используемый для выполнения этого проекта, взят с superdatascience.com с метаданными здесь. Это набор данных клиента банка для получения информации о том, покинет ли клиент банк или нет.

# load dataset
bank_df = pd.read_csv('data_input/Churn_Modelling.csv')
bank_df

Описание данных:

  • CustomerId — содержит случайные значения.
  • Surname — фамилия покупателя.
  • CreditScore — поскольку клиент с более высоким кредитным рейтингом с меньшей вероятностью покинет банк — может повлиять на отток клиентов.
  • Geography — местонахождение клиентов может повлиять на их решение уйти из банка.
  • Gender — интересно выяснить, влияет ли пол на уход клиента из банка.
  • Age — этот фактор, безусловно, важен, потому что пожилые клиенты реже, чем молодые, покидают свой банк.
  • Tenure (лет) — количество лет, в течение которых клиент является клиентом банка. Пожилые клиенты, как правило, более надежны и с меньшей вероятностью покинут банк.
  • Balance — также очень хороший показатель оттока клиентов, так как люди с более высоким остатком на счете с меньшей вероятностью покинут банк по сравнению с теми, у кого он меньше.
  • NumOfProducts — относится к количеству продуктов, которые клиент приобрел через банк.
  • HasCrCard — указывает, есть ли у клиента кредитная карта. Эта колонка актуальна еще и потому, что люди с кредитной картой реже уходят из банка.
  • IsActiveMember — активные клиенты реже уходят из банка.
  • EstimatedSalary — как и в случае с балансом, люди с более низкой зарплатой чаще уходят из банка по сравнению с теми, у кого зарплата выше.
  • Exited — независимо от того, покинул ли клиент банк.

📈 Вывод: мы знаем, что CustomerId и Surname никак не влияют на их решение покинуть банк.

bank_df.shape
(10000, 14)

Очистка данных

Выполните проверки, чтобы увидеть все столбцы.

# print the names of the features and label (`Exited`)
bank_df.info()

Разработка функций

# check unique values to define which one is unused and must be on category type
bank_df.nunique()

Во-первых, мы знаем, что RowNumber и CustomerId имеют уникальное значение в каждой строке, и эти столбцы ничего не значат. С точки зрения бизнеса, Surname также никак не влияет на их решение покинуть банк. Мы можем бросить их!

# drop unused column
bank_df = bank_df.drop(['CustomerId', 'RowNumber', 'Surname'], axis=1)
bank_df

Изменить типы данных. Далее мы выполним разработку функций, изменив тип данных Geography, Gender на категорию.

# change into category type
cat_cols = ['Geography', 'Gender']
bank_df[cat_cols] = bank_df[cat_cols].astype('category')
bank_df.dtypes
CreditScore           int64
Geography          category
Gender             category
Age                   int64
Tenure                int64
Balance             float64
NumOfProducts         int64
HasCrCard             int64
IsActiveMember        int64
EstimatedSalary     float64
Exited                int64
dtype: object
bank_df['Geography'].cat.categories
Index(['France', 'Germany', 'Spain'], dtype='object')
bank_df['Gender'].cat.categories
Index(['Female', 'Male'], dtype='object')

Проверьте отсутствующие значения и дубликаты

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

bank_df.isna().sum()

bank_df.duplicated().sum()
0

📈 Аналитика: мы знаем, что наши данные чисты (нет пропущенных и повторяющихся значений).

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

📌 В этом разделе мы покажем некоторое распределение статистических данных для каждой переменной в наборе данных bank_df. Использование метода .describe() дает следующий результат:

bank_df.describe()

📈 Статистика:

В этой таблице мы также можем сосредоточиться на среднем значении каждого двоичного столбца (имеют только значения 0 и 1), например «HasCrCard», «IsActiveMember», «Exited». Из среднего мы можем узнать распределение данных, которые у нас есть. Пример: для HasCrCard среднее значение = 0,70, можно сказать, что 70% данных клиентов банка имеют кредитную карту. И из этого мы знаем, что масштаб в каждом столбце очень разный. Итак, возможно, в следующем процессе мы можем попробовать стандартизацию/нормализацию в зависимости от того, является ли наше распределение данных гауссовым или нет.

bank_df.describe(include='category')

📈 Статистика:

  • Числовая переменная в данных, а именно переменная Tenure, имеет в среднем 5 лет, а Age клиент в данных, взятых на этот раз, имеет диапазон от 18 до 92 лет.
  • Категориальные переменные в форме Geography, Gender являются категориальными типами данных. Так что сводка показывает только количество каждого уровня категории.
  • Что касается переменной Geography, то большая ее часть поступает из Франции, а не из Испании и Германии.
  • Большая часть собранных данных о клиентах поступает из Мале.

Проверьте переменное целевое распределение

bank_df['Exited'].value_counts().plot(kind='bar')

💡Целевая переменная Exited имеет два значения, а именно 0 и 1

  • 0 означает, что клиент не покинет банк.
  • 1 означает, что клиент, скорее всего, покинет банк.

📈 Статистика:

Самое главное, мы знаем, что наша целевая переменная Exited имеет довольно несбалансированное значение. Где клиентов, которые не уйдут из банка (7963), больше, чем тех, кто уйдет из банка (отток). Итак, позже необходимо будет провести лечение, чтобы эта несбалансированная проблема не повлияла на производительность модели.

Проверьте выбросы, используя Z-Score

num_cols = list(bank_df.columns)
for x in cat_cols:
    num_cols.remove(x)
# check outlier
fig, ax = plt.subplots(ncols=1, nrows=9, figsize=(12, 38))

i = 0
for col in num_cols:
    sns.boxplot(data=bank_df, x=col, ax=ax[i], palette='pastel')
    i = i+1

def detect_outlier(data):
    outliers = []
    threshold = 3 
    mean = np.mean(data)
    std = np.std(data)

    for y in data:
        z_score= (y - mean)/std 
        if np.abs(z_score) > threshold:
            outliers.append(y)
    return outliers
for item in num_cols:
    mean = np.mean(bank_df[f'{item}'])
    print(f'Outliers {item} : {mean}')
    outliers = detect_outlier(bank_df[f'{item}'])
    if outliers: print(outliers)

bank_df[bank_df['NumOfProducts'] == 4].head()

📈 Статистика:

Если мы проверим этот код, на самом деле эти выбросы имеют тенденцию возникать в оттоке клиентов, поэтому здесь мы решаем сохранить эти выбросы.

Горячее кодирование

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

Есть несколько причин, по которым так важно однократное кодирование:

  • Многие алгоритмы машинного обучения не могут напрямую обрабатывать категориальные данные. Они ожидают числовых входных данных, поэтому горячее кодирование — это способ преобразования категориальных данных в числовую форму, которую могут использовать эти алгоритмы.
  • Горячее кодирование помогает предотвратить смещение модели. Без горячего кодирования категориальная переменная с тремя категориями (например, Испания, Германия и Франция) была бы представлена ​​как три отдельные числовые переменные, каждая со значениями в диапазоне от 0 до 1, со значением 1, указывающим на наличие этой категории. и значение 0 указывает на отсутствие этой категории.

Итак, по этой причине мы будем сразу кодировать переменные Gender и Geography.

bank_df = pd.get_dummies(bank_df, columns = cat_cols)
bank_df.head()

Корреляция переменных-предикторов с целевыми переменными

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

corr = bank_df.corr()
f, ax = plt.subplots(figsize=(10, 8))
sns.heatmap(corr, annot=True, fmt=".2f", cmap='YlGnBu')
plt.show()

churn_corr = corr[['Exited']]
sns.heatmap(churn_corr, annot=True,  fmt=".2f", cmap='YlGnBu')

📈 Статистика:

На графике выше показана корреляция между потенциальным оттоком клиентов и столбцами. Столбец с высокой корреляцией указывает на то, что столбец оказывает большое влияние на потенциальный отток. 3 столбца, которые больше всего влияют на потенциальный отток: Age (0,29), Geography_Germany (0,17) и IsActiveMember (-0,16 как отрицательная корреляция).

Затем будут выбраны столбцы с высокой корреляцией с потенциальным оттоком, в этом случае столбцы с корреляцией выше/ниже 0,1 — это объекты, которые будут поддерживаться в качестве входных данных из исследуемой модели.

Число 0,1 является субъективным выбором кодировщика, при желании вы можете определить другие числа/пороги, которые считаются влиятельными

high_corr = churn_corr[abs(churn_corr['Exited']) >= 0.1]
high_corr.sort_values(by='Exited', ascending=False)

high_corr_columns = list(high_corr.index)
high_corr_columns.remove('Exited')
high_corr_columns

Визуализируйте данные

# check age distribution
sns.histplot(bank_df, x='Age', hue='Exited')

📈 Вывод:из этого графика мы знаем, что распределение по возрасту показывает разницу между теми, у кого есть потенциальный отток (1), и теми, у кого оттока нет (1). Доминирование класса 0 в молодом возрасте (20–50 лет) не имеет потенциала оттока, тогда как возраст распределения класса 1, как правило, самый старший (около 40–60 лет).

# check geography distribution
fig, ax = plt.subplots(ncols=3, figsize=(14, 4))
idx = 0
for col in bank_df.columns:
    if 'Geography' in col: 
        sns.histplot(bank_df, x=col, hue='Exited', ax=ax[idx])
        idx += 1

📈 Вывод:Основываясь на приведенном выше графике, мы можем сделать вывод, что люди из Германии и Испании, как правило, не уходят.

# check geography distribution
fig, ax = plt.subplots(ncols=2, figsize=(14, 4))
idx = 0
for col in bank_df.columns:
    if 'Gender' in col: 
        sns.histplot(bank_df, x=col, hue='Exited', ax=ax[idx])
        idx += 1

📈 Вывод: На самом деле пол не влияет на то, уходят люди или нет, но если мы попытаемся сосредоточиться на небольших различиях в данных, мы узнаем, что женщины склонны уходить, и наоборот.

# check balance distribution
sns.histplot(bank_df, x='Balance', hue='Exited')

📈 Вывод: поскольку распределение почти нормальное для классов 0 и 1, баланс не имеет сильной связи с оттоком или нет.

# check IsActiveMember distribution
sns.histplot(bank_df, x='IsActiveMember', hue='Exited')

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

Основываясь на всем этом, мы попробуем high_corr_columns для сценария после попытки построить модель для всех столбцов.

Разделить данные тренировочного теста

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

Общее эмпирическое правило состоит в том, чтобы выделить 70–80% данных для обучения, а оставшиеся 20–30% — для тестирования. Это разделение позволяет модели учиться на большой части данных, но при этом иметь достаточное количество данных для оценки ее производительности.

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

df = bank_df.copy()
X_raw = df.drop(columns=['Exited'])

X = X_raw.values
y = df['Exited'].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print('Train - X:', X_train.shape, ' y:', y_train.shape)
print('Test - X:', X_test.shape, ' y:', y_test.shape)
Train - X: (8000, 13)  y: (8000,)
Test - X: (2000, 13)  y: (2000,)

Необязательно: подготавливает idx столбцов для эксперимента, если берутся только столбцы с высокой корреляцией.

idx_high_corr_columns = [X_raw.columns.get_loc(c) for c in high_corr_columns if c in X_raw]
idx_high_corr_columns
[1, 3, 6, 8, 9, 11, 12]

Данные стандартизации

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

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

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

# in this case we know that range each columns is different
pd.DataFrame({
    'columns': bank_df.columns,
    'min': list(bank_df.min()),
    'max': list(bank_df.max())
}).sort_values(by='min')

# because of that we need to try scaled this data
ss = StandardScaler()

X_train_ss = ss.fit_transform(X_train)
X_test_ss = ss.fit_transform(X_test)

✨ Дополнительно: стандартизация и нормализация

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

Нормализация – это процесс масштабирования характеристик набора данных до определенного диапазона, обычно от 0 до 1. Обычно он используется, когда характеристики набора данных имеют гауссово распределение (гауссова кривая) или когда объекты имеют разные единицы измерения (например, рост в дюймах и вес в фунтах). Нормализация выполняется путем вычитания среднего значения признака из каждой точки данных и последующего деления результата на стандартное отклонение признака. Это масштабирует функцию, чтобы иметь среднее значение 0 и стандартное отклонение 1.

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

Построение модели

Машина опорных векторов

Машины опорных векторов (SVM) — это тип алгоритма обучения с учителем, который можно использовать для классификации. Учитывая набор помеченных обучающих данных, алгоритм SVM строит модель, которая присваивает новые точки данных одной из двух категорий, что делает его невероятностным бинарным линейным классификатором.

# create a svm Classifier
svc = svm.SVC(kernel='linear') # linear kernel

# train the model using train dataset
svc.fit(X_train, y_train)

# predict the churn for test dataset
y_pred = svc.predict(X_test)

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

# model accuracy
svc_acc = metrics.accuracy_score(y_test, y_pred)
print("Accuracy Train:", metrics.accuracy_score(y_train, svc.predict(X_train)))
print("Accuracy Test:", svc_acc)
Accuracy Train: 0.779125
Accuracy Test: 0.7925

❓Что бы мы построили модель с масштабированными данными? Так намного лучше?

# create a svm Classifier
svc_ss = svm.SVC(kernel='linear') # linear kernel

# train the model using the train data
svc_ss.fit(X_train_ss, y_train)

# predict the churn for test dataset
y_pred_ss = svc_ss.predict(X_test_ss)
# model accuracy
svc_ss_acc = metrics.accuracy_score(y_test, y_pred_ss)
print("The Model Trained with Scaled Data")
print("Accuracy Train:", metrics.accuracy_score(y_train, svc_ss.predict(X_train)))
print("Accuracy Test", svc_ss_acc)
The Model Trained with Scaled Data
Accuracy Train: 0.70375
Accuracy Test 0.8035

📈 Статистика:

Время запуска модели SVC слишком велико: на 13 минут больше, чем SVC с использованием масштабированных данных (всего менее 1 минуты). Мы также знаем, что использование масштабированных данных может уменьшить временную сложность и повысить точность (1,1%).

Оптимизация модели

Необязательно:

Несмотря на то, что мы знаем, что масштабированные данные работают быстрее (поскольку временная сложность уменьшается), мы замечаем, что разница в значениях точности между обучением и тестированием на модели с масштабированными данными составляет почти 10%. Итак, давайте посмотрим, что произойдет, если мы будем использовать только функции с высокой корреляцией!

X_train_ss_hc = X_train_ss[:,idx_high_corr_columns]
X_test_ss_hc = X_test_ss[:,idx_high_corr_columns]
# create a svm Classifier
svc_selected = svm.SVC(kernel='linear') # linear kernel

# train the model using the train data
svc_selected.fit(X_train_ss_hc, y_train)

# predict the churn for test dataset
y_pred_selected = svc_selected.predict(X_test_ss_hc)
# model accuracy
svc_selected_acc = metrics.accuracy_score(y_test, y_pred_selected)
print("The Model Trained with Scaled Data & Only High Correlation Features")
print("Accuracy Train:", metrics.accuracy_score(y_train, svc_selected.predict(X_train_ss_hc)))
print("Accuracy Test", svc_selected_acc)
# 0.8035
The Model Trained with Scaled Data & Only High Correlation Features
Accuracy Train: 0.7945
Accuracy Test 0.8035

📈 Статистика:

Оказывается, если мы используем функции с высокой корреляцией, точность модели поезда увеличивается, предотвращая ее переоснащение. Поскольку ранее точность модели поезда составляла всего 70%,

Гиперпараметр SVM

Есть несколько параметров, которые можно настроить при обучении модели SVC:

  • C: это параметр штрафа за неправильно классифицированные обучающие примеры. Большее значение C соответствует более строгому штрафу (жесткому пределу), что означает, что модель будет прилагать больше усилий, чтобы избежать неправильной классификации любых обучающих примеров.
  • kernel: Этот параметр указывает тип ядра, которое будет использоваться в модели. Общие варианты включают линейное ядро, полиномиальное ядро ​​и ядро ​​радиальной базисной функции (RBF).
  • gamma: Этот параметр используется для определения коэффициента ядра для ядра RBF и полиномиального ядра. Он контролирует ширину ядра и определяет, какое влияние на модель оказывает каждый обучающий пример.
# create a svm Classifier
svc_optimized = svm.SVC(C=0.1, kernel='rbf', gamma=0.1) # linear kernel

# train the model using the train data
svc_optimized.fit(X_train_ss_hc, y_train)

# predict the churn for test dataset
y_pred_optimized = svc_optimized.predict(X_test_ss_hc)
# model accuracy
svc_optimized_acc = metrics.accuracy_score(y_test, y_pred_optimized)
print("The Model Optimized SVM")
print("Accuracy Train:", metrics.accuracy_score(y_train, svc_optimized.predict(X_train_ss_hc)))
print("Accuracy Test", svc_optimized_acc)
The Model Optimized SVM
Accuracy Train: 0.826
Accuracy Test 0.827

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

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

grid_params = {'C':[0.1,1,10],
               'gamma':[1,0.1,0.001],
               'kernel':['linear','rbf']}

svc_model = svm.SVC()
model_grid = GridSearchCV(svc_model, grid_params)
model_grid.fit(X_train_ss_hc, y_train)
GridSearchCV(estimator=SVC(),
             param_grid={'C': [0.1, 1, 10],
                         'gamma': [1, 0.1, 0.001],
                         'kernel': ['linear', 'rbf']})
model_grid.best_params_
{'C': 1, 'gamma': 1, 'kernel': 'rbf'}
# predict the churn for test dataset
y_pred_grid = model_grid.predict(X_test_ss_hc)

# model accuracy
grid_acc = metrics.accuracy_score(y_test, y_pred_grid)
print("SVM {'C': 1, 'gamma': 1, 'kernel': 'rbf'}")
print("Accuracy Train:", metrics.accuracy_score(y_train, model_grid.predict(X_train_ss_hc)))
print("Accuracy Test", grid_acc)
SVM {'C': 1, 'gamma': 1, 'kernel': 'rbf'}
Accuracy Train: 0.843
Accuracy Test 0.839

⚠️ Хотя машины опорных векторов (SVM) эффективны при поиске гиперплоскости, которая максимально разделяет различные классы в многомерных пространствах признаков, они не предназначены для создания удобочитаемых правил, которые можно легко интерпретировать.

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

Попробуйте другую модель (интерпретируемую)

Древо решений

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

# we will use original data because we want to interpreted this
X_train_hc = X_train[:, idx_high_corr_columns]
X_test_hc = X_test[:, idx_high_corr_columns]
dtree = DecisionTreeClassifier(criterion="entropy", max_depth=3)
dtree = dtree.fit(X_train_hc, y_train)
# plot tree
plt.figure(figsize=(12,12))  # set plot size (denoted in inches)
tree.plot_tree(dtree, fontsize=10, feature_names=high_corr_columns)
plt.show()

# predict the churn for test dataset
y_pred_dtree = dtree.predict(X_test_hc)

# model accuracy
dtree_acc = metrics.accuracy_score(y_test, y_pred_dtree)
print("Decision Tree")
print("Accuracy Train:", metrics.accuracy_score(y_train, dtree.predict(X_train_hc)))
print("Accuracy Test", dtree_acc)
Decision Tree
Accuracy Train: 0.82525
Accuracy Test 0.829

Заключение

  • Основываясь на результатах EDA, на решение клиента банка об оттоке или отказе от него сильное влияние оказывают следующие характеристики: «Возраст», «Баланс», «Активный член», «География» и «Пол». Где клиенты, которые уходят, как правило, женщины, а география не немецкая и не испанская.
  • Затем, на основе построения модели, модель SVM с наилучшей точностью — это та, которая использует масштабированные данные и выбирает только функции с высокой корреляцией, с оценкой точности 0,839 (тест) и 0,843 (поезд).
  • Если мы хотим понять процесс принятия решений в модели машинного обучения и извлечь явные правила, которые можно легко интерпретировать, одним из вариантов является использование дерева решений. Основываясь на модели дерева решений, мы знаем, что возраст является определяющим фактором, который действительно определяет решение об оттоке или нет, а затем география и IsActiveMember. Возможно, возраст, безусловно, важен, потому что пожилые клиенты реже, чем молодые, покидают свой банк.

💡 Важные примечания. Использование масштабированных данных и выбора признаков может быть полезным при обучении модели метода опорных векторов (SVM).

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

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

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

Будущее улучшение

Как мы знаем, недостатком SVM является то, что ему приходится обрабатывать данные с большим количеством строк, что может привести к снижению точности.

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

Ссылка