Автор статьи: Артем Михайлов
В современном мире, где конкуренция между компаниями становится все более жесткой, понимание поведения клиентов и их удержание становятся ключевыми факторами для успешного бизнеса. Одним из важных инструментов в достижении этой цели является анализ данных клиентов и прогнозирование оттока пользователей.
Анализ данных клиентов – это процесс извлечения, очистки, исследования и визуализации данных о клиентах компании с целью выявления интересных закономерностей и паттернов в их поведении. Такой анализ позволяет компаниям понять, что делает их клиентов довольными, что их раздражает и, самое главное, предсказать вероятность того, что клиент может уйти к конкуренту, что называется оттоком пользователей.
Прогнозирование оттока – это процесс разработки моделей машинного обучения, которые позволяют предсказать, сколько и какие клиенты вероятно покинут компанию в определенный период времени. Предупреждение о возможном оттоке дает компаниям возможность принять меры по удержанию клиентов, что может существенно снизить потери и повысить общую прибыль.
Цель данной статьи – познакомить читателей с процессом анализа данных клиентов и построения модели прогнозирования оттока с использованием языка программирования Python. Мы рассмотрим ключевые этапы работы с данными, включая подготовку, исследовательский анализ, построение моделей машинного обучения и интерпретацию результатов.
Подготовка данных
Подготовим наши данные.
# A. Загрузка данных клиентов data = { 'CustomerID': [1, 2, 3, 4, 5], 'Age': [32, 45, 29, 56, 38], 'Gender': ['Male', 'Female', 'Female', 'Male', 'Male'], 'TotalSpend': [1000, 1500, 500, 2000, 800], 'NumOfPurchases': [5, 3, 7, 2, 4], 'Churn': [0, 1, 0, 1, 0] # 0 - остается, 1 - ушел } # B. Импорт необходимых библиотек import pandas as pd from sklearn.preprocessing import LabelEncoder, StandardScaler # Преобразуем данные в DataFrame df = pd.DataFrame(data) # C. Очистка данных: обработка пропущенных значений и дубликатов # Проверим наличие пропущенных значений print("Количество пропущенных значений:") print(df.isnull().sum()) # В данном примере предположим, что у нас нет пропущенных значений, поэтому нет необходимости в дополнительной обработке. # Однако, если бы в данных были пропуски, то мы могли бы обработать их с помощью метода fillna() для заполнения пропусков # определенными значениями, либо удалить строки с пропущенными значениями с помощью dropna(). # Проверим и удалим дубликаты, если они есть df.drop_duplicates(inplace=True) # D. Преобразование данных: кодирование категориальных признаков и масштабирование числовых признаков # Кодируем категориальный признак "Gender" в числовой формат, чтобы модель машинного обучения могла работать с ним. le = LabelEncoder() df['Gender'] = le.fit_transform(df['Gender']) # Масштабируем числовые признаки для их нормализации и уменьшения влияния различных единиц измерения. # В данном примере мы используем StandardScaler для приведения признаков к стандартному нормальному распределению # со средним значением 0 и стандартным отклонением 1. scaler = StandardScaler() df[['Age', 'TotalSpend', 'NumOfPurchases']] = scaler.fit_transform(df[['Age', 'TotalSpend', 'NumOfPurchases']]) # Выведем окончательный результат print("\nПодготовленные данные:") print(df)

В данном примере мы предположили, что данные не содержат пропущенных значений. Однако, в реальных данных может быть необходимость в более сложной обработке пропусков. Также, при работе с реальными данными, предполагается, что данные загружаются из файлов, баз данных или других источников, и их обработка может потребовать дополнительных этапов, которые не были учтены в данном примере. Важно всегда проверять и анализировать данные для выбора оптимального подхода к их обработке и подготовке перед построением моделей машинного обучения.
Исследовательский анализ данных
Основные статистики о клиентах
Для начала, давайте рассмотрим основные статистики о клиентах, чтобы получить общее представление о нашем наборе данных.
# Посмотрим на первые несколько строк данных print("Первые 5 строк данных:") print(df.head()) # Получим основные статистические показатели о клиентах print("\nОсновные статистики о клиентах:") print(df.describe())
Получаем следующее(на картинке):

Данные о клиентах выглядят нормализованными, так как средние значения близки к 0, а стандартные отклонения приближаются к 1. Представленные статистические показатели помогают нам лучше понять характеристики клиентов и их распределения в наборе данных.
Визуализация данных для лучшего понимания распределений
Для визуализации данных и получения более глубокого понимания распределения признаков, давайте построим графики и диаграммы.
import matplotlib.pyplot as plt import seaborn as sns # Построим гистограмму возраста клиентов plt.figure(figsize=(8, 5)) sns.histplot(df['Age'], bins=10, kde=True, color='skyblue') plt.xlabel('Возраст') plt.ylabel('Частота') plt.title('Распределение возраста клиентов') plt.show() # Построим гистограмму общего объема расходов plt.figure(figsize=(8, 5)) sns.histplot(df['TotalSpend'], bins=10, kde=True, color='salmon') plt.xlabel('Общий объем расходов') plt.ylabel('Частота') plt.title('Распределение общего объема расходов клиентов') plt.show() # Построим гистограмму количества покупок plt.figure(figsize=(8, 5)) sns.histplot(df['NumOfPurchases'], bins=10, kde=True, color='orange') plt.xlabel('Количество покупок') plt.ylabel('Частота') plt.title('Распределение количества покупок клиентов') plt.show() # Построим диаграмму рассеяния для визуализации связи между признаками Age и TotalSpend plt.figure(figsize=(8, 5)) sns.scatterplot(x='Age', y='TotalSpend', data=df, hue='Churn', palette='viridis', s=100) plt.xlabel('Возраст') plt.ylabel('Общий объем расходов') plt.title('Диаграмма рассеяния: Возраст vs. Общий объем расходов') plt.legend(title='Churn', labels=['Остается', 'Ушел']) plt.show()
Мы получаем следующие результаты:




