Epsilon Decay: quando [math]\epsilon[/math]-Greedy inizia a diventare intelligente
Finora abbiamo visto come l’algoritmo [math]\epsilon[/math]-Greedy riesca a bilanciare l’eterno dilemma tra esplorazione e sfruttamento alternando due comportamenti netti: con una probabilità [math]\epsilon[/math] esplora l’ignoto, mentre con una probabilità [math]1 – \epsilon[/math] sfrutta la migliore opzione nota fino a quel momento.
L’approccio è un ottimo punto di partenza, ma si porta dietro un’inefficienza strutturale.
Supponiamo di impostare un classico [math]\epsilon = 0.1[/math].
Ciò significa che il sistema continuerà a esplorare il 10% delle volte, per sempre.
A prima vista potrebbe sembrare un prezzo accettabile da pagare per mantenere il sistema aggiornato. In realtà, su larga scala, questa rigidità si trasforma in un salasso in termini di performance.
Nelle prime cento osservazioni, l’algoritmo non sa quasi nulla dei video a disposizione: avrebbe un disperato bisogno di esplorare per raccogliere dati.
Dopo milioni di visualizzazioni, al contrario, dispone di stime solidissime e altamente affidabili.
Continuare a investire il 10% del traffico in test casuali quando si conoscono già i vincitori è puramente inefficiente. È come se uno studente continuasse a tirare a indovinare le risposte di un esame anche dopo aver studiato perfettamente l’intero programma.
O, ancora, immagina di aver trovato il tragitto più veloce per andare in ufficio, ma una volta ogni dieci giorni decidi comunque di imboccare una via a caso per “vedere se c’è meno traffico”. Il primo mese ha senso per testare le alternative. Dopo un anno, è solo uno spreco di tempo e benzina.
Nel Machine Learning, e in particolare nei sistemi di raccomandazione, questo spreco si chiama “esplorazione inefficiente”. Se impostiamo un classico [math]\epsilon = 0.1[/math], il sistema continuerà a testare opzioni subottimali nel 10% dei casi, per sempre.
Vediamo come l’Epsilon Decay risolve questa inefficienza, insegnando all’algoritmo a fidarsi gradualmente della propria esperienza.
L’intuizione dietro l’Epsilon Decay
La soluzione a questo spreco di risorse ricalca fedelmente il modo in cui noi esseri umani accumuliamo esperienza nel corso della vita: all’inizio esploro molto, poi sempre meno.
- Fase iniziale ([math]\epsilon \approx 1[/math]): Non abbiamo dati. Muoversi alla cieca è l’unico modo per mappare l’ambiente. Quasi tutte le decisioni del sistema sono puramente esplorative.
- Fase intermedia: Abbiamo raccolto evidenze sufficienti per iniziare a separare i contenuti spazzatura da quelli promettenti. La quota di esplorazione si riduce progressivamente a vantaggio dello sfruttamento.
- Fase finale ([math]\epsilon \approx 0[/math]): Le stime del CTR sono ormai cristallizzate e precise. Il sistema va sul sicuro, riservando all’esplorazione una percentuale minima, quasi impercettibile.
Per tradurre questa intuizione in codice, la Data Science si affida principalmente a due strategie di decadimento.
Strategia 1: Decadimento Inverso
La formula più immediata per ridurre la spregiudicatezza dell’algoritmo si basa sul calcolo del tempo (o delle iterazioni) trascorso:
[math]\epsilon_t = \frac{c}{t}[/math]
Dove [math]t[/math] rappresenta il numero di iterazioni correnti e [math]c[/math] è una costante di bilanciamento. Man mano che il denominatore [math]t[/math] cresce, il valore di [math]\epsilon_t[/math] si riduce in modo automatico. Il limite di questo approccio è la sua aggressività: la curva tende a precipitare troppo rapidamente nei primissimi istanti, rischiando di azzerare l’esplorazione prima che l’algoritmo abbia strutturato un campione statistico minimamente attendibile.
Strategia 2: Decadimento Esponenziale
Nella pratica industriale e nei sistemi di raccomandazione di colossi come Netflix o Spotify, la scelta ricade quasi sempre sul decadimento esponenziale, regolato dalla formula:
[math]\epsilon_t = \epsilon_{t-1} \cdot \alpha[/math]
Il parametro [math]\alpha[/math] rappresenta il decay rate (tasso di decadimento), il cui valore viene rigidamente compreso tra [math]0.99[/math] e [math]1[/math]. Moltiplicando il vecchio [math]\epsilon[/math] per un fattore come 0.999 a ogni iterazione, la transizione verso una mentalità focalizzata sullo sfruttamento avviene in modo estremamente fluido e controllato.
Curve a confronto
Per capire davvero l’impatto di queste formule, l’ideale è osservare l’andamento del parametro [math]\epsilon[/math] (l’esplorazione) nel tempo su un piano cartesiano:
- [math]\epsilon[/math] Statico: Una linea perfettamente retta e piatta. Il sistema non evolve, non matura e continua a spendere risorse alla cieca dall’inizio alla fine.
- Decadimento Inverso: Una caduta verticale brutale nei primissimi istanti. L’algoritmo smette di esplorare troppo presto, rischiando l’effetto “cecità precoce”.
- Decadimento Esponenziale: Una discesa morbida, controllata e progressiva che scivola dolcemente verso il pavimento minimo dell’1%.

