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

Статистика может применяться во многих областях знаний, помогая нам справляться с неопределенностью, рассчитывать вероятности и поддерживать принятие решений.
Одной из областей, где статистика играет важную роль, является медицина, использующая такие инструменты, как T-тесты, A/B-тесты или анализ выживаемости. Последний инструмент и является предметом данной статьи.
Анализ выживаемости зародился в медицине и биологии, где в качестве основного события пытались смоделировать смерть пациента или организма. Отсюда и название.
Однако статистики поняли, что такой анализ настолько эффективен, что его можно применять во многих других областях жизни, и поэтому он распространился в сфере бизнеса, особенно после всплеска развития науки о данных.
Давайте узнаем об этом подробнее.
Анализ выживаемости
Анализ выживаемости [SA] — это раздел статистики, используемый для прогнозирования времени, необходимого для наступления определенного события .[1]
Этот метод, также известный как анализ времени до события, позволяет определить, сколько времени потребуется для наступления определенного события, с учетом того, что некоторые события еще не произошли к моменту сбора данных.
Примеры встречаются не только в медицине и биологии, но и повсюду.
- Время до поломки машины
- Время, необходимое клиенту для отмены подписки.
- Время до следующей покупки со стороны клиента
Поскольку мы пытаемся оценить число, а не группу или класс, это означает, что мы имеем дело с регрессионной задачей. Так почему же мы не можем использовать линейную регрессию методом наименьших квадратов?
Зачем использовать анализ выживаемости?
Стандартные регрессионные модели, такие как МНК или логистическая регрессия, испытывают трудности с обработкой данных о выживаемости, поскольку они предназначены для обработки завершенных событий, а не «продолжающихся» историй.
Представьте, что вы хотите предсказать, кто финишировал в забеге на 10 миль, но входные данные — это событие, которое еще не закончилось. До конца забега 2 часа, и вы хотите использовать имеющиеся данные для оценки чего-либо.
Стандартные алгоритмы регрессии потерпят неудачу, потому что:
- OLS : У вас есть данные только от тех, кто уже финишировал. Использование только их данных создаст огромную предвзятость в пользу более быстрых участников.
- Логистическая регрессия : Она, вероятно, может определить, финишировал ли кто-то в гонке, но рассматривает тех, кто финишировал за 30 минут, так же, как и тех, кто финишировал за 8 часов.
Основы анализа выживаемости
Давайте рассмотрим несколько важных понятий для понимания анализа выживаемости.
Во-первых, мы должны понять, как возникает и исчезает та или иная точка данных.
- Рождение : Момент, когда мы начали измерять данную точку данных. Например, момент, когда пациенту диагностируют рак, или день, когда человека принимают на работу в компанию. Обратите внимание, что наблюдения не обязательно должны начинаться одновременно.
- Смерть : Она наступает в момент наступления интересующего события. В день увольнения сотрудника из компании.
Интересной особенностью анализа ситуационной осведомленности является то, что исследование или наблюдение может завершиться до того, как произойдет событие. В этом случае у нас возникнет еще одно важное понятие: цензурированная точка данных.
- Цензурирование (отсутствие смерти) : Если исследование заканчивается или участник выбывает до наступления события, данные считаются «цензурированными», то есть мы знаем только, что он выжил, по крайней мере, до этого момента.
Однако данные могут быть подвергнуты цензуре различными способами.
- Правосторонняя цензура : наиболее распространенное явление. Происходит после окончания периода наблюдения или отказа участника от участия.

- Левая цензура : Событие произошло до начала исследования.
Отлично. Важно отметить, что анализ выживаемости — это способ оценки вероятности наступления события как функции времени. Рассматривая выживаемость как функцию времени, мы можем ответить на вопросы, на которые нельзя ответить с помощью одной вероятностной оценки, например: «В каком конкретном месяце риск оттока клиента достигает пика?»
Теперь, когда мы знаем основы, давайте подробнее рассмотрим функции, выполняемые в рамках системы SA.
Функция выживания
Функция выживания S(t) выражает вероятность того, что событие не произойдет, как функцию времени . Естественно, она будет уменьшаться с течением времени, поскольку все больше и больше людей будут переживать это событие.
Таким образом, применив это к нашему примеру с текучестью кадров, мы увидим вероятность того, что сотрудник останется в компании через N лет.

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