В итоге получили визуализации, которые помогают нам лучше понять распределение признаков. Гистограммы позволяют нам увидеть, какие значения признаков чаще всего встречаются, а диаграмма рассеяния показывает возможные связи между признаками «Возраст» и «Общий объем расходов», а также как фактор оттока (Churn) может влиять на эти связи.
Исследование корреляции между признаками
Корреляция между признаками позволяет нам определить, какие признаки сильно связаны друг с другом, что помогает в идентификации важных факторов.
# Построим матрицу корреляции между признаками correlation_matrix = df.corr() # Визуализируем матрицу корреляции с помощью тепловой карты plt.figure(figsize=(10, 8)) sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt='.2f', linewidths=0.5) plt.title('Матрица корреляции') plt.show()
Результат:

Матрица корреляции позволяет нам оценить силу и направление связи между признаками. Самая яркая точка на диагонали (значение 1) представляет собой корреляцию признака с самим собой (что логично, так как корреляция признака с самим собой всегда равна 1). Важным для анализа является взаимосвязь между оттоком (Churn) и другими признаками. Значения корреляции близкие к 1 или -1 указывают на сильную связь, в то время как значения близкие к 0 указывают на отсутствие линейной зависимости.
Построение модели прогнозирования оттока
Выбор алгоритма машинного обучения
Для прогнозирования оттока клиентов, мы выберем три алгоритма машинного обучения: логистическую регрессию, случайный лес и градиентный бустинг. Эти алгоритмы широко используются для задач классификации, таких как прогнозирование оттока, и позволяют получить хорошие результаты при правильной настройке гиперпараметров.
from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier # Инициализируем модели logreg_model = LogisticRegression(random_state=42) rf_model = RandomForestClassifier(random_state=42) gb_model = GradientBoostingClassifier(random_state=42) # Обучение моделей будет произведено в следующей части, когда данные разделены на обучающую и тестовую выборки.
Разделение данных на обучающую и тестовую выборки
Перед обучением модели необходимо разделить данные на обучающую и тестовую выборки. Обучающая выборка будет использоваться для обучения модели, а тестовая выборка для оценки ее производительности.
from sklearn.model_selection import train_test_split # Разделяем данные на обучающую (80%) и тестовую (20%) выборки X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Обучение модели на обучающей выборке
Теперь обучим выбранные модели на обучающей выборке.
# Обучение моделей на обучающей выборке logreg_model.fit(X_train, y_train) rf_model.fit(X_train, y_train) gb_model.fit(X_train, y_train)
Оценка производительности модели на тестовой выборке
После обучения моделей на обучающей выборке, необходимо оценить их производительность на тестовой выборке.
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score # Функция для оценки производительности модели def evaluate_model(model, X_test, y_test): y_pred = model.predict(X_test) accuracy = accuracy_score(y_test, y_pred) precision = precision_score(y_test, y_pred) recall = recall_score(y_test, y_pred) f1 = f1_score(y_test, y_pred) roc_auc = roc_auc_score(y_test, y_pred) return accuracy, precision, recall, f1, roc_auc # Оценка производительности моделей logreg_accuracy, logreg_precision, logreg_recall, logreg_f1, logreg_roc_auc = evaluate_model(logreg_model, X_test, y_test) rf_accuracy, rf_precision, rf_recall, rf_f1, rf_roc_auc = evaluate_model(rf_model, X_test, y_test) gb_accuracy, gb_precision, gb_recall, gb_f1, gb_roc_auc = evaluate_model(gb_model, X_test, y_test) # Вывод результатов print("Результаты оценки производительности моделей на тестовой выборке:") print("Логистическая регрессия:") print(f"Точность: {logreg_accuracy:.4f}, Полнота: {logreg_recall:.4f}, F1-мера: {logreg_f1:.4f}, ROC-AUC: {logreg_roc_auc:.4f}") print("Случайный лес:") print(f"Точность: {rf_accuracy:.4f}, Полнота: {rf_recall:.4f}, F1-мера: {rf_f1:.4f}, ROC-AUC: {rf_roc_auc:.4f}") print("Градиентный бустинг:") print(f"Точность: {gb_accuracy:.4f}, Полнота: {gb_recall:.4f}, F1-мера: {gb_f1:.4f}, ROC-AUC: {gb_roc_auc:.4f}")
Мы обучили три различные модели машинного обучения (логистическую регрессию, случайный лес и градиентный бустинг) на обучающей выборке и оценили их производительность на тестовой выборке. Результаты оценки включают значения точности, полноты, F1-меры и ROC-AUC для каждой модели. При оценке производительности моделей, мы можем определить, какая модель лучше всего справляется с задачей прогнозирования оттока пользователей.
Заключение
Анализ данных клиентов и прогнозирование оттока играют важную роль для компаний, позволяя предпринимать меры по удержанию клиентов и оптимизации бизнес-процессов. Результаты данного исследования помогут компании лучше понять своих клиентов, выделить ключевые факторы, влияющие на отток.
Кстати, о том, чем занимается системный аналитик и о профессии в целом мои друзья из OTUS расскажут на бесплатном вебинаре. Вы узнаете о востребованности профессии в 2023 году и перспективах в будущем. А также о том, как повысить зарплатную вилку на начальном этапе: с какой суммы начинать и к какой сумме стремиться. По итогам вебинара вы сможете понять подходит вам профессия системного аналитика или нет. Регистрируйтесь и приходите, будет интересно.
ссылка на оригинал статьи https://habr.com/ru/companies/otus/articles/750822/
Добавить комментарий