Epistemico vs Aleatorico: Misurare ciò che un modello di rendimento non sa
Ogni regola di dimensionamento della posizione in questo blog riduce l'incertezza a un singolo scalare. Kelly divide per varianza. Predizione conforme divide per larghezza dell'intervallo. Targeting della volatilità divide per una previsione GARCH. Tutte e tre sono corrette, e tutte e tre scartano una distinzione che conta per il trading: la differenza tra un mercato rumoroso e un modello ignorante.
Quelli non sono lo stesso rischio. Il rumore del mercato è prezzato — è ciò per cui sei compensato per sopportarlo. L'ignoranza del modello non è prezzata, non è compensata, ed è precisamente lo stato in cui la tua stima di edge è meno affidabile. Una regola di sizing che penalizza entrambi allo stesso modo lascia qualcosa sul tavolo.
Questo post riguarda rendere misurabile quella divisione. Concretamente:
Metti quello nel denominatore Kelly invece della varianza totale. Il resto dell'articolo riguarda come stimare i due componenti (MC Dropout, deep ensembles), e come appare la divisione sui dati reali.
La Tesi: Due incertezze richiedono due risposte
| Epistemico | Aleatorico | |
|---|---|---|
| Fonte | Dati limitati / modello | Rumore intrinseco nei dati |
| Riducibile? | Sì (più dati aiutano) | No |
| Azione di trading | Riduci posizione o astieniti | Allarga stop, riduci leva |
| Segnale | "Non ho visto questo regime" | "Questo mercato è rumoroso ora" |
L'asimmetria nella riga "azione di trading" è l'intero argomento. Una varianza aleatorica alta è un noto non noto: puoi dimensionare per essa, hedgearla, e aspettarti di essere pagato un premio di rischio per detenerla. La varianza epistemica alta è un non noto non noto: il modello sta extrapolando, la sua stima della media è sospetta quanto la sua stima della varianza, e non c'è premio associato ad aver torto sui propri parametri.
Un modello che confonde i due farà over-trading in regimi non familiari (ignorando l'incertezza epistemica) o under-trading in regimi familiari ma rumorosi (over-penalizzando l'incertezza aleatorica). Kelly standard, applicato a , fa entrambi a seconda di quale componente domina.
La Decomposizione
L'incertezza epistemica proviene dall'incertezza sui parametri del modello . Invece di un singolo (come nella massima verosimiglianza), manteniamo una distribuzione e integriamo:
La diffusione indotta dall'integrazione su è epistemica. Si riduce mentre cresce per coprire la regione di input.
L'incertezza aleatorica è il rumore condizionato del processo generatore di dati. In una rete neurale, è modellato da una seconda testa di output che emette una varianza dipendente dall'input:
Questa testa eteroschedastica stima lo stesso oggetto che GARCH stima classicamente — varianza condizionale dipendente dallo stato che è alta di notte e bassa nelle ore di punta. Se vuoi gli empirici di quell'oggetto su crypto, GARCH(1,1) per la volatilità crypto lo copre appropriatamente, incluso perché la previsione condizionale live (non la varianza campionaria non condizionale) appartiene nel denominatore Kelly. La testa NN è solo un diverso stimatore della stessa quantità, fit congiuntamente con la media.
Quello che GARCH non può darti è l'altro termine. È per quello che serve il resto di questo post.
Dove questo si colloca rispetto a quanto già pubblicato
Due post precedenti coprono un terreno adiacente e valgono la pena di essere letti prima, perché questo deliberatamente non li ripete:
- Predizione conforme per il sizing di posizione consapevole del rischio ti dà intervalli con una garanzia di copertura di campione finito, senza assunzione distributiva, più sizing inverso alla larghezza e un filtro no-trade di ratio-edge. È lo strumento più forte se vuoi solo un intervallo correttamente dimensionato.
- Temporal Fusion Transformers emettono quantili direttamente e già avvertono che i quantili di perdita pinball non sono automaticamente calibrati out-of-sample.
Il trade-off è pulito. Conforme ti dà una garanzia ma un numero — la larghezza dell'intervallo non è scomponibile, quindi non può dirti perché si è allargata. I metodi Bayesian ti danno una scomposizione ma nessuna garanzia — gli intervalli MC Dropout sono buoni quanto il posteriore approssimato. Questo articolo riguarda l'acquisto della scomposizione; probabilmente dovresti mantenere conforme sopra per la copertura.
Metodo 1: Inferenza Variazionale (Bayes by Backprop)

