Vai al contenuto principale
Modelli predittivi per LTV e churn - immagine ufficiale della lezione su GinnyTech, creata da AD

Modelli predittivi per LTV e churn

Costruire modelli predittivi per Customer Lifetime Value e churn probability nel marketing.

AD
Creato daAndrii Dyshkantiuk
Lezione 87 / 236Livello: AvanzatoDurata: 22 minPrerequisiti: 1

Cosa imparerai

  • Costruire feature di churn da recency, trend di utilizzo, attrito e tenure
  • Valutare il modello con AUC, precision nel top 20% e lift invece dell'accuracy
  • Stimare l'LTV con BG-NBD/Gamma-Gamma o Gradient Boosting secondo il contesto

Modelli predittivi per LTV e churn

Capire chi sta per andarsene e quanto vale chi resta è uno dei compiti più richiesti in azienda, e si risolve con tabelle di feature, modelli tabellari e pipeline di scoring. I modelli di churn e LTV ordinano i clienti per rischio di abbandono e valore atteso, così investi solo dove il recupero supera il costo di intervento. Qui impari a costruirli, valutarli e metterli in produzione.

Che cosa fanno i modelli di churn e LTV

I modelli di churn e LTV ordinano i clienti per rischio di abbandono e valore atteso per investire solo dove il recupero supera il costo di intervento.

La procedura in cinque passaggi

Ecco la sequenza che seguiamo per costruire e mettere in produzione questi modelli.

  1. Definisci churn a 30 giorni e orizzonte LTV a 12 mesi con unità cliente.
  2. Ingegnerizza recency, trend di utilizzo, attrito, engagement e tenure.
  3. Valuta con AUC, precision nel top 20 per cento e lift, mai con accuracy.
  4. Stima LTV con metodo probabilistico o Gradient Boosting secondo il contesto.
  5. Attiva scoring giornaliero con soglia di degrado e segmentazione per azione.

Le feature che predicono il churn

Le feature più predittive di churn, confermate su decine di implementazioni, seguono un ordine abbastanza stabile. Il singolo miglior predittore, quasi universalmente, è la recency, cioè i giorni dall’ultima azione significativa. Subito dopo viene il trend di utilizzo, dove la direzione conta più del livello assoluto. Pesano poi gli eventi negativi come pagamenti falliti, ticket di supporto o downgrade di piano. Contano inoltre l’engagement depth, cioè quante feature core il cliente usa abitualmente, e infine la tenure: i clienti nuovi churnano più degli storici, un paradosso solo apparente.

df['recency'] = (df['today'] - df['last_active_date']).dt.days
df['usage_trend'] = df['active_days_last_14'] / df['active_days_prev_14'].clip(lower=1)
df['has_payment_failure'] = (df['failed_payments_30d'] > 0).astype(int)
df['engagement_depth'] = df[['feature_A', 'feature_B', 'feature_C', 'feature_D']].sum(axis=1)
df['tenure_months'] = (df['today'] - df['signup_date']).dt.days / 30.44

Attenzione a non valutare mai il modello con l’accuracy su dataset sbilanciati. Con un churn rate del 5 per cento, un modello che dice sempre no churn raggiunge il 95 per cento di accuracy ed è completamente inutile. Le metriche corrette sono AUC-ROC con soglia buona sopra 0.80, precision nel top 20 per cento dei clienti più a rischio, e lift.

Due approcci per prevedere l’LTV

Per il retail e l’ecommerce con acquisti discreti e non a subscription, l’approccio probabilistico BG-NBD più Gamma-Gamma modella frequenza e valore come processi stocastici.

from lifetimes import BetaGeoFitter, GammaGammaFitter

# BG/NBD per frequenza acquisti futuri
bgf = BetaGeoFitter(penalizer_coef=0.01)
bgf.fit(df['frequency'], df['recency'], df['T'])

# Gamma-Gamma per valore medio per acquisto
ggf = GammaGammaFitter(penalizer_coef=0.01)
ggf.fit(df['frequency'], df['monetary_value'])

# LTV predetto a 12 mesi
ltv_12m = ggf.customer_lifetime_value(
    bgf, df['frequency'], df['recency'], df['T'],
    df['monetary_value'], time=12, discount_rate=0.01)

Il vantaggio è che resta interpretabile, robusto e basato su assunzioni esplicite. Il limite è che funziona solo con pattern di acquisto discreti, non con le subscription.

Per il SaaS, le subscription o i dati con molte feature comportamentali conviene un Gradient Boosting Regression.

from sklearn.ensemble import HistGradientBoostingRegressor
from sklearn.model_selection import TimeSeriesSplit

tscv = TimeSeriesSplit(n_splits=5)

