Una guía de análisis de supervivencia con Python: uso de modelos de tiempo hasta el evento para pronosticar la vida útil del cliente

a muchas áreas del conocimiento, ayudándonos a lidiar con la incertidumbre, calcular probabilidades y respaldar decisiones a lo largo del camino.

Una de esas áreas que depende en gran medida de las estadísticas es la industria médica, que utiliza herramientas como pruebas T, pruebas A/B o análisis de supervivencia. Este último es el tema de este artículo.

El análisis de supervivencia se originó en las ciencias médicas y biológicas, donde intentaban modelar, como evento principal, la muerte de un paciente u organismo. Ésa es la razón del nombre.

Sin embargo, los estadísticos entendieron que ese análisis era tan poderoso que podía aplicarse a muchas otras áreas de la vida, por lo que se extendió al ámbito empresarial, aún más después del auge de la ciencia de datos.

Aprendamos más al respecto.

Análisis de supervivencia

El Análisis de Supervivencia [SA] es una rama de la estadística que se utiliza para predecir la cantidad de tiempo que tarda en ocurrir un evento específico.[1]

También conocido como tiempo hasta el evento, este estudio puede determinar cuánto tiempo tomará para que suceda algo teniendo en cuenta el hecho de que algunos eventos aún no han sucedido en el momento en que se recopilan los datos.

Los ejemplos no se encuentran sólo en las ciencias médicas y biológicas, sino en todas partes.

Tiempo hasta que falla una máquina Tiempo hasta que un cliente cancela una suscripción Tiempo hasta que el cliente vuelve a comprar

Ahora bien, dado que estamos tratando de estimar un número, en lugar de un grupo o clase, esto significa que estamos ante un tipo de problema de regresión. Entonces, ¿por qué no podemos optar por la regresión lineal OLS?

¿Por qué utilizar el análisis de supervivencia?

Los modelos de regresión estándar como OLS o Regresión Logística luchan con los datos de supervivencia porque están diseñados para manejar eventos completados, no historias "en curso".

Imagine que quiere predecir quién terminó una carrera de 10 millas, pero los datos de entrada son un evento que aún continúa. La carrera es a las 2 horas y quieres utilizar los datos que tienes hasta el momento para estimar algo.

Los algoritmos de regresión habituales fallarán porque:

OLS: Sólo tienes los datos de los que ya terminaron la carrera. Usar solo sus datos creará un gran sesgo hacia las personas más rápidas. Regresión logística: Puede saber si alguien terminó la carrera, probablemente, pero trata a los que terminaron en 30 minutos de la misma manera que a los que terminaron en 8 horas.

Los fundamentos del análisis de supervivencia

Repasemos algunos conceptos importantes para comprender el análisis de supervivencia.

Primero, debemos comprender el nacimiento y la muerte de un punto de datos.

Nacimiento: el momento en que comenzamos a medir ese punto de datos. Por ejemplo, el momento en que a un paciente le diagnostican cáncer, o el día que una persona es contratada por una empresa. Observe que no es necesario que las observaciones comiencen todas al mismo tiempo. Muerte: Ocurre al ocurrir el evento de interés. El día que el empleado dejó la empresa.

Ahora bien, lo interesante del SA es que el estudio o la observación puede finalizar antes de que ocurra el evento. En este caso tendremos otro concepto importante: el punto de datos censurados.

Censura (no muerte): si el estudio finaliza o un sujeto abandona antes de que ocurra el evento, los datos se “censuran”, lo que significa que solo sabemos que sobrevivió al menos hasta ese punto.

Sin embargo, los datos pueden censurarse de diferentes maneras.

Censura por la derecha: la más común. El evento ocurre después de que finaliza el período de observación o el sujeto abandona.

El punto de datos C está censurado por la derecha. Imagen del autor.

Censura izquierda: El evento ocurrió antes de que comenzara el estudio.

Excelente. Es importante señalar que el análisis de supervivencia es una forma de estimar la probabilidad de que ocurra un evento en función del tiempo. Al tratar la supervivencia como una función del tiempo, podemos responder preguntas que una sola puntuación de probabilidad no puede responder, como por ejemplo: "¿En qué mes específico el riesgo de que un cliente abandone su punto máximo?"

Ahora que conocemos los conceptos básicos, aprendamos más sobre las funciones involucradas en SA.

Función de supervivencia

La función de supervivencia S

Entonces, aplicándolo a nuestro ejemplo de rotación de empleados, veríamos la probabilidad de que un empleado siga en la empresa después de N años.

Función de supervivencia. Imagen del autor.

Función de peligro

La función de peligro indica la probabilidad de que el evento ocurra en un momento dado. Es lo opuesto a la función de supervivencia y representa el riesgo de abandono (en lugar de la probabilidad de permanecer en la empresa).

