Behavioral Model Interactive
Recency Bias
Users overweight recent performance when predicting future outcomes. Exploit this by identifying regression to the mean opportunities.
๐ง The Cognitive Bias
What People Do
Overweight the most recent data points. A player's last game feels more predictive than it actually is.
- โข "He just dropped 40, he's on fire!"
- โข "He's cold, only 12 pts last game"
- โข "This team can't lose, 5 game win streak"
What Actually Happens
Performance regresses to the mean. Hot and cold streaks are mostly random variation.
- โข Variance in small samples is high
- โข True ability changes slowly
- โข Outliers are... outliers
Player Stats
10 35
10 45
5 60
๐ Projection Comparison
Public Projection
33.2
Heavy recency weighting
Optimal Projection
26.4
Regression-adjusted
Mispricing
+6.8 pts
Fade OVER
Weighting Schemes
Public (Recency Biased)
Season Avg 20%
Last 5 Games 40%
Last Game 40%
Optimal (Regression-Adjusted)
Season Avg 60%
Last 5 Games 30%
Last Game 10%
Simulated Regression to Mean
Hot streaks regress toward season average, not stay at elevated levels.
๐ Common Scenarios
Hot Streak
Recent: +35% vs avg
Public thinks: Will keep it up!
Reality: Likely regression
Edge: Fade the over
Cold Streak
Recent: -25% vs avg
Public thinks: Lost it, done
Reality: Likely bounce back
Edge: Take the over
Blowup Game
Recent: 50 pts (2x avg)
Public thinks: New level!
Reality: Outlier, regress
Edge: Strong fade
Injury Return
Recent: 15 pts (low)
Public thinks: Not same player
Reality: Ramping up
Edge: Buy the over
๐ฐ Pricing Implications
Exploit Recency Bias
- โ Shade lines toward public perception (let them bet wrong side)
- โ Boost props for players on cold streaks (public under-bets)
- โ Reduce props for hot players (public over-bets)
For Your Models
- โ Use Bayesian shrinkage to weight season over recent
- โ Calibrate optimal recency weights empirically
- โ Identify situations where recent IS more predictive (injuries, role changes)
R Code Equivalent
# Regression-adjusted projection
project_with_regression <- function(season_avg, last5_avg, last1,
weights = c(0.6, 0.3, 0.1)) {
projection <- season_avg * weights[1] +
last5_avg * weights[2] +
last1 * weights[3]
return(projection)
}
# Compare public vs optimal
public_proj <- project_with_regression(22, 30, 42,
weights = c(0.2, 0.4, 0.4))
optimal_proj <- project_with_regression(22, 30, 42,
weights = c(0.6, 0.3, 0.1))
mispricing <- public_proj - optimal_proj
cat(sprintf("Public: %.1f, Optimal: %.1f, Edge: %.1f pts\n",
public_proj, optimal_proj, mispricing))โ Key Takeaways
- โข Humans overweight recent performance
- โข Hot streaks regress, cold streaks bounce back
- โข Season average is more predictive than last game
- โข Fade extreme recent performance
- โข Use Bayesian shrinkage for optimal weighting
- โข Exception: genuine role/situation changes