Kalman Filter¶
The Kalman Filter tracks a continuous latent variable representing the player's true point potential. It handles gradual form drift, a player slowly improving or declining across gameweeks.
State-Space Model¶
- \(x_t\) — true (unobserved) point potential at gameweek \(t\)
- \(y_t\) — observed weekly points (noisy measurement)
- \(Q_t\) — process noise (how fast true form can drift)
- \(R_t\) — observation noise (how noisy weekly points are)
The random-walk model (\(x_{t+1} = x_t + w_t\)) means form drifts gradually. \(Q\) controls drift speed: large \(Q\) allows rapid changes, small \(Q\) assumes stable form.
Predict-Update Cycle¶
At each timestep:
Predict:
Update:
Kalman Gain Interpretation
When \(Q_t\) is large → \(P_{t|t-1}\) is large → \(K_t\) is large → the filter trusts the observation more. When \(R_t\) is large → \(K_t\) is small → the filter trusts the prior more. This is exactly how news and fixtures should affect inference.
Adaptive Noise (Signal Injection)¶
Both \(Q_t\) and \(R_t\) can be overridden per-timestep:
| Signal | Parameter | Multiplier | Effect |
|---|---|---|---|
| Injury news | \(Q_t\) | 5.0 | Form may have jumped; widen state uncertainty |
| Doubtful news | \(Q_t\) | 2.0 | Moderate form uncertainty |
| Easy fixture (difficulty 1) | \(R_t\) | 0.8 | Points more predictable, trust observation |
| Hard fixture (difficulty 5) | \(R_t\) | 1.5 | Points less predictable, trust prior |
kf = KalmanFilter(Q=1.0, R=4.0, x0=4.0, P0=2.0)
# Injury at gameweek 20: process noise inflated
kf.inject_process_shock(timestep=20, multiplier=5.0)
# Hard fixture at gameweek 21: observation noise inflated
kf.inject_observation_noise(timestep=21, factor=1.5)
x_est, P_est = kf.filter(observations)
RTS Smoother¶
The Rauch-Tung-Striebel smoother runs a backward pass after the forward Kalman filter, producing refined estimates that use all data (past and future):
Available via KalmanFilter.smooth().
Default Parameters¶
| Parameter | Default | Meaning |
|---|---|---|
| \(Q\) | 1.0 | Process noise — moderate form drift |
| \(R\) | 4.0 | Observation noise — weekly points are noisy |
| \(x_0\) | 4.0 | Initial estimate — league-average points |
| \(P_0\) | 2.0 | Initial uncertainty |
Tuning
\(Q\) should be higher for young/volatile players and lower for established veterans. \(R\) can be estimated from the empirical variance of weekly points across the league.