Выбор модели для анализа выживаемости
Как видите, тема социальной тревожности может быстро стать очень сложной и запутанной. Но давайте постараемся не усложнять.
При проведении анализа выживаемости используются две основные модели. Одна из них — модель Каплана-Мейера, которая проще, но не учитывает влияние дополнительных переменных-предикторов и требует для своей работы ряда допущений.
Другая модель — это модель пропорциональных рисков Кокса, которая является отраслевым стандартом, поскольку она может учитывать другие переменные, математически более стабильна и хорошо работает даже при нарушении некоторых предположений.
Давайте узнаем о них побольше.
Каплан-Мейер
- Хорошо работает с данными, подвергнутыми правосторонней цензуре (помните? Когда событие происходит после окончания периода наблюдения).
- Интуитивная модель
- Непараметрический: не подчиняется никакому распределению
- Необходимо сделать предположения, например, что отсев участников не связан с событием; время входа не влияет на риск выживания; и время событий известно с достаточной точностью.
- Возвращает функцию выживания , которая выглядит как лестница.
Когда использовать:
- Простой анализ выживаемости без учета других ковариат или предикторов.
- Отлично подходит для быстрой визуализации.
Пропорциональная вероятность риска Кокса
- Отраслевой стандарт
- Принимает дополнительные предикторы или ковариаты.
- Работает хорошо, даже если некоторые предположения нарушены.
- Оценивает функцию риска , которая, как правило, более стабильна, чем функция выживаемости.
Когда использовать:
- Оценка на данных с несколькими предикторами (ковариантами).
Теперь давайте займемся кодом.
Код
В этом разделе мы научимся моделировать SA, используя обе ранее представленные модели.
Для этого упражнения был выбран набор данных о оттоке клиентов телекоммуникационных компаний, который можно найти в репозитории машинного обучения Калифорнийского университета в Ирвайне под лицензией Creative Commons.

Далее импортируем необходимые пакеты.
# Данные из ucimlrepo import fetch_ucirepo # Обработка данных import pandas as pd import numpy as np # Визуализация данных import matplotlib.pyplot as plt import seaborn as sns # Анализ выживаемости Lifelines from lifelines import KaplanMeierFitter from lifelines import CoxPHFitter # Получение набора данных telco_churn = fetch_ucirepo(id=563) # данные (в виде фреймов данных pandas) X = telco_churn.data.features y = telco_churn.data.targets # Pandas df df = pd.concat([X, y], axis=1) df.head(3)
Внедрение метода Каплана-Мейера
Как уже упоминалось, модель Каплана-Мейера (КМ) очень проста и удобна в использовании, являясь хорошим выбором для визуализации. Нам нужны всего две переменные: один предиктор и одна метка.
Затем мы можем создать экземпляр модели KM и подогнать ее к данным, используя продолжительность подписки (общее количество месяцев подписки) в качестве предиктора и отток клиентов в качестве наблюдаемого события.
# Создание экземпляра KM kmf = KaplanMeierFitter() # Обучение модели kmf.fit(df['Длительность подписки'], event_observed=df['Отток клиентов'], label= 'Отток клиентов')
Готово. Далее мы можем визуализировать функцию выживания.
# Построение кривой выживаемости plt.figure(figsize=(12, 5)) kmf.plot_survival_function() plt.title('Кривая выживаемости Каплана-Мейера: пожизненный срок пользования услугами телекоммуникационных компаний') plt.xlabel('Время (месяцы)') plt.ylabel('Вероятность того, что абонент останется подписан') plt.grid(True) plt.show()
Это просто замечательно! Мы видим, что более 90% клиентов остаются с телекоммуникационной компанией примерно на 35 месяцев.

Если мы хотим это подтвердить, мы можем легко написать код, который покажет, что 90% сотрудников остаются в компании на 34 месяца.
# Проверка показателя выживаемости через 34 месяца kmf.survival_function_at_times(34) Отток клиентов 34 0.900613
Если мы хотим узнать медианное время оттока клиентов, мы можем использовать атрибут KM .median_survival_time_. Это момент времени (t), когда вероятность выживания падает до 50%. В нашем случае это будет бесконечность, поскольку функция выживания никогда не опускается ниже 0,5. Но если результат равен 24 (например), это означает, что в среднем половина ваших клиентов уйдет к 24-му месяцу.
# Время (t), когда показатель выживаемости падает ниже 50% median_survival = kmf.median_survival_time_ print(f»Медианный срок жизни клиента: {median_survival} месяцев»)
Мы также можем проводить другие анализы, например, сравнения между группами. Представьте, что эта телекоммуникационная компания делит своих клиентов на две группы:
- Активные пользователи : частота использования > медианная
- Пользователи программного обеспечения : частота использования <= медиана
Мы можем сравнить функции выживаемости обеих групп.
# Группы столбцов df['Heavy_User'] = np.where(df['Frequency of use'] > df['Frequency of use'].median(), 1, 0) df.head() plt.figure(figsize=(12, 5)) plt.title('Кривая выживаемости Каплана-Мейера: пожизненный срок пользования услугами телекоммуникационных компаний') plt.xlabel('Время (месяцы)') plt.ylabel('Вероятность оттока') # Подгонка модели для пользователей с низкой активностью и построение графика kmf.fit(df[df.Heavy_User == 0]['Длительность подписки'], df[df.Heavy_User == 0]['Отток'], label='Пользователь с низкой активностью') ax = kmf.plot_survival_function() # Подгонка модели для пользователей с высокой активностью и построение графика kmf.fit(df[df.Heavy_User == 1]['Длительность подписки'], df[df.Heavy_User == 1]['Отток'], label='Активный пользователь') ax = kmf.plot_survival_function(ax=ax) plt.show()
Вот и всё. В то время как активные пользователи остаются верны компании на протяжении всего периода, пользователи, не слишком активно использующие сервис, быстро уходят после 30 месяцев. Средний срок их пребывания в компании составляет 40 месяцев.