Esta función calculará cuál es la probabilidad de que los empleados que no han abandonado hasta ahora lo hagan a partir de este momento.

Función de peligro. Imagen del autor.

Elegir su modelo para el análisis de supervivencia

Como puede ver, SA es un tema que puede volverse profundo y denso muy rápidamente. Pero intentemos hacerlo simple.

Hay dos modelos principales que se utilizan al realizar análisis de supervivencia. Uno es el Kaplan-Meier, que es más simple pero no considera el efecto de variables predictoras adicionales y requiere algunas suposiciones para funcionar.

El otro es el modelo de riesgo proporcional de Cox, que es el estándar de la industria porque puede incorporar otras variables al modelo, es más estable matemáticamente y funciona bien incluso si se infringen algunos supuestos.

Aprendamos más sobre ellos.

Kaplan-Meier

Funciona bien con datos censurados por la derecha (¿recuerdas? cuando el evento ocurre después de que finaliza el período de observación) Modelo intuitivo No paramétrico: no sigue ninguna distribución Se requieren suposiciones, como que los abandonos no están relacionados con el evento; El tiempo de entrada no afecta el riesgo de supervivencia; y Los tiempos de los eventos se conocen con precisión. Devuelve una función de supervivencia que parece una escalera.

Cuando usar:

Análisis de supervivencia simple sin otras covariables ni predictores. Ideal para visualizaciones rápidas.

Peligro proporcional de Cox

Estándar de la industria Acepta predictores o covariables adicionales Funciona bien incluso si se violan algunos supuestos Estima una función de riesgo, que tiende a ser más estable que las funciones de supervivencia

Cuando usar:

Estimar sobre datos con múltiples variables predictoras (covariables).

A continuación, pongamos manos a la obra con algo de código.

Código

En esta sección, aprenderemos cómo modelar una SA utilizando ambos modelos presentados anteriormente.

El conjunto de datos elegido para este ejercicio es Telco Customer Churn, que puede encontrar en el Repositorio de aprendizaje automático de UCI bajo la licencia Creative Commons.

Vista del conjunto de datos. Imagen del autor.

A continuación, importemos los paquetes necesarios.

# Datos de ucimlrepo import fetch_ucirepo # Gestión de datos importar pandas como pd importar numpy como np # DataViz importar matplotlib.pyplot como plt importar seaborn como sns # Análisis de supervivencia de Lifelines desde lifelines importar KaplanMeierFitter desde lifelines importar CoxPHFitter # buscar conjunto de datos telco_churn = fetch_ucirepo(id=563) # datos (como pandas marcos de datos) X = telco_churn.data.features y = telco_churn.data.targets # Pandas df df = pd.concat([X, y], eje=1) df.head(3)

Implementación de Kaplan-Meier

Ahora bien, como se mencionó, el modelo Kaplan-Meier [KM] es realmente simple y directo de usar, siendo una buena opción para visualizaciones. Todo lo que necesitamos son dos variables: un predictor y una etiqueta.

Luego, podemos crear una instancia del modelo KM y ajustarlo a los datos, utilizando la duración de la suscripción (meses totales de suscripción) como predictor y la tasa de abandono como el evento observado.

# Crear una instancia de KM kmf = KaplanMeierFitter() # Ajustar el modelo kmf.fit(df['Longitud de la suscripción'], event_observed=df['Churn'], label= 'Curn de clientes')

Hecho. A continuación, podemos visualizar la función de supervivencia.

# Trazar la curva de supervivencia plt.figure(figsize=(12, 5)) kmf.plot_survival_function() plt.title('Curva de supervivencia de Kaplan-Meier: vida útil del cliente de telecomunicaciones') plt.xlabel('Tiempo (meses)') plt.ylabel('Probabilidad de permanecer suscrito') plt.grid(True) plt.show()

¡Esto es genial! Podemos ver que más del 90% de los clientes permanecen en la empresa de Telecom durante aproximadamente 35 meses.

El modelo Kaplan-Meier es ideal para visualizaciones. Imagen del autor.

Si queremos confirmarlo, podemos codificarlo fácilmente para saber que, en realidad, el 90% permanece en la empresa durante 34 meses.

# Comprobando la tasa de supervivencia a los 34 meses kmf.survival_function_at_times(34) Rotación de clientes 34 0.900613

Si queremos saber cuál es el tiempo medio en que las personas abandonan, podemos usar el atributo de KM .median_survival_time_. Este es el momento # Tiempo median_survival = kmf.median_survival_time_ print(f"Vida útil media del cliente: {median_survival} meses")

