
Un guide d’analyse de survie avec Python : utilisation de modèles de temps d’événement pour prévoir la durée de vie des clients
à de nombreux domaines de connaissances, nous aidant à faire face à l’incertitude, à calculer les probabilités et à prendre des décisions en cours de route.
L’industrie médicale est l’un des domaines qui s’appuie fortement sur les statistiques, en utilisant des outils tels que les tests T, les tests A/B ou l’analyse de survie. C’est cette dernière qui fait l’objet de cet article.
L’analyse de la survie trouve son origine dans les sciences médicales et biologiques, où l’on essayait de modéliser, comme principal objectif événementla mort d’un patient ou d’un organisme. C’est la raison du nom.
Cependant, les statisticiens ont compris que cette analyse était si puissante qu’elle pouvait être appliquée à de nombreux autres domaines de la vie, et s’est donc étendue au domaine des affaires, encore plus après l’essor de la Data Science.
Apprenons-en davantage.
Analyse de survie
Analyse de survie [SA] est une branche des statistiques utilisée pour prédire le le temps qu’il faut pour qu’un événement spécifique se produise.[1]
Aussi connu sous le nom Délai jusqu’à l’événementcette étude peut déterminer combien de temps il faudra pour qu’un événement se produise tout en tenant compte du fait que certains événements ne se sont pas encore produits au moment de la collecte des données.
Les exemples ne se trouvent pas seulement dans les sciences médicales et biologiques, mais partout.
- Temps jusqu’à ce qu’une machine tombe en panne
- Délai jusqu’à ce qu’un client annule un abonnement
- Temps jusqu’à ce que le client achète à nouveau
Maintenant, étant donné que nous essayons d’estimer un nombre plutôt qu’un groupe ou une classe, cela signifie que nous avons affaire à un type de problème de régression. Alors pourquoi ne pouvons-nous pas utiliser la régression linéaire OLS ?
Pourquoi utiliser l’analyse de survie ?
Les modèles de régression standard comme OLS ou Logistic Regression ont du mal avec les données de survie car ils sont conçus pour gérer des événements terminés, et non des histoires « en cours ».
Imaginez que vous vouliez prédire qui a terminé une course de 10 milles, mais que les données d’entrée sont un événement qui se poursuit. La course dure 2 heures et vous souhaitez utiliser les données dont vous disposez jusqu’à présent pour estimer quelque chose.
Les algorithmes de régression réguliers échoueront parce que :
- MOL: Vous disposez uniquement des données de ceux qui ont déjà terminé la course. Utiliser uniquement leurs données créera un énorme biais en faveur des personnes plus rapides.
- Régression logistique: Il peut probablement dire si quelqu’un a terminé la course, mais il traite ceux qui ont terminé en 30 minutes de la même manière que ceux qui ont terminé en 8 heures.
Les principes fondamentaux de l’analyse de survie
Passons en revue quelques concepts importants pour comprendre l’analyse de survie.
Premièrement, nous devons comprendre la naissance et la mort d’un point de données.
- Naissance: Le moment où nous avons commencé à mesurer ce point de données. Par exemple, au moment où un patient reçoit un diagnostic de cancer ou le jour où une personne est embauchée par une entreprise. Notez qu’il n’est pas nécessaire que les observations commencent toutes en même temps.
- La mort: Cela se produit lors de la survenance de l’événement d’intérêt. Le jour où le salarié a quitté l’entreprise.
Or, ce qui est intéressant avec l’AS, c’est que l’étude ou l’observation peut se terminer avant l’événement se produit. Dans ce cas, nous aurons un autre concept important : le point de données censuré.
- Censure (Non-mort): Si l’étude se termine ou si un sujet abandonne avant que l’événement ne se produise, les données sont « censurées », ce qui signifie que nous savons seulement qu’il a survécu au moins jusqu’à ce point.
Les données peuvent cependant être censurées de différentes manières.
- Censure à droite: Le plus courant. L’événement se produit après la fin de la période d’observation ou après l’abandon du sujet.

- Censure à gauche: L’événement s’est produit avant le début de l’étude.
Super. Il est important de noter que l’analyse de survie est un moyen d’estimer la probabilité qu’un événement se produise en fonction du temps. En traitant la survie en fonction du temps, nous pouvons répondre à des questions qu’un seul score de probabilité ne peut pas répondre, telles que : « À quel mois précis le risque de désabonnement des clients atteint-il son maximum ?
Maintenant que nous connaissons les bases, apprenons-en davantage sur les fonctions impliquées dans SA.
Fonction de survie
La fonction de survie St) exprime le probabilité que l’événement ne se produise pas en fonction du temps. Elle diminuera naturellement avec le temps, puisque de plus en plus d’individus vivront l’événement.
Ainsi, en l’appliquant à notre exemple de désabonnement des employés, nous verrions la probabilité qu’un employé soit toujours dans l’entreprise après N ans.