При сравнении групп необходимо убедиться в статистической значимости различий. Для этого в пакете lifelines реализован лог-ранговый тест. Это проверка гипотезы:
- Нулевая гипотеза (Ho) : Кривые выживаемости двух популяций не различаются.
- Ha (альтернативная гипотеза): Кривые выживаемости двух популяций различаются.
from lifelines.statistics import logrank_test # 3. Выполнение теста лог-ранга results = logrank_test(df[df.Heavy_User == 0]['Длительность подписки'], df[df.Heavy_User == 1]['Длительность подписки'], event_observed_A= df[df.Heavy_User == 0]['Отток'], event_observed_B= df[df.Heavy_User == 1]['Отток']) # 4. Вывод результатов print(f»P-значение: {results.p_value}») print(f»Статистика теста: {results.test_statistic}») if results.p_value < 0.05: print("Результат: Статистически значимая разница между группами.") else: print("Результат: Значимой разницы не обнаружено.") P-значение: 7.23487469906141e-103 Тестовая статистика: 463.7794219211866 Результат: Статистически значимая разница между группами.
Внедрение модели пропорциональных рисков Кокса
Первое, что интересно в модели пропорциональных рисков Кокса (CPH), — это проверка того, как другие переменные могут влиять на выживаемость наблюдаемого индивида.
Давайте разберем это по пунктам.
- Начнём с выбора нескольких ковариат.
- Мы фильтруем набор данных.
- Создайте экземпляр модели.
- Подогнать под модель
# 1. Подготовка данных # Выбор времени, события и выбранных ковариат cols_to_use = [ 'Длительность подписки', # Время (t) 'Отток', # Событие (E) 'Сумма платежа', # Ковариата 1 'Жалобы', # Ковариата 2 'Частота использования' # Ковариата 3 ] # Удаление пропущенных значений для модели df_model = df[cols_to_use].dropna() # 2. Инициализация и подгонка модели Кокса # Использование штрафного коэффициента для стабилизации вычислений, если модель не сходится. cph = CoxPHFitter(penalizer=0.1) cph.fit(df_model, duration_col='Длительность подписки', event_col='Отток') # 3. Отображение результатов cph.print_summary() # 4. Визуализация влияния ковариат cph.plot()
Это наш прекрасный результат.

Как это можно интерпретировать?
Пунктирная вертикальная линия на отметке 0,0 обозначает нейтральную точку.
- Если значение переменной равно 0 , это не влияет на отток клиентов.
- Справа (> 0): Увеличивает опасность (ускоряет процесс смены персонала).
- Слева (< 0): Снижает опасность (заставляет клиента дольше оставаться).
- В таблице наиболее важным столбцом для заинтересованных сторон является показатель коэффициента риска exp(coef). Он показывает мультипликативный эффект на риск оттока клиентов.
[ТАБЛИЦА] Жалобы (5,36): Клиент, который жалуется, в 5,36 раза (или на 436%) чаще уходит, чем клиент, который не жалуется. Это очень значительный эффект.
[ГРАФИК] Жалобы (высокий риск): Это наш самый сильный прогностический фактор. Клиенты, имеющие жалобы, примерно в 5,4 раза чаще уходят в любой момент времени по сравнению с теми, у кого жалоб нет.
[ТАБЛИЦА] Частота использования (0,99): Хотя значение p указывает на техническую значимость, HR 0,99 фактически равен 1. Это означает, что влияние на отток клиентов незначительно (изменение всего на 1%).
[ГРАФИК] Частота использования (нейтральная): Квадрат расположен почти точно на линии 0,0. В данной конкретной модели частота использования услуги клиентом существенно не меняется при его уходе.
[ТАБЛИЦА] Размер платы (0,83): При каждом увеличении платы на одну единицу риск оттока клиентов снижается на 17% (1 долл. – 0,83 = 0,17 долл.). Клиенты, которые платят больше, более стабильны.
[ГРАФИК] Размер платы (защитный коэффициент): Квадрат находится слева от нулевой линии. Более высокие сборы связаны с меньшим риском оттока клиентов.
Мы также можем рассмотреть функции «Выживание» и «Опасность» для этой модели.