Guardando queste tre traiettorie, salta subito all’occhio quale dinamica rispetti la reale fisiologia dell’apprendimento. La curva esponenziale simula perfettamente lo sviluppo di un’esperienza solida: concede ampio spazio ai colpi di testa iniziali, per poi guidare il sistema verso una saggia e redditizia capitalizzazione delle certezze.
- La linea rossa tratteggiata (Statico): Rimane inchiodata a 0.2 dall’inizio alla fine. Non si adatta al tempo che passa.
- La curva arancione (Inverso): Crolla quasi istantaneamente verso lo zero. A 100 iterazioni ha già smesso praticamente di esplorare, rendendolo troppo drastico per scenari reali.
- La curva verde (Esponenziale): Inizia a 1.0 (esplorazione totale), scende con una pendenza elegante e inizia a stabilizzarsi in modo asintotico verso il limite minimo (0.01). È visivamente l’unica curva che riflette un processo di apprendimento maturo.
La rete di sicurezza: perché serve un limite minimo?
Se ci limitassimo ad applicare ciecamente il decadimento esponenziale, nel lungo periodo il valore di [math]\epsilon[/math] tenderebbe inevitabilmente a zero. Questo scenario è altamente pericoloso in ambienti iper-dinamici come il feed di TikTok. I gusti del pubblico mutano, i vecchi trend passano di moda nel giro di ore e nuovi creator caricano video continuamente.
Un algoritmo che smettesse del tutto di esplorare diventerebbe istantaneamente cieco di fronte alle novità, intrappolando l’utente in una bolla statica. Per disinnescare questo rischio si introduce una costante di sbarramento: epsilon_min = 0.01. In questo modo, l’esplorazione cala, ma non scende mai sotto l’1% permanente, lasciando sempre una piccola finestra aperta per intercettare i cambiamenti del mercato.
L’evoluzione del sistema nel tempo
Nel codice Python, questa logica si traduce in un blocco di aggiornamento dinamico posizionato alla fine di ogni ciclo di visualizzazione:
# Ad ogni iterazione riduciamo epsilon, proteggendo il limite minimo dell'1%
epsilon = max(epsilon_min, epsilon * decay_rate)
Per capire visivamente l’impatto di questa riga di codice, basta osservare come si comporta il parametro [math]\epsilon[/math] nel corso di 10.000 iterazioni simulate con un decay_rate impostato a 0.999:
| Iterazione | Valore di [math]\epsilon[/math] | Comportamento dell’Algoritmo |
|---|---|---|
| 0 | 1.000 | Esplorazione totale (fase di studio) |
| 100 | 0.905 | Orientato all’esplorazione |
| 500 | 0.606 | Bilanciamento instabile |
| 1.000 | 0.368 | Orientato allo sfruttamento |
| 5.000 | 0.010 | Raggiungimento del pavimento minimo |
| 10.000 | 0.010 | Esplorazione di sicurezza (1%) |
Implementazione in Python
Riprendiamo il codice precedente e modifichiamolo per includere l’Epsilon Decay Esponenziale.
import numpy as np
true_ctr = [0.05, 0.08, 0.12, 0.15]
n_arms = len(true_ctr)
counts = np.zeros(n_arms)
rewards = np.zeros(n_arms)
# --- NUOVI PARAMETRI DI OTTIMIZZAZIONE ---
epsilon = 1.0 # Partiamo esplorando sempre (100%)
epsilon_min = 0.01 # Non scendiamo mai sotto l'1% di esplorazione
decay_rate = 0.999 # Velocità con cui l'esplorazione diminuisce
total_reward = 0
for t in range(10000):
# La scelta dipende dall'epsilon corrente
if np.random.rand() < epsilon:
arm = np.random.randint(n_arms)
else:
estimates = rewards / (counts + 1e-5)
arm = np.argmax(estimates)
reward = np.random.rand() < true_ctr[arm]
counts[arm] += 1
rewards[arm] += reward
total_reward += reward
# --- AGGIORNAMENTO DI EPSILON ---
# Riduciamo epsilon, ma non oltre il limite minimo
epsilon = max(epsilon_min, epsilon * decay_rate)
print(f"Click totali generati con Epsilon Decay: {total_reward}")
print(f"Valore finale di Epsilon: {epsilon:.4f}")
Perché questa ottimizzazione è fondamentale?
Se esegui questo codice, otterrai un reward totale molto vicino a quello del Thompson Sampling (solitamente tra 1.470 e 1.485 click), abbattendo drasticamente il Regret rispetto all'[math]\epsilon[/math]-Greedy statico.
All’inizio, il sistema raccoglie dati su tutti i video in modo aggressivo, evitando di farsi ingannare dalla fortuna iniziale di un video mediocre. Verso la fine delle 10.000 iterazioni, [math]\epsilon[/math] avrà toccato il limite minimo dell’1% (0.01), smettendo di sprecare visualizzazioni preziose sui video peggiori, ma mantenendo un piccolissimo spiraglio aperto alle novità.
C’è un compromesso, però:
Mentre il Thompson Sampling si adatta naturalmente da solo grazie alla statistica Bayesiana, ottimizzare l'[math]\epsilon[/math]-Greedy introduce nuovi iperparametri (devi scegliere tu a mano il decay_rate e l'epsilon_min). Nel mondo della Data Science industriale, trovare i valori perfetti per queste variabili richiede a sua volta test accurati.
I Risultati sul campo: il crollo del Regret
Cosa succede quando mettiamo a confronto le prestazioni di questa ottimizzazione all’interno della nostra simulazione da 10.000 tentativi? I dati parlano chiaro:
| Strategia | Click Ottenuti (Reward) | Click Persi (Regret) |
|---|---|---|
| Oracolo Perfetto | 1.500 | 0 |
| Thompson Sampling | 1.487 | 13 |
| [math]\epsilon[/math]-Greedy con Decay | 1.478 | 22 |
| [math]\epsilon[/math]-Greedy Statico ([math]\epsilon=0.1[/math]) | 1.418 | 82 |
| Scelta Casuale | 1.000 | 500 |
L’introduzione del decadimento dinamico ha un effetto immediato: riduce drasticamente il numero di esplorazioni superflue quando l’algoritmo ha già capito qual è il video migliore. Il Regret crolla da 82 a 22, recuperando quasi tutto lo svantaggio competitivo nei confronti delle strategie più avanzate.
Perché il Thompson Sampling mantiene il primato?
A fronte di numeri così vicini, sorge spontanea una domanda: se un [math]\epsilon[/math]-Greedy ottimizzato con il Decay ottiene performance così elevate, per quale motivo la Data Science si orienta comunque verso il Thompson Sampling?
La risposta risiede nell’autonomia del modello. Il decadimento di [math]\epsilon[/math] è un trucco ingegneristico efficiente, ma pur sempre una regola artificiale basata su parametri rigidi che l’essere umano deve impostare a mano (decay_rate ed epsilon_min).
Il Thompson Sampling, al contrario, non ha bisogno di istruzioni esterne per capire quando smettere di esplorare. La sua curiosità è dettata organicamente dall’incertezza statistica insita nei dati stessi. Se il sistema è incerto, esplora molto; se raccoglie certezze, si concentra sullo sfruttamento; se all’improvviso viene caricato un nuovo video di cui non sa nulla, la curva di quel contenuto si allarga, innescando un’ondata di esplorazione mirata e spontanea senza toccare la stabilità degli altri contenuti. Questa resilienza rende gli approcci Bayesiani infinitamente più robusti e facili da scalare all’interno degli instabili ecosistemi digitali del mondo reale.
Algoritmi, Recommendation Systems e Dynamic Pricing
👉Multi‑Armed Bandit: Epsilon‑Greedy vs Thompson Sampling
👉Multi-Armed Bandit: Cos’è, Come Funziona e Perché Sostituisce l’A/B Testing
👉L’algoritmo di YouTube spiegato: Recommendation Systems e Decision Intelligence
👉Come funziona davvero l’algoritmo di TikTok
👉Oltre il prezzo fisso: introduzione al Dynamic Pricing
👉Dynamic Pricing per l’ottimizzazione del processo produttivo: il caso TechParts S.p.A.
👉Algoritmi Greedy: una scelta ottimale… a volte
👉Algoritmi Greedy in Python: guida pratica con esercizi, scheduling e scadenze