Fonction de danger
La fonction de hasard indique la probabilité qu’un événement se produise à un moment donné. C’est l’opposé de la fonction de survie, et représente le risque de désabonnement (au lieu de la probabilité de rester dans l’entreprise).
Cette fonction calculera quelle est la probabilité que les employés qui n’ont pas quitté leur emploi jusqu’à présent le fassent à partir de ce moment-là.

Choisir votre modèle pour l’analyse de survie
Comme vous le voyez, SA est un sujet qui peut devenir très rapidement profond et dense. Mais essayons de rester simple.
Deux modèles principaux sont utilisés lors de l’analyse de survie. L’un est le Kaplan-Meierqui est plus simple mais ne prend pas en compte l’effet de variables prédictives supplémentaires, et nécessite quelques hypothèses pour fonctionner.
L’autre est le Risque proportionnel de Cox modèle, qui est la norme de l’industrie car il peut intégrer d’autres variables dans le modèle, il est mathématiquement plus stable et il fonctionne bien même si certaines hypothèses ne sont pas respectées.
Apprenons-en davantage à leur sujet.
Kaplan-Meier
- Fonctionne bien avec les données censurées à droite (vous vous souvenez ? lorsque l’événement se produit après la fin de la période d’observation)
- Modèle intuitif
- Non paramétrique : ne suit aucune distribution
- Des hypothèses sont requises, comme les abandons ne sont pas liés à l’événement ; L’heure d’entrée n’affecte pas le risque de survie ; et les heures des événements sont connues avec précision.
- Renvoie un fonction de survie ça ressemble à un escalier
Quand utiliser :
- Analyse de survie simple sans autres covariables ou prédicteurs.
- Idéal pour des visualisations rapides.
Risque proportionnel de Cox
- Norme industrielle
- Accepte des prédicteurs ou des covariables supplémentaires
- Fonctionne bien même si certaines hypothèses ne sont pas respectées
- estime un fonction de dangerqui ont tendance à être plus stables que les fonctions de survie
Quand utiliser :
- Estimation sur des données avec plusieurs variables prédictives (covariables).
Ensuite, mettons la main sur du code.
Code
Dans cette section, nous apprendrons comment modéliser une SA en utilisant les deux modèles présentés précédemment.
L’ensemble de données choisi pour cet exercice est le Désabonnement des clients des télécommunicationsque vous pouvez trouver dans le référentiel UCI Machine Learning sous licence Creative Commons.

Ensuite, importons les packages nécessaires.
# Data
from ucimlrepo import fetch_ucirepo
# Data Wrangling
import pandas as pd
import numpy as np
# DataViz
import matplotlib.pyplot as plt
import seaborn as sns
# Lifelines Survival Analysis
from lifelines import KaplanMeierFitter
from lifelines import CoxPHFitter
# fetch dataset
telco_churn = fetch_ucirepo(id=563)
# data (as pandas dataframes)
X = telco_churn.data.features
y = telco_churn.data.targets
# Pandas df
df = pd.concat([X, y], axis=1)
df.head(3)
Implémentation de Kaplan-Meier
Maintenant, comme mentionné, le Kaplan-Meier [KM] Le modèle est vraiment simple et direct à utiliser, constituant un bon choix pour les visualisations. Tout ce dont nous avons besoin, ce sont deux variables : un prédicteur et une étiquette.
Ensuite, nous pouvons instancier le modèle KM et l’adapter aux données, en utilisant Subscription Length (total des mois d’abonnement) comme prédicteur, et Churn comme l’a observé l’événement.
# Instantiate K-M
kmf = KaplanMeierFitter()
# Fit the model
kmf.fit(df['Subscription Length'],
event_observed=df['Churn'],
label= 'Customer Churn')
Fait. Ensuite, nous pouvons visualiser la fonction de survie.
# Plot survival curve
plt.figure(figsize=(12, 5))
kmf.plot_survival_function()
plt.title('Kaplan-Meier Survival Curve: Telco Customer Lifetime')
plt.xlabel('Time (months)')
plt.ylabel('Probability of Remaining Subscribed')
plt.grid(True)
plt.show()
C’est tellement génial ! On constate que plus de 90 % des clients restent chez l’entreprise Télécom pendant environ 35 mois.

