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

Оглавление

  1. Прием данных
  2. Исследовательский анализ данных
  3. Предварительная обработка данных
  4. Обучение модели
  5. Тестирование модели
  6. Вывод
  7. Кредиты

1. Прием данных

1.1 Введение

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

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

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

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

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

Спасибо Калифорнийскому университету в Ирвине за предоставление набора данных.

Источник:

[Moro et al., 2014] С. Моро, П. Кортес и П. Рита. Подход, основанный на данных, для прогнозирования успеха банковского телемаркетинга. Системы поддержки принятия решений, Elsevier, 62:22–31, июнь 2014 г..

1.2 Понимание данных

  • Работа. Категория работы, к которой принадлежит клиент. (категория: «админ», «синий воротничок», «предприниматель», «домработница», «управление», «пенсионер», «самозанятый», «услуги», «студент», «техник», «безработный»
  • семейное: семейное положение клиента (категория: «разведен», «женат», «холост», «неизвестно»; примечание: «разведен» означает разведенный или овдовевший).
  • образование: уровень образования клиента (категория: "базовый.4 года", "базовый.6 лет", "базовый.9 лет", "высшая.школа", "неграмотный", "профессиональный.курс", 'университетская.степень','неизвестно')
  • по умолчанию: является ли клиент неплательщиком? (категоричные: «нет», «да», «неизвестно»)
  • баланс: общая сумма баланса клиента.
  • жилье. Есть ли у клиента жилищная ссуда? (категоричные: «нет», «да», «неизвестно»)
  • кредит: есть ли у клиента личный кредит? (категоричные: «нет», «да», «неизвестно»)

Связан с последним контактом текущей кампании.

  • контакт: тип связи с клиентом (категория: «сотовый», «телефон»).
  • день: последний день, когда с клиентом связались. (числовые: 1, 2, 3, … 31)
  • месяц: последний месяц, когда с клиентом связывались (категория: 'январь', 'февраль', 'март', …, 'ноябрь', 'декабрь')
  • duration: продолжительность последнего контакта с клиентом в секундах (числовое). Важное примечание: этот атрибут сильно влияет на цель вывода (например, если продолжительность = 0, то целевая переменная y = «нет», т. е. клиент не подписался). Тем не менее, в практическом сценарии продолжительность неизвестна до выполнения вызова. Также после окончания звонка заведомо известно y, т.е. подписался ли клиент. Таким образом, эти входные данные должны быть включены только для целей сравнительного анализа и должны быть отброшены, если намерение состоит в том, чтобы иметь реалистичную прогностическую модель.

Другие атрибуты

  • кампания: количество клиентов, с которыми связались во время этой кампании (число, включая последний контакт).
  • дней: количество дней, прошедших с момента последнего контакта с клиентом из предыдущей кампании (числовое значение; 999 означает, что с клиентом ранее не связывались).
  • предыдущий: количество контактов, выполненных до этой кампании и для банка (числовое).
  • результат: результат предыдущей маркетинговой кампании (категория: «неудача», «несуществующий», «успех»). Выходная переменная (желаемая цель)
  • y: это целевая переменная. Определяет, подписались ли клиенты на срочный депозитный продукт (для которого запущена акция)? (двоичный: «да», «нет»)

1.3 Статистический анализ

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

# ignore warnings
import warnings 
warnings.filterwarnings(’ignore’)

Теперь давайте импортируем необходимые библиотеки. Библиотека pandas используется для удобного управления фреймом данных и Seaborn, Matplotlib используется для визуализации.

# importing the required libraries
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

Выполнение статистического анализа полей в наборе данных.

# statistical description of the fields
df_bank.describe()

Результатами являются 7 числовых переменных и 10 категориальных переменных. Мы должны сначала преобразовать категориальные переменные в числовые, чтобы продолжить анализ.

# checking for null data
print ("Presence of any null values: " +
     str(df_bank.isnull().values.any()))

Мы видим, что в наборе данных нет нулевых значений.

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

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

# Checking customer base i.e clients of the bank 
fig = plt.figure(figsize=(15,15)) 
plt.subplot(2,3,1) 
pd.value_counts(df_bank[’education’]).plot.bar() plt.title(’EDUCATION’) 
plt.subplot(2,3,2) 
pd.value_counts(df_bank[’poutcome’]).plot.bar() 
plt.title(’OUTCOME’) 
plt.subplot(2,3,3) 
pd.value_counts(df_bank[’contact’]).plot.bar() 
plt.title(’CONTACT’) 
plt.subplot(2,3,4) 
pd.value_counts(df_bank[’job’]).plot.bar() 
plt.title(’JOB’) 
plt.axis(’tight’) 
plt.show()

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

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

# Analyzing the customer base using bar graphs
fig = plt.figure(figsize=(15,15))
plt.subplot(2,3,1)pd.value_counts(df_bank[’month’]).plot.bar() 
plt.title(’MONTH’)
plt.subplot(2,3,2)
pd.value_counts(df_bank[’default’]).plot.bar() 
plt.title(’DEFAULT’) 
plt.subplot(2,3,3) 
pd.value_counts(df_bank[’housing’]).plot.bar() 
plt.title(’HOUSING’) 
plt.subplot(2,3,4) 
pd.value_counts(df_bank[’loan’]).plot.bar() 
plt.title(’LOAN’) 
plt.subplot(2,3,5)
pd.value_counts(df_bank[’subscribed’]).plot.bar() plt.title(’SUBSCRIBED’)
plt.axis(’tight’) 
plt.show()

График выше показывает, что в основном с клиентами связывались в течение мая, и многие клиенты не подписались на срочный депозит.

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

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

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

# Check the percentage of subscribed customers
df_not_subscribed = df_bank.loc[df_bank[’subscribed’] == ’no’] df_subscribed = df_bank.loc[df_bank[’subscribed’] == ’yes’] 
sub = len(df_not_subscribed.index) 
nsub = len(df_subscribed.index) 
# Pie chart
labels = [’Not Subscribed’, ’Subscribed’] explode = (0, 0.1) 
# add colors
colors = [’#ff9999’,’#66b3ff’] 
sizes = [(sub/(sub+nsub))*100, (nsub/(sub+nsub))*100] 
fig1, ax1 = plt.subplots() 
ax1.pie(sizes, labels=labels, explode = explode, colors=colors,            
      autopct=’%1.1f%%’, 
      shadow=True, startangle=90) 
# Equal aspect ratio ensures that pie is drawn as a circleax1.axis(’equal’)
plt.tight_layout() 
plt.show()

Круговая диаграмма показывает, что только 11,7% клиентов подписались на срочный депозит после кампании. Для числовых данных необходимо проверять выбросы [1].

Мы собираемся построить два графика: один для баланса [2], а другой для продолжительности [3].

# Box plots to check for outliers
fig = plt.figure(figsize = (15, 15)
plt.subplot (2,3,1)
sns.boxplot (x = 'balance', y = 'subscribed', data = df_bank
plt.title ('BALANCE')
plt.subplot (2,3,2)
sns.boxplot (x = 'duration', y = 'subscribed', data = df_bank)
plt.title ('DURATION')
plt.show()

Можно наблюдать несколько выбросов [1] в балансе [2] и продолжительности [3] . Баланс большинства клиентов составляет от 0 до 20 000 долларов. Кроме того, подписавшиеся клиенты имели в среднем более длительный контакт с персоналом банка, чем те, кто не подписался.

Продолжительность контакта играет важную роль и сильно влияет на решение о подписке.

3. Предварительная обработка данных

Во-первых, мы должны преобразовать категориальные переменные в фиктивные переменные [4] (числовой объект).

Для этого мы создадим функцию convertToDummy и используем метод pandas get dummies для преобразования категориальных переменных в фиктивные столбцы.

Затем мы удалим один из фиктивных столбцов, чтобы избежать ловушки фиктивной переменной [5] (проблемы мультиколлинеарности [6]).

# function to convert categorical
def convertToDummy (df, column):
  # Create dummy variables for categorical variables
  df_dummies = pd.get_dummies (column)
  
  # Deleting one of the dummy variable to avoid multicollinearity issues
  del df_dummies[df_dummies.columns [-1]]
  # Add the columns to existing data frame
  df = pd.concat ([df, df_dummies], axis - 1)
  return df

Теперь мы преобразуем зависимую переменную и подписываем значения «да» и «нет» на двоичные 1 и 0, используя функцию карты.

# Function to convert categorical variables to dummy 
# Convert y to binary for further processing
df_bank[’subscribed’] = df_bank[’subscribed’].map({’yes’: 1, ’no’: 0})

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

Мы также собираемся удалить некоторые столбцы, которые не важны для создания модели.

Более низкую корреляцию [7] также можно наблюдать в корреляционной матрице, как подробно описано в разделе 3.1. Удаление этих столбцов не повлияет на точность модели.

# delete unwanted columns day 
del df_bank[’day’] 
del df_bank[’month’]
 
# Create dummy variables for categorical variables
df_bank = convertToDummy(df_bank, df_bank[’marital’]) 
df_bank = convertToDummy(df_bank, df_bank[’job’]) 
df_bank = convertToDummy(df_bank, df_bank[’education’]) 
df_bank = convertToDummy(df_bank, df_bank[’poutcome’]) 
df_bank = convertToDummy(df_bank, df_bank[’contact’]) 
# Delete the original categorical columns as new variables are created
del df_bank[’marital’] 
del df_bank[’job’] 
del df_bank[’education’] 
del df_bank[’poutcome’] 
del df_bank[’contact’] 
# Convert default, housing, loan to binary for further processing
df_bank[’default’] = df_bank[’default’].map({’yes’: 1, ’no’: 0}) df_bank[’loan’] = df_bank[’loan’].map({’yes’: 1, ’no’: 0}) df_bank[’housing’] = df_bank[’housing’].map({’yes’: 1, ’no’: 0})

3.1 Проверка корреляционной матрицы (Тепловая карта)

Мы построим тепловую карту для проверки корреляции [7] между переменными. Мы будем использовать метод тепловой карты из пакета seaborn.

# Plotting heat map for displaying correlation matrix
fig = plt.figure(figsize=(20,20))
corr = df_bank.corr()
sns.heatmap(corr, annot = True)

4. Модельное обучение

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

# Importing the required libraries
from xgboost import XGBClassifier 
from sklearn.tree import DecisionTreeClassifier 
from sklearn.datasets import make_classification 
from sklearn.ensemble import RandomForestClassifier 
from sklearn.naive_bayes import GaussianNB 
from sklearn.linear_model import LogisticRegression 
from sklearn.svm import SVC 
from sklearn.neighbors import KNeighborsClassifier 
from sklearn.preprocessing import StandardScaler 
from sklearn.model_selection import train_test_split 
from sklearn.metrics import accuracy_score

Теперь мы преобразуем зависимые [8] и независимые переменные [9] в матрицу признаков, т.е. преобразуем зависимые и независимые переменные в матричную форму, чтобы их можно было использовать в модели.

# Creating matrix of features of independent variable
 
x = df_bank.iloc[:,df_bank.columns != ’subscribed’].values 
y = df_bank.iloc[:,9].values

Теперь мы разделим наш набор данных на обучающий набор, тестовый набор и набор проверки. Это сделано для того, чтобы избежать проблем с переоснащением [10].

Мы разделим весь набор данных, отнеся 70% к обучающему набору и 30% к тестовому набору данных.

Затем мы разделяем набор тестовых данных дальше, классифицируя 70% как набор тестовых данных и 30% как набор данных проверки.

Теперь мы будем использовать метод разбивки обучающего теста из библиотеки выбора sklearn.model, чтобы разбить набор данных.

# Split dataset into training and test set
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size      
  = 0.3, random_state = 0)
x_test, x_valid, y_test, y_valid = train_test_split(x_test, y_test,   
  test_size = 0.3, random_state = 0)

Теперь мы выполним масштабирование признаков, то есть стандартизируем [11] переменные, прежде чем мы передадим их в модели классификатора для классификации, используя метод StandardScaler из пакета sklearn.preprocessing.

# Feature Scaling
sc_x = StandardScaler()
x_train = sc_x.fit_transform(x_train) 
x_test = sc_x.fit_transform(x_test) 
x_valid = sc_x.fit_transform(x_valid)

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

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

def classify(x_train, y_train) : 
  
# Initializing the models 
  lr = LogisticRegression(random_state = 0) 
  xgb = XGBClassifier(random_state = 0) 
  dtc = DecisionTreeClassifier(random_state = 0) 
  rfc = RandomForestClassifier(random_state = 0) 
nbc = GaussianNB() 
  svm = SVC(kernel=’rbf’, C=1,gamma=’auto’) 
  knn = KNeighborsClassifier(n_neighbors=3) 
  
# Fitting Models to training data set
  lr.fit(x_train, y_train)
  xgb.fit(x_train, y_train) 
  dtc.fit(x_train, y_train) 
  rfc.fit(x_train, y_train) 
  nbc.fit(x_train, y_train) 
  svm.fit(x_train, y_train) 
  knn.fit(x_train, y_train) 
  classifiers = [lr, xgb, dtc, rfc, nbc, svm, knn] return classifiers

Вызовите описанный выше метод и передайте обучающий набор данных для обучения модели.

# Passing training data to classify function to fit various classification models
classifiers = classify(x_train, y_train)

5. Тестирование модели

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

# Function to plot the accuracy of the model
def plot_accuracy_plot(accuracy) :
  dims = (11.7, 8.27) 
  fig, ax = plt.subplots(figsize = dims) 
  plt.xlabel(’Accuracy’) 
  plt.title(’Classifier Accuracy’) 
  sns.set_color_codes("muted") 
  splot = sns.barplot(ax=ax, x=’Accuracy’, y=’Classifier’,     
     data=accuracy, color="b") 
plt.show()

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

# This function performs prediction, 
# plots the accuracy score of all classifiers and 
# returns the accuracy score data frame
def predict(x_test, classifiers, y_test): 
lr_test_pred = classifiers[0].predict(x_test) 
xgb_test_pred = classifiers[1].predict(x_test) 
dtc_test_pred = classifiers[2].predict(x_test) 
rfc_test_pred = classifiers[3].predict(x_test) 
nbc_test_pred = classifiers[4].predict(x_test) 
svm_test_pred = classifiers[5].predict(x_test) 
knn_test_pred = classifiers[6].predict(x_test) 
# judge accuracy using built-in function
 
accuracy_test = dict() 
accuracy_test[’Logistic Regression’] = accuracy_score(y_test, 
    lr_test_pred) 
accuracy_test[’XGBoost’] = accuracy_score(y_test, xgb_test_pred) accuracy_test[’DecisionTree’] = accuracy_score(y_test,dtc_test_pred) 
accuracy_test[’RandomForest’] = accuracy_score(y_test,rfc_test_pred) accuracy_test[’Naive_bayes’] = accuracy_score(y_test, nbc_test_pred) accuracy_test[’support_vector_Machines’] = 
    accuracy_score(y_test,svm_test_pred) 
accuracy_test[’KNN’] = accuracy_score(y_test,knn_test_pred) print(accuracy_test) 
df_acc= pd.DataFrame([accuracy_test.keys(),   
    accuracy_test.values()]).T 
df_acc.columns= [’Classifier’, ’Accuracy’] 
df_acc.sort_values(by=[’Accuracy’], ascending = False) 
# Plot accuracy plot 
plot_accuracy_plot(df_acc) 
return df_acc.sort_values(’Accuracy’, ascending = False)

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

Мы вызываем метод прогнозирования и проходим через тестовый набор данных.

# Predicting the test data set
predict (x_test, classifiers, y_test)

Результат: XGBoost обеспечивает самую высокую оценку точности [12] 89,99% среди других классификаторов для тестового набора данных.

Теперь мы вызываем метод прогнозирования и передаем действительный набор данных.

# Predicting the test data set
predict (x_valid, classifiers, y_valid)

Результат: XGBoost обеспечивает наивысшую оценку точности [12] 89,83% среди других классификаторов для набора данных проверки.

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

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

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

Чтобы запустить свой набор данных в автоматизированной среде и получить ценную информацию, попробуйте наш новый продукт 5411!

7. Кредиты

Еще раз спасибо Калифорнийскому университету в Ирвине за предоставление этого набора данных.

Ссылки

[1] выбросы: значение, которое «лежит вне» (намного меньше или больше) большинства других значений в наборе данных. Например, в оценках 25, 29, 3, 32, 85, 33, 27, 28 и 3, и 85 являются «выбросами».

[2] balance: общая сумма баланса клиента

[3] duration: продолжительность последнего контакта с клиентом в секундах (числовое)

[4] фиктивные переменные: фиктивные переменные — это переменные-посредники или числовые заменители качественных фактов, т. е. категориальные переменные

[5] ловушка фиктивной переменной: Ловушка фиктивной переменной — это сценарий, в котором независимые переменные являются мультиколлинеарными — сценарий, в котором две или более переменных сильно коррелированы; проще говоря, одна переменная может быть предсказана по другим.

[6] мультиколлинеарность. Мультиколлинеарность возникает, когда независимые переменные в регрессионной модели коррелируют. Эта корреляция является проблемой, потому что независимые переменные должны быть независимыми. Если степень корреляции между переменными достаточно высока, это может вызвать проблемы при подборе модели и интерпретации результатов.

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

[8] зависимая переменная: Зависимую переменную иногда называют «переменной результата». также известная как целевая переменная

[9] независимая переменная: независимая переменная — это переменная, которая, как считается, влияет на зависимую переменную

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

[11] Стандартизация: Стандартизация — это процесс помещения различных переменных на одну шкалу. Этот процесс позволяет сравнивать значения различных диапазонов переменных.

[12] показатель точности: точность – это доля правильных прогнозов, полученных нашей моделью. Это количество сделанных правильных прогнозов, деленное на общее количество сделанных прогнозов, умноженное на 100, чтобы превратить его в процент. Чем выше показатель точности, тем лучше модель

Свяжитесь с нами: Cocolevio.com| Фейсбук | ЛинкедИн | Инстаграм