También podemos realizar otros análisis, como comparaciones entre grupos. Imaginemos que esta empresa Telco clasifica a sus clientes en dos grupos:

Usuarios habituales: Frecuencia de uso > mediana Usuarios suaves: Frecuencia de uso <= mediana

Podemos comparar ambas funciones de supervivencia de estos dos grupos.

# Grupos de columnas 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('Curva de supervivencia de Kaplan-Meier: vida útil del cliente de telecomunicaciones') plt.xlabel('Tiempo (meses)') plural kmf.fit(df[df.Heavy_User == 1]['Duración de la suscripción'], df[df.Heavy_User == 1]['Churn'], label='Usuario intensivo') ax = kmf.plot_survival_function(ax=ax) plt.show()

Y ahí está. Si bien los usuarios habituales se mantienen estables en la empresa durante todo el período, los usuarios habituales abandonarán rápidamente la empresa después del mes 30. Su tiempo medio de supervivencia es de 40 meses.

Comparación de supervivencia entre grupos. Imagen del autor.

Al comparar grupos, debes asegurarte de que la diferencia sea estadísticamente significativa. Para eso, el paquete lifelines tiene implementada la prueba de rango logarítmico. Es una prueba de hipótesis:

Ho (hipótesis nula): Las curvas de supervivencia de dos poblaciones no difieren. Ha (hipótesis alternativa): Las curvas de supervivencia de dos poblaciones son diferentes. from lifelines.statistics import logrank_test # 3. Realice los resultados de la prueba Log-Rank = logrank_test(df[df.Heavy_User == 0]['Longitud de la suscripción'], df[df.Heavy_User == 1]['Longitud de la suscripción'], event_observed_A= df[df.Heavy_User == 0]['Churn'], event_observed_B= df[df.Heavy_User == 1]['Churn']) # 4. Imprimir resultados print(f"P-value: {results.p_value}") print(f"Estadística de prueba: {results.test_statistic}") if results.p_value < 0.05: print("Resultado: diferencia estadísticamente significativa entre grupos.") else: print("Resultado: no se detectó diferencia significativa.") Valor P: 7.23487469906141e-103 Estadística de prueba: 463.7794219211866 Resultado: Diferencia estadísticamente significativa entre grupos.

Implementación del riesgo proporcional de Cox

Lo primero que puede hacer con el modelo de riesgo proporcional de Cox [CPH] es comprobar cómo otras variables pueden influir en la supervivencia del individuo observado.

Analicémoslo.

Comenzamos eligiendo algunas covariables Filtramos el conjunto de datos Creamos una instancia del modelo Ajustamos el modelo n.° 1. Preparamos los datos para el modelo df_model = df[cols_to_use].dropna() # 2. Inicializar y ajustar el modelo de Cox # Usar el penalizador para estabilizar las matemáticas si no convergen. cph = CoxPHFitter(penalizer=0.1) cph.fit(df_model, duration_col='Subscription Longitud', event_col='Churn') # 3. Mostrar los resultados cph.print_summary() # 4. Visualizar la influencia de las covariables cph.plot()

Este es nuestro hermoso resultado.

Modelo CPH. Imagen del autor.

¿Cómo podemos interpretar esto?

La línea vertical discontinua en 0,0 es el punto neutral.

Si el punto de una variable se sitúa en 0, no tiene ningún efecto sobre la deserción. A la derecha (> 0): aumenta el peligro (hace que el abandono sea más rápido). A la izquierda (< 0): Disminuye el peligro (hace que el cliente permanezca más tiempo). En la mesa, la columna más importante para las partes interesadas del negocio es la Ración de Riesgo exp(coef). Nos dice el efecto multiplicador sobre el riesgo de abandono.

[TABLA] Quejas (5.36): Un cliente que se queja tiene 5,36 veces (o 436%) más probabilidades de abandonar en un momento dado que un cliente que no se queja. Este es un efecto masivo.

[GRÁFICO] Quejas (alto riesgo): Este es nuestro predictor más sólido. Los clientes con quejas tienen aproximadamente 5,4 veces más probabilidades de abandonar en un momento dado en comparación con aquellos que no las tienen.

[TABLA] Frecuencia de uso (0,99): si bien el valor p dice que esto es técnicamente significativo, un HR de 0,99 es efectivamente 1. Significa que el impacto en la deserción es insignificante (solo un cambio del 1%).

[GRÁFICO] Frecuencia de uso (Neutral): El cuadrado se encuentra casi exactamente en la línea 0.0. En este modelo específico, la frecuencia con la que un cliente utiliza el servicio no cambia significativamente cuando abandona el servicio.

[TABLA] Monto del cargo (0,83): por cada aumento de una unidad en el cargo, el riesgo de abandono se reduce en un 17 % ($1 – 0,83 = 0,17 $). Los clientes que pagan más son más estables.