Si nous voulons confirmer, nous pouvons facilement coder cela pour apprendre que 90 % restent dans l’entreprise pendant 34 mois, en fait.
# Checking survival rate at 34 months
kmf.survival_function_at_times(34)
Customer Churn
34 0.900613
Si nous voulons savoir quel est le moment médian auquel les gens se désabonnent, nous pouvons utiliser l’attribut de KM. .median_survival_time_. C’est le moment
# Time
median_survival = kmf.median_survival_time_
print(f"Median Customer Lifetime: {median_survival} months")
Nous pouvons également effectuer d’autres analyses, telles que des comparaisons entre groupes. Imaginez que cette entreprise de télécommunications classe ses clients en deux groupes :
- Gros utilisateurs:
Frequency of Use > median - Utilisateurs logiciels:
Frequency of Use <= median
Nous pouvons comparer les deux fonctions de survie de ces deux groupes.
# Column Groups
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('Kaplan-Meier Survival Curve: Telco Customer Lifetime')
plt.xlabel('Time (months)')
plt.ylabel('Probability Churn')
# Fit the model for Soft users and plot
kmf.fit(df[df.Heavy_User == 0]['Subscription Length'], df[df.Heavy_User == 0]['Churn'], label='Soft User')
ax = kmf.plot_survival_function()
# Fit the model for Heavy users and plot
kmf.fit(df[df.Heavy_User == 1]['Subscription Length'], df[df.Heavy_User == 1]['Churn'], label='Heavy User')
ax = kmf.plot_survival_function(ax=ax)
plt.show()
Et voilà. Alors que les gros utilisateurs restent fidèles à l’entreprise tout au long de la période, les utilisateurs logiciels se désintéresseront rapidement après le 30e mois. Leur durée médiane de survie est de 40 mois.

Lorsque vous comparez des groupes, vous devez vous assurer que la différence est statistiquement significative. Pour cela, le forfait lifelines le test de log-rank a-t-il été mis en œuvre. Il s’agit d’un test d’hypothèse :
- Ho (hypothèse nulle): Les courbes de survie des deux populations ne diffèrent pas.
- Ha (hypothèse alternative) : Les courbes de survie des deux populations sont différentes.
from lifelines.statistics import logrank_test
# 3. Perform the Log-Rank Test
results = logrank_test(df[df.Heavy_User == 0]['Subscription Length'],
df[df.Heavy_User == 1]['Subscription Length'],
event_observed_A= df[df.Heavy_User == 0]['Churn'],
event_observed_B= df[df.Heavy_User == 1]['Churn'])
# 4. Print Results
print(f"P-value: {results.p_value}")
print(f"Test Statistic: {results.test_statistic}")
if results.p_value < 0.05:
print("Result: Statistically significant difference between groups.")
else:
print("Result: No significant difference detected.")
P-value: 7.23487469906141e-103
Test Statistic: 463.7794219211866
Result: Statistically significant difference between groups.
Mise en œuvre du risque proportionnel de Cox
La première chose sympa que vous pouvez faire avec le Cox Proportional Hazard [CPH] Le modèle vérifie comment d’autres variables peuvent influencer la survie de l’individu observé.
Décomposons-le.
- Nous commençons par choisir quelques covariables
- Nous filtrons l’ensemble de données
- Instancier le modèle
- Ajuster le modèle
# 1. Prepare the data
# Selecting the time, the event, and our chosen covariates
cols_to_use = [
'Subscription Length', # Time
'Churn', # Event (E)
'Charge Amount', # Covariate 1
'Complains', # Covariate 2
'Frequency of use' # Covariate 3
]
# Dropping any missing values for the model
df_model = df[cols_to_use].dropna()
# 2. Initialize and fit the Cox model
# Use the penalizer to stabilize the math if not converging.
cph = CoxPHFitter(penalizer=0.1)
cph.fit(df_model,
duration_col='Subscription Length',
event_col='Churn')
# 3. Display the results
cph.print_summary()
# 4. Visualize the influence of covariates
cph.plot()
C’est notre beau résultat.

Comment peut-on interpréter cela ?
La ligne verticale pointillée à 0,0 est le point neutre.
- Si le point d’une variable se situe à 0cela n’a aucun effet sur le taux de désabonnement.
- À droite (> 0) : Augmente le danger (rend le taux de désabonnement plus rapide).
- À gauche (< 0) : Diminue le danger (permet au client de rester plus longtemps).
- Sur la table, la colonne la plus importante pour les acteurs économiques est le ratio de risque.
exp(coef). Il nous dit le multiplicateur effet sur le risque de désabonnement.
[TABLE] Se plaint (5.36) : Un client qui se plaint est 5,36 fois (ou 436 %) plus probable à un moment donné qu’un client qui ne se plaint pas. C’est un effet massif.
[GRAPHIC] Plaintes (danger élevé) : C’est notre prédicteur le plus puissant. Les clients ayant des plaintes sont à peu près 5,4 fois plus probable se déstabiliser à tout moment par rapport à ceux qui ne le font pas.
[TABLE] Fréquence d’utilisation (0,99) : Bien que la valeur p indique que cela est techniquement significatif, un HR de 0,99 équivaut en réalité à 1. Cela signifie que l’impact sur le taux de désabonnement est négligeable (seulement un changement de 1 %).
[GRAPHIC] Fréquence d’utilisation (neutre) : Le carré se situe presque exactement sur la ligne 0,0. Dans ce modèle spécifique, la fréquence à laquelle un client utilise le service ne change pas de manière significative quand ils s’agitent.
[TABLE] Montant des frais (0,83) : Pour chaque augmentation de charge d’une unité, le risque de désabonnement baisse de 17% (1 $ – 0,83 = 0,17 $). Les clients les mieux payés sont plus stables.
[GRAPHIC] Montant des frais (facteur de protection) : Le carré est à gauche de la ligne zéro. Des frais plus élevés sont associés à un inférieur risque de désabonnement.
Nous pouvons également jeter un œil aux fonctions Survie et Risque pour ce modèle.