Una rete neurale Bayesian pone un prior sui pesi e cerca il posteriore . Il normalizzatore richiede l'integrazione su ogni configurazione di pesi, che è intrattabile per qualsiasi cosa con più di un pugno di parametri.
L'inferenza variazionale sostituisce il posteriore intrattabile con una famiglia trattabile — tipicamente un Gaussiano fattorizzato — e minimizza
Dato che ciò coinvolge il posteriore sconosciuto, invece massimizziamo l'Evidence Lower Bound:
Il primo termine spinge a spiegare i dati; il secondo lo mantiene vicino al prior. Bayes by Backprop (Blundell et al., 2015) rende questo differenziabile con il trucco di riparametrizzazione: campiona , imposta .
In pratica, VI raddoppia il conteggio dei parametri, aumenta la varianza del gradiente (ogni passata in avanti usa pesi diversi), e l'assunzione di campo medio ignora le correlazioni dei pesi, il che tende a sottostimare l'incertezza epistemica. Per uno stack di trading dove hai già un modello deterministico addestrato, i due metodi più economici sotto sono solitamente il miglior punto di ingresso.
Metodo 2: MC Dropout

Gal e Ghahramani (2016) hanno mostrato che una rete addestrata con dropout e valutata con dropout ancora attivo al tempo di test è una procedura di inferenza variazionale approssimata in un processo Gaussiano profondo. Il dropout induce già una distribuzione sulle sottoreti; mantenerlo attivo durante l'inferenza ed eseguire passate in avanti campiona da quel posteriore implicito.
Questo non esiste da nessuna altra parte in questo blog. Il codice pubblicato qui usa dropout solo come regolarizzatore al tempo di addestramento (modeling dello spread, TFT su dropout=0.1–0.3). Tenerlo attivo durante l'inferenza è una modifica di una riga con un significato completamente diverso.
Statistiche Predittive
Dato passate in avanti stocastiche che producono e varianze per-passata :
Media predittiva:
Epistemica (disaccordo tra passate):
Aleatorica (media del rumore predetto):
La scomposizione è esattamente la legge della varianza totale: varianza della media condizionale, più media della varianza condizionale. La varianza predittiva totale è la loro somma.
Implementazione PyTorch
import torch
import torch.nn as nn
import numpy as np
class MCDropoutNet(nn.Module):
"""
Rete di predizione dei rendimenti con MC Dropout per la stima dell'incertezza.
Output sia la media predetta che la log-varianza (aleatorica).
"""
def __init__(self, input_dim: int, hidden_dim: int = 128, dropout_p: float = 0.1):
super().__init__()
self.net = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Dropout(p=dropout_p),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Dropout(p=dropout_p),
)
self.head_mu = nn.Linear(hidden_dim, 1) # rendimento predetto
self.head_logvar = nn.Linear(hidden_dim, 1) # log(varianza aleatorica)
def forward(self, x: torch.Tensor):
h = self.net(x)
return self.head_mu(h), self.head_logvar(h)
def heteroscedastic_loss(mu, log_var, target):
"""Log-verosimiglianza negativa per un Gaussiano con varianza appresa, dipendente dall'input."""
precision = torch.exp(-log_var)
return torch.mean(0.5 * precision * (target - mu) ** 2 + 0.5 * log_var)
@torch.no_grad()
def mc_predict(model: MCDropoutNet, x: torch.Tensor, n_samples: int = 100):
"""
Inferenza MC Dropout: mantenere dropout attivo, raccogliere T passate in avanti,
scomporre la varianza predittiva in parti epistemica e aleatorica.
"""
model.train() # NON eval() — questo è ciò che mantiene dropout attivo
mus, log_vars = [], []
for _ in range(n_samples):
mu, log_var = model(x)
mus.append(mu)
log_vars.append(log_var)
mus = torch.stack(mus) # (T, batch, 1)
log_vars = torch.stack(log_vars) # (T, batch, 1)
pred_mean = mus.mean(dim=0)
epistemic_var = mus.var(dim=0) # Var su passate
aleatoric_var = log_vars.exp().mean(dim=0) # E su passate
return {
"mean": pred_mean.squeeze(-1),
"epistemic_std": epistemic_var.sqrt().squeeze(-1),
"aleatoric_std": aleatoric_var.sqrt().squeeze(-1),
"total_std": (epistemic_var + aleatoric_var).sqrt().squeeze(-1),
}
L'addestramento usa la perdita eteroschedastica, che è ciò che rende significativa la testa della varianza. Nota la struttura autoregolante: il termine 0.5 * precision * (target - mu)**2 vuole varianza piccola, il termine 0.5 * log_var la punisce, e il punto di equilibrio è il livello di rumore condizionale.
model = MCDropoutNet(input_dim=50, hidden_dim=128, dropout_p=0.1)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
for epoch in range(200):
model.train()
for x_batch, y_batch in train_loader:
mu, log_var = model(x_batch)
loss = heteroscedastic_loss(mu, log_var, y_batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()
L'errore che uccide silenziosamente il metodo: chiamare model.eval() dentro mc_predict. Disabilita il dropout, ogni passata restituisce il valore identico, epistemic_var collassa esattamente a zero, e la tua regola di sizing ritorna silenziosamente al Kelly semplice sulla varianza aleatorica. Fallisce senza errore. Assicurati che epistemic_var > 0 nel tuo percorso di inferenza.
Scegliere il numero di passate in avanti
- : limite inferiore ragionevole per una media stabile
- : predefinito utilizzabile per media e varianza
- : rendimenti decrescenti a meno che tu non abbia bisogno di quantili di coda
Metodo 3: Deep Ensembles
Lakshminarayanan et al. (2017) addestrano reti indipendenti da diverse inizializzazioni casuali e aggregano. Sebbene non formalmente Bayesian, i deep ensembles battono costantemente metodi più principati sui benchmark di calibrazione dell'incertezza.
Il disaccordo tra membri è la stima epistemica. Gli ensemble appaiono altrove in questo blog come dispositivi di aggregazione — rilevamento anomalie, rilevamento regime HMM, block bootstrap EnbPI conforme — ma mai come estimatore di incertezza via spread inter-membro. Questo è l'uso qui.
Implementazione Ensemble
La diversità viene dall'addestramento indipendente, non dal costruire oggetti. Un ensemble di membri non addestrati o addestrati in modo identico restituisce rumore o varianza epistemica zero:
class DeepEnsemble:
def __init__(self, input_dim: int, n_models: int = 5, hidden_dim: int = 128):
self.models = []
for seed in range(n_models):
torch.manual_seed(seed) # diverso init per membro
self.models.append(
MCDropoutNet(input_dim, hidden_dim, dropout_p=0.0)
)
def fit(self, train_loader, epochs: int = 200, lr: float = 1e-3):
"""Ogni membro viene addestrato indipendentemente. Qui è da dove viene la diversità
-- diverso init, diverso ordine di shuffle. Saltare questo
risulta in epistemic_var == 0 (membri identici) o rumore puro (non addestrato)."""
for seed, model in enumerate(self.models):
torch.manual_seed(1000 + seed) # diverso stream di shuffle/dropout
opt = torch.optim.AdamW(model.parameters(), lr=lr, weight_decay=1e-4)
model.train()
for _ in range(epochs):
for x_batch, y_batch in train_loader:
mu, log_var = model(x_batch)
loss = heteroscedastic_loss(mu, log_var, y_batch)
opt.zero_grad()
loss.backward()
opt.step()
return self
@torch.no_grad()
def predict(self, x: torch.Tensor):
mus, variances = [], []
for model in self.models:
model.eval() # corretto qui: nessun sampling dropout
mu, log_var = model(x)
mus.append(mu.squeeze(-1))
variances.append(log_var.exp().squeeze(-1))
all_mus = torch.stack(mus)
all_vars = torch.stack(variances)
epistemic_var = all_mus.var(dim=0) # spread TRA membri
aleatoric_var = all_vars.mean(dim=0)
return {
"mean": all_mus.mean(dim=0),
"epistemic_std": epistemic_var.sqrt(),
"aleatoric_std": aleatoric_var.sqrt(),
"total_std": (epistemic_var + aleatoric_var).sqrt(),
}
Nota che model.eval() è corretto in DeepEnsemble.predict e sbagliato in mc_predict. La fonte di stochasticità differisce: gli ensemble la ottengono dall'addestramento indipendente, MC Dropout da maschere dropout live.
Trade-off: MC Dropout vs Deep Ensembles
| MC Dropout | Deep Ensembles | |
|---|---|---|
| Costo addestramento | 1x (modello singolo) | x ( modelli) |
| Costo inferenza | passate in avanti | passate in avanti |
| Memoria | 1x parametri | x parametri |
| Qualità incertezza | Tende a sottostimare epistemica | Meglio calibrato globalmente |
| Facilità implementazione | Banale (cambiare una flag) | Banale (addestra modelli) |
| Parallelismo | Passate sequenziali (stesso modello) | Embarrassingly parallelo |
Un ibrido pragmatico: addestra un piccolo ensemble () dove ogni membro usa anche MC Dropout, catturando sia il disaccordo inter-modello che la stochasticity intra-modello.
Il Payoff: Sizing Asimmetrico

Ecco il vero contributo. Kelly Gaussiano è ; la derivazione, la parabola di crescita, la tabella di probabilità di drawdown e i quattro motivi per eseguire Kelly frazionario invece di pieno sono tutti in Il Criterio di Kelly per le Strategie, e non sono ripetuti qui. Prendi a una frazione di quarto-Kelly come dato.
La modifica è il denominatore. Invece della varianza predittiva totale:
L'argomento per : la varianza aleatorica è il rumore del mercato, è prezzata, e sopportarla è come una strategia guadagna. La varianza epistemica è la tua ignoranza — non porta premio, e peggio, è correlata con la tua stima essere sbagliata. Quando è grande, il numeratore di Kelly è inaffidabile allo stesso tempo del denominatore, quindi l'errore di sizing si compone. Penalizzarla in modo superlineare rispetto al rumore di mercato è l'espressione diretta di ciò.
def uncertainty_adjusted_position_size(
pred_mean: float,
epistemic_std: float,
aleatoric_std: float,
max_position: float = 1.0,
lam: float = 2.0, # penalità epistemica; sintonizza su validazione
max_epi_ratio: float = 0.5, # asteniti sopra questo rapporto epi/alea
base_kelly_fraction: float = 0.25,
) -> float:
"""Sizing Kelly dove la varianza epistemica è penalizzata più forte dell'aleatorica."""
effective_var = aleatoric_std ** 2 + lam * epistemic_std ** 2
if effective_var < 1e-10:
return 0.0
position = (pred_mean / effective_var) * base_kelly_fraction
epi_ratio = epistemic_std / (aleatoric_std + 1e-8)
if epi_ratio > max_epi_ratio:
position *= max(0.0, 1.0 - epi_ratio)
return float(np.clip(position, -max_position, max_position))
Il gate merita una nota. Azzerare posizioni sotto una soglia di fiducia non è nuovo qui — l'articolo conforme specifica e codifica il filtro generale no-trade come con una soglia min_edge, incluso come scegliere la soglia e la lettura geometrica di un intervallo che attraversa lo zero. Vedi predizione conforme per quella macchinaria. Quello che è nuovo è il denominatore: fare gating su spara specificamente quando il modello è più confuso sui propri parametri di quanto il mercato sia rumoroso — uno stato che il gating di incertezza totale non può rilevare, perché un regime tranquillo ma non familiare può avere bassa varianza totale e un rapporto epistemico terribile.
Calibrazione: Delega Questo
Una stima dell'incertezza è utile solo se calibrata: un intervallo nominale del 95% dovrebbe contenere la verità ~95% delle volte. Non creare il tuo controllo di affidabilità quantile Gaussiano — un intervallo parametrico su residui di rendimento a coda pesante è esattamente la modalità di fallimento che predizione conforme esiste per evitare, e spedisce un evaluate() funzionante che riporta obiettivo vs copertura empirica con una garanzia di campione finito dietro. Il post TFT fa lo stesso punto per le teste quantile.
Il rescaling post-hoc ( fit su un set di validazione) è la correzione economica, ed è il cugino più debole dell'Inferenza Conforme Adattiva, che mantiene un livello di mancato-ripertura online con un bound di copertura a lungo termine piuttosto che un rescaling statico. ACI è l'opzione più forte; l'unica ragione per preferire il rescaling lineare è che esso preserva il rapporto epistemico/aleatorico, che la larghezza singola di ACI non fa.
Cosa Deve Essere Misurato Prima della Pubblicazione
I metodi sopra sono stabiliti. L'asserzione che lo split compra qualcosa nel trading non lo è, e questo blog non pubblica regole di sizing solo sull'argomento. L'asticella:
1. Dataset e obiettivo. Nomina lo strumento, dimensione barra, intervallo di date esplicito, set di feature e obiettivo di previsione.
2. La divisione stessa. Quale frazione di varianza predittiva totale è epistemica vs aleatorica, e come si muove questo rapporto tra una finestra calma nominata e una volatile nominata. Questo è il grafico dei soldi e non esiste ancora. L'ipotesi che vale la pena falsificare: il rapporto impenna prima della volatilità realizzata, perché la non familiarità precede la turbolenza.
3. Copertura vs conforme. Copertura misurata out-of-sample degli intervalli MC Dropout contro nominale, confrontata con gli intervalli split-conforme dall'articolo pubblicato sugli stessi dati. Quel testa a testa è esso stesso un nuovo risultato e il ponte naturale tra i due post.
4. compra qualcosa? Spazzola la penalità epistemica su validazione e riporta PnL e drawdown massimo contro la baseline . Se non compra nulla, dillo — Il Negativo Onesto è il template per quel risultato ed è un risultato pubblicabile.
5. Costo inferenza. Misurato, sull'hardware target, a ogni .
Ogni valutazione qui gira sotto la disciplina walk-forward — è un iperparametro, e un sintonizzato sul campione completo non è un risultato.
Consigli Pratici per la Produzione
1. Riscalda il prior. Con inferenza variazionale, inizializza la media variazionale da una rete deterministica pre-addestrata invece che a caso. Tipicamente dimezza il tempo di convergenza.
2. Guarda il collasso della varianza. Le varianze apprese possono derivare verso quasi zero, riportando silenziosamente il BNN a una rete deterministica. Monitora la media durante l'addestramento; aggiungi annealing KL se necessario.
3. Ricalibra su base rotolante, non su un set di validazione fisso. I mercati sono non stazionari e una calibrazione fit una volta decade. O riaddestra su una finestra rotolante sotto disciplina Walk-Forward, o lascia che ACI assorba online la obsolescenza del modello — il post conforme copre direttamente il trade-off frequenza riaddestramento.
4. La diversità dell'ensemble conta. Semi diversi, shuffle diversi, opzionalmente iperparametri diversi per membro. La diversità di inizializzazione è il driver primario della qualità dell'ensemble, ecco perché il loop fit() sopra non è opzionale.
5. Log la scomposizione, non solo il totale. Memorizza entrambi i componenti accanto agli esiti realizzati. Senza questo non puoi rispondere alla unica domanda che conta nella revisione: quando il sizer ha tagliato l'esposizione, era perché il mercato era rumoroso o perché il modello era perso — ed aveva ragione?
6. Incertezza come feature. Le statistiche epistemiche rotolanti possono essere predittive dei drawdown. Plausibile, non misurato, e vale un post separato.
Limitazioni e Caveats Onesti
- I posteriori approssimati sono ancora approssimati. MC Dropout e VI danno una vista limitata del posteriore vero. Meglio di niente, non verità terra, e nessuna garanzia di copertura è allegata a nessuno dei due.
- La calibrazione degrada esattamente quando ne hai bisogno. In un regime veramente nuovo il modello può ancora essere miscalibrato — tende solo ad essere meno miscalibrato di uno deterministico. Le stime di incertezza da un input out-of-distribution sono esse stesse output out-of-distribution.
- La varianza aleatorica può assorbire il segnale epistemico. Se la testa eteroschedastica è sufficientemente flessibile, impara a spiegare l'incertezza del modello come rumore dei dati, collassando verso zero e sconfiggendo silenziosamente l'intera scomposizione. Questa è la modalità di fallimento più importante in questo post e non si annuncia da sola. Monitora il rapporto attraverso i regimi; un rapporto che non si muove mai è una scomposizione rotta, non un mercato stabile.
- è un parametro libero. Introdurre un manopola sintonizzabile in una regola di sizing è come vengono costruite regole di sizing overfit. Ha bisogno di una giustificazione walk-forward o deve essere fissato a 1.
Conclusione
La predizione conforme dà già a questo blog larghezze di intervallo con garanzia di copertura, e Kelly dà già una regola di sizing. Quello che nessuno dei due dà è una risposta al perché l'intervallo è largo. Dividere la varianza predittiva in parti epistemiche e aleatoriche risponde a ciò, e la risposta è agibile in un modo che il totale non lo è: il rumore del mercato è rischio compensato, l'ignoranza del modello no, e il denominatore di sizing dovrebbe dirlo.
MC Dropout rende la divisione quasi gratuita — una riga (model.train() all'inferenza) trasforma qualsiasi rete dropout in una Bayesian approssimata. I deep ensembles costano x e calibrano meglio. Entrambi alimentano lo stesso denominatore asimmetrico .
Se paga davvero è una domanda empirica che questa bozza non risponde ancora. Le misurazioni elencate sopra sono il prezzo di pubblicarlo.
Riferimenti:
- Blundell, C., Cornebise, J., Kavukcuoglu, K., & Wierstra, D. (2015). Weight Uncertainty in Neural Networks. ICML.
- Gal, Y. & Ghahramani, Z. (2016). Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning. ICML.
- Lakshminarayanan, B., Pritzel, A., & Blundell, C. (2017). Simple and Scalable Predictive Uncertainty Estimation using Deep Ensembles. NeurIPS.
- Kendall, A. & Gal, Y. (2017). What Uncertainties Do We Need in Bayesian Deep Learning for Computer Vision? NeurIPS.
- Gibbs, I. & Candes, E. (2021). Adaptive Conformal Inference Under Distribution Shift. NeurIPS.
- Kelly, J. L. (1956). A New Interpretation of Information Rate. Bell System Technical Journal.
Autori
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.