Кривая похожа на модель Каплана-Мейера. Давайте сравним вероятность выживания на том же 34-м месяце.
# Извлекаем базовую вероятность выживания в момент времени 34 survival_at_34 = cph.baseline_survival_.loc[34] print(f»Базовая вероятность выживания в период 34: {survival_at_34.values[0]:.4f}») Базовая вероятность выживания в период 34: 0.9294
Это почти на 3% выше, примерно 93%.
В завершение статьи давайте выберем двух разных клиентов, одного без жалоб, а другого с жалобами, и сравним вероятность их сохранения на 34-м месяце.
# 1. Выбираем клиента (или прогнозируем нового) individual = df_model.iloc[[110,111]] # 2. Прогнозируем полную кривую выживаемости pred_survival = cph.predict_survival_function(individual) # 3. Получаем значение в момент времени 34 prob110_at_34 = pred_survival.loc[34].values[0] prob111_at_34 = pred_survival.loc[34].values[1] print(f»Клиент 110 (нет жалоб) Вероятность «Выживает» до периода 34: {prob110_at_34:.2%}») print(f»Клиент 111 (да жалоб) Вероятность «Выживает» до периода 34: {prob111_at_34:.2%}») Customer 110 (нет жалоб) Вероятность «дожить» до 34-го периода: 93,94% Клиент 111 (да, есть жалобы) Вероятность «дожить» до 34-го периода: 61,68%
Большая разница, правда? Более 30%. И наконец, мы можем рассчитать, сколько месяцев, по прогнозам, пройдёт с момента ухода каждого клиента.
# Время до оттока (ожидаемый срок жизни) клиента pred_churn = cph.predict_expectation(df_model.iloc[[110,111]]) # Получаем значения в месяцах prob110_churn = pred_churn.loc[110] prob111_churn = pred_churn.loc[111] print(f»Клиент 110 (без жалоб) ожидаемый отток через: {prob110_churn: .0f} месяцев») print(f»Клиент 111 (с жалобами) ожидаемый отток через: {prob111_churn:.0f} месяцев») Клиент 110 (без жалоб) ожидаемый отток через: 41 месяц Клиент 111 (с жалобами) ожидаемый отток через: 31 месяц
Безусловно, жалобы существенно влияют на отток клиентов в этой телекоммуникационной компании.
Прежде чем уйти
Анализ выживаемости — это гораздо больше, чем просто статистическая функция. Компании могут использовать его для понимания поведения клиентов.
Модели Каплана-Мейера и пропорционального риска Кокса предоставляют полезную информацию о продолжительности пользования услугами. Мы видели, как такие переменные, как ценность клиента и количество жалоб на обслуживание, напрямую влияют на отток клиентов, позволяя лицам, принимающим решения, разрабатывать более целенаправленные стратегии удержания.
Специалисты по работе с данными, понимающие эти модели, могут создать мощный инструмент для компаний, позволяющий улучшить отношения с их пользовательской базой. Используйте эти инструменты, чтобы оставаться на шаг впереди. В прямом смысле слова.
Если вам понравился этот контент, найдите меня на моем сайте.
https://gustavorsantos.me
Репозиторий GitHub
https://github.com/gurezende/Survival-Analysis
Ссылки
[1. Определение анализа выживаемости] (https://en.wikipedia.org/wiki/Survival_analysis)
[2. Полное введение в анализ выживаемости на Python] (https://medium.com/data-science/the-complete-introduction-to-survival-analysis-in-python-7523e17737e6)
[3. Введение в анализ выживаемости клиентов: понимание жизненного цикла клиента] (https://medium.com/@slavyolov/introduction-to-customer-survival-analysis-understanding-customer-lifetimes-6e4ba41d7724)
[4. Полное руководство по анализу выживаемости] (https://www.graphpad.com/guides/survival-analysis)
[5. В чем разница между методом Каплана-Мейера (КМ) и методом пропорциональных рисков Кокса (КФР)?] (https://www.droracle.ai/articles/218904/what-is-the-difference-between-kaplan-meier-km-and-cox)
[6. Документация по Lifelines] (https://lifelines.readthedocs.io/en/latest/)
[7. Анализ выживаемости в R для начинающих] (https://www.datacamp.com/tutorial/survival-analysis-R)
Источник: towardsdatascience.com





