[GRÁFICO] Monto del cargo (Factor de protección): El cuadrado está a la izquierda de la línea cero. Los cargos más altos están asociados con un menor riesgo de abandono.

También podemos echar un vistazo a las funciones de Supervivencia y Peligro de este modelo.

Funciones de Supervivencia y Peligro del modelo CPH. Imagen del autor.

La curva es similar al modelo KM. Comparemos la probabilidad de supervivencia en el mismo mes 34.

# Extraiga la probabilidad de supervivencia inicial en el momento 34 survival_at_34 = cph.baseline_survival_.loc[34]print(f"Probabilidad inicial de supervivencia en el período 34: {survival_at_34.values[0]:.4f}") Probabilidad de supervivencia inicial en el período 34: 0,9294

Es casi un 3% más alto, ~93%

Y para cerrar este artículo, elijamos dos clientes diferentes, uno sin quejas y otro con quejas, y comparemos sus probabilidades de supervivencia al mes 34.

# 1. Elija un cliente (o prediga uno nuevo) individual = df_model.iloc[[110,111]] # 2. Prediga su curva de supervivencia completa pred_survival = cph.predict_survival_function(individual) # 3. Obtenga el valor en el momento 34 prob110_at_34 = pred_survival.loc[34].valores[0]prob111_at_34 = pred_survival.loc[34].valores[1]print(f"Cliente 110 (sin quejas) Probabilidad de 'Sobrevivir' al período 34: {prob110_at_34:.2%}") print(f"Cliente 111 (sí quejas) Probabilidad de 'Sobrevivir' al período 34: {prob111_at_34:.2%}") Cliente 110 (sin quejas) Probabilidad de 'Sobrevivir' al periodo 34: 93,94% Cliente 111 (sí quejas) Probabilidad de 'Sobrevivir' al periodo 34: 61,68%

Gran diferencia, ¿eh? Más del 30%. Y finalmente podemos calcular el tiempo en meses en el que se espera que cada cliente abandone.

# Tiempo hasta la deserción (vida esperada) por cliente pred_churn = cph.predict_expectation(df_model.iloc[[110,111]]) # Obtener los valores en meses prob110_churn = pred_churn.loc[110]prob111_churn = pred_churn.loc[111]print(f"Cliente 110 (sin quejas) abandono esperado en: {prob110_churn: .0f} meses") print(f"Cliente 111 (sí compaints) abandono esperado en: {prob111_churn:.0f} meses") Cliente 110 (sin quejas) abandono esperado en: 41 meses Cliente 111 (sí compaints) abandono esperado en: 31 meses

Definitivamente, las quejas marcan la diferencia en la deserción de esta empresa Telco.

Antes de ir

Bueno, el análisis de supervivencia es mucho más que una simple función estadística. Las empresas pueden utilizarlo para comprender el comportamiento de los clientes.

Los modelos de riesgo proporcional de Kaplan-Meier y Cox brindan información útil sobre la longevidad de los suscriptores. Hemos visto cómo variables como el valor del cliente y las quejas sobre el servicio afectan directamente la deserción, lo que permite a los tomadores de decisiones seguir estrategias de retención más específicas.

Los profesionales de datos que comprenden estos modelos pueden crear una herramienta poderosa para que las empresas mejoren su relación con su base de usuarios. Utilice estas herramientas para mantenerse a la vanguardia. Literalmente.

Si te gustó este contenido, búscame en mi sitio web.

https://gustavorsantos.me

Repositorio GitHub

https://github.com/gurezende/Survival-Analysis

Referencias

[1. Definición de análisis de supervivencia] (https://en.wikipedia.org/wiki/Survival_analysis)

[2. La introducción completa al análisis de supervivencia en Python] (https://medium.com/data-science/the-complete-introduction-to-survival-analysis-in-python-7523e17737e6)

[3. Introducción al análisis de supervivencia del cliente: comprensión de la vida útil del cliente] (https://medium.com/@slavyolov/introduction-to-customer-survival-analysis-understanding-customer-lifetimes-6e4ba41d7724)

[4. Guía definitiva para el análisis de supervivencia] (https://www.graphpad.com/guides/survival-analysis)

[5. ¿Cuál es la diferencia entre la relación de riesgos proporcionales de Kaplan-Meier (KM) y Cox (CPH)?] (https://www.droracle.ai/articles/218904/what-is-the-difference-between-kaplan-meier-km-and-cox)

[6. Documentación de Lifelines] (https://lifelines.readthedocs.io/en/latest/)

[7. Análisis de supervivencia en R para principiantes] (https://www.datacamp.com/tutorial/survival-analysis-R)