model = HistGradientBoostingRegressor(
    max_iter=200, max_depth=5, learning_rate=0.05,
    early_stopping=True, validation_fraction=0.1, random_state=42)

# Feature: comportamento prime 4 settimane
features = ['w1_sessions', 'w2_sessions', 'w3_sessions', 'w4_sessions',
            'features_used_w4', 'support_tickets_w4', 'plan_type',
            'acquisition_source', 'country', 'device_type']

model.fit(X_train, y_train)
predicted_ltv = model.predict(X_test)

È flessibile, cattura relazioni non lineari e gestisce molte feature, ma è meno interpretabile e richiede più dati.

Verdetto: BG-NBD con Gamma-Gamma per acquisti discreti retail, Gradient Boosting per subscription e tabelle comportamentali ricche.

Mandare il modello in produzione

In produzione il modello vive dentro una pipeline di scoring batch che gira ogni giorno. Carica il modello salvato, estrae le feature dal warehouse, calcola la probabilità di churn e scrive il risultato su una tabella di activation. I clienti risultano già segmentati per azione.

# Pipeline di scoring batch (giornaliera)

# Carica modello
model = joblib.load('models/churn_model_v3.joblib')

# Estrai feature da warehouse
query = """
SELECT c.customer_id,
       DATEDIFF('day', c.last_active, CURRENT_DATE) AS recency,
       ...
FROM customers c
LEFT JOIN activity a ON c.customer_id = a.customer_id
"""
df = pd.read_sql(query, warehouse_engine)

# Predici
df['churn_probability'] = model.predict_proba(df[feature_cols])[:, 1]

# Segmenta per azione
df['action'] = pd.cut(df['churn_probability'],
    bins=[0, 0.3, 0.6, 0.8, 1.0],
    labels=['low_risk', 'monitor', 'high_risk', 'critical'])

# Scrivi su tabella di activation
df[['customer_id', 'churn_probability', 'action']].to_sql(
    'mrt_activation__churn_prediction', warehouse_engine,
    if_exists='replace', index=False)

Monitorare il modello nel tempo

I modelli predittivi degradano perché il comportamento dei clienti cambia. Il controllo minimo verifica l’AUC sul periodo recente. Misura poi il drift delle feature con un test di Kolmogorov-Smirnov e lancia un alert quando l’AUC scende sotto soglia.

def check_model_health(recent_data, actual_outcomes):
    # Predici sul periodo recente
    preds = model.predict_proba(recent_data[feature_cols])[:, 1]
    auc = roc_auc_score(actual_outcomes['churned'], preds)

    # Verifica feature drift
    for col in feature_cols:
        ks_stat = ks_2samp(
            training_data[col].dropna(),
            recent_data[col].dropna()
        ).statistic
        if ks_stat > 0.15:  # feature significativamente diversa dal training
            print(f"WARNING: {col} distribution shifted (KS={ks_stat:.3f})")

    # Alert se AUC scende sotto soglia
    if auc < AUC_THRESHOLD_ALERT:
        send_alert(f"Model AUC dropped to {auc:.3f}")

Un modello in produzione è un processo continuo, non un artefatto statico.

Controllo di qualità e lettura per segmenti

Prima di usare un modello di LTV o churn in una decisione, controlla sempre completezza, duplicati, timezone, definizioni cambiate e segmenti esclusi. La media aggregata è solo il punto di partenza. Segmenta per canale, coorte, piano, paese, device e maturità dell’utente. Se due segmenti si muovono in direzioni opposte, la media non rappresenta nessuno dei due e può portare a una scelta sbagliata. Ogni analisi deve chiudersi con una decisione possibile. Se il modello non cambia una decisione, manca ancora il collegamento tra metrica e azione.

Un caso che fa riflettere: Netflix

Nel terzo trimestre 2011 Netflix perse circa 800000 abbonati negli Stati Uniti dopo aumento dei prezzi e annuncio della separazione in due servizi. La base passò da circa 24 milioni a circa 23.2 milioni di abbonati in un trimestre. Il titolo crollò di oltre il 70 per cento dai massimi e la società ritirò il piano di separazione. Il caso resta il manuale del churn da prezzo: recency e ticket di protesta anticiparono l’abbandono prima dei report finanziari.

Domande per l’autoverifica

  1. Quale feature tra recency e trend di utilizzo anticipa meglio l’abbandono?
  2. Quale metrica sostituisce l’accuracy su dataset con churn al 5 per cento?
  3. Quale approccio LTV scegli tra probabilistico e Gradient Boosting?
  4. Quale soglia di AUC fa scattare retraining in produzione?
Serve una mano concreta?

Bloccato su questo argomento o vuoi applicarlo al tuo caso? Prenota una call di 15 minuti con un analista esperto.

Prenota una call