La courbe est similaire au modèle KM. Comparons la probabilité de survie au même 34ème mois.
# Extract the baseline survival probability at time 34
survival_at_34 = cph.baseline_survival_.loc[34]
print(f"Baseline Survival Probability at period 34: {survival_at_34.values[0]:.4f}")
Baseline Survival Probability at period 34: 0.9294
Il est près de 3 % plus élevé, à ~93 %
Et pour clôturer cet article, choisissons deux clients différents, l’un sans plainte et l’autre avec plainte, et comparons leurs probabilités de survie au 34ème mois.
# 1. Pick a customer (or predict for a new one)
individual = df_model.iloc[[110,111]]
# 2. Predict their full survival curve
pred_survival = cph.predict_survival_function(individual)
# 3. Get the value at time 34
prob110_at_34 = pred_survival.loc[34].values[0]
prob111_at_34 = pred_survival.loc[34].values[1]
print(f"Customer 110 (no complaints) Probability of 'Surviving' to period 34: {prob110_at_34:.2%}")
print(f"Customer 111 (yes compaints) Probability of 'Surviving' to period 34: {prob111_at_34:.2%}")
Customer 110 (no complaints) Probability of 'Surviving' to period 34: 93.94%
Customer 111 (yes compaints) Probability of 'Surviving' to period 34: 61.68%
Grosse différence, hein ? Plus de 30 %. Et nous pouvons enfin calculer le temps en mois pendant lequel chaque client est censé se désinscrire.
# Time Until Churn (Expected life) by customer
pred_churn = cph.predict_expectation(df_model.iloc[[110,111]])
# Get the values in months
prob110_churn = pred_churn.loc[110]
prob111_churn = pred_churn.loc[111]
print(f"Customer 110 (no complaints) expected churn at: {prob110_churn: .0f} months")
print(f"Customer 111 (yes compaints) expected churn at: {prob111_churn:.0f} months")
Customer 110 (no complaints) expected churn at: 41 months
Customer 111 (yes compaints) expected churn at: 31 months
Il est certain que les plaintes font une différence dans le taux de désabonnement pour cette société de télécommunications.
Avant de partir
Eh bien, l’analyse de survie est bien plus qu’une simple fonction statistique. Les entreprises peuvent l’utiliser pour comprendre le comportement des clients.
Les modèles de risque proportionnel de Kaplan-Meier et Cox fournissent des informations exploitables sur la longévité des abonnés. Nous avons vu comment des variables telles que la valeur client et les plaintes liées au service affectent directement le taux de désabonnement, permettant aux décideurs de poursuivre des stratégies de fidélisation plus ciblées.
Les professionnels des données qui comprennent ces modèles peuvent créer un outil puissant permettant aux entreprises d’améliorer leurs relations avec leur base d’utilisateurs. Utilisez ces outils pour garder une longueur d’avance. Littéralement.
Si vous avez aimé ce contenu, retrouvez-moi sur mon site Internet.
Dépôt GitHub
https://github.com/gurezende/Survival-Analysis
Références
[1. Survival Analysis Definition] (https://en.wikipedia.org/wiki/Survival_analysis)
[2. The Complete Introduction to Survival Analysis in Python] (https://medium.com/data-science/the-complete-introduction-to-survival-analysis-in-python-7523e17737e6)
[3. Introduction to Customer Survival Analysis: Understanding Customer Lifetimes] (https://medium.com/@slavyolov/introduction-to-customer-survival-analysis-understanding-customer-lifetimes-6e4ba41d7724)
[4. Ultimate Guide to Survival Analysis] (https://www.graphpad.com/guides/survival-analysis)
[5. What is the difference between Kaplan-Meier (KM) and Cox Proportional Hazards (CPH) ratio?] (https://www.droracle.ai/articles/218904/what-is-the-difference-between-kaplan-meier-km-and-cox)
[6. Lifelines Documentation] (https://lifelines.readthedocs.io/en/latest/)
[7. Survival Analysis in R For Beginners] (https://www.datacamp.com/tutorial/survival-analysis-R)



