Chapter 19: Key Takeaways - Player Performance Forecasting

Quick Reference Summary

This chapter covered building player projection systems using regression, aging curves, and comparable players.


Core Concepts

Projection Fundamentals

Concept Formula Purpose
Regression to Mean proj = r×observed + (1-r)×league_avg Adjust for sample size
Reliability r = sample / (sample + stabilization) Weight for observed data
Marcel Weights 5/4/3 for Y-0/Y-1/Y-2 Multi-year weighting

Stat Stability by Type

Stat Type Stabilization Point Notes
Completion % ~200 attempts Moderately stable
Yards/Attempt ~300 attempts Moderate regression needed
TD Rate ~500 attempts Highly variable
INT Rate ~400 attempts Variable
Yards/Carry ~200 carries Context-dependent
Catch Rate ~100 targets Relatively stable

Essential Formulas

Reliability Weight

reliability = opportunities / (opportunities + stabilization_point)

Example: QB with 300 attempts, stabilization = 300
reliability = 300 / (300 + 300) = 0.5

Projection = 0.5 × observed + 0.5 × league_average

Marcel Projection

weighted_rate = Σ(weight_i × opportunities_i × rate_i) / Σ(weight_i × opportunities_i)

regression_factor = weighted_opps / (weighted_opps + regression_opps)

projection = regression_factor × weighted_rate + (1 - regression_factor) × league_avg

Aging Adjustment

if age < peak_age:
    adjustment = 1.0 + improvement_rate × (peak_age - age)
else:
    adjustment = 1.0 - decline_rate × (age - peak_age)

projected = base_projection × adjustment

Code Patterns

Basic Regression Projector

def project_rate(observed, sample_size, league_avg, stabilization):
    """Project a rate statistic."""
    reliability = sample_size / (sample_size + stabilization)
    return reliability * observed + (1 - reliability) * league_avg

# Example: QB completion percentage
obs_comp_pct = 0.68
attempts = 350
league_avg = 0.62
stab_point = 200

proj = project_rate(obs_comp_pct, attempts, league_avg, stab_point)
# proj ≈ 0.655

Marcel-Style Projection

def marcel_project(seasons, weights=(5, 4, 3)):
    """Marcel projection from multi-year data."""
    weighted_sum = 0
    weight_total = 0

    for i, season in enumerate(seasons[:3]):
        w = weights[i]
        opps = season['attempts']
        rate = season['rate']

        weighted_sum += w * opps * rate
        weight_total += w * opps

    observed = weighted_sum / weight_total
    reliability = weight_total / (weight_total + 1200)

    return reliability * observed + (1 - reliability) * league_avg

Aging Curve Application

def apply_aging(projection, position, current_age, target_age):
    """Apply aging curve to projection."""
    curves = {
        'QB': {'peak': 28, 'decline': 0.015},
        'RB': {'peak': 25, 'decline': 0.05},
        'WR': {'peak': 27, 'decline': 0.025}
    }

    curve = curves[position]
    peak = curve['peak']
    decline = curve['decline']

    if target_age <= peak:
        return projection  # No decline yet
    else:
        years_past_peak = target_age - peak
        adjustment = 1.0 - decline * years_past_peak
        return projection * adjustment

Position-Specific Guidelines

Quarterback Projection

Metric Stability Key Factors
Completion % Moderate Scheme, WR quality
Y/A Moderate OL quality, arm strength
TD Rate Low Red zone opportunities
INT Rate Moderate Decision-making, scheme

QB Checklist: - [ ] Weight 2-3 years of data - [ ] Regress heavily for TDs/INTs - [ ] Adjust for supporting cast changes - [ ] Apply minimal aging (QBs age well)

Running Back Projection

Metric Stability Key Factors
Y/C Low OL quality, scheme
Catch Rate Moderate Role in passing game
TD Rate Very Low Goal line usage

RB Checklist: - [ ] Project usage separately from efficiency - [ ] Heavy regression for Y/C - [ ] Apply significant aging (RBs decline fast) - [ ] Monitor role in passing game

Wide Receiver Projection

Metric Stability Key Factors
Y/Target Moderate Route running, QB
Catch Rate Moderate Target quality
Target Share Moderate Competition, scheme

WR Checklist: - [ ] Project target share - [ ] Apply moderate efficiency regression - [ ] Account for QB changes - [ ] Development curve (peak ~27)


Common Pitfalls

1. Insufficient Regression

Wrong: Using raw stats as projections

# BAD - no regression
proj_y_a = last_season['yards'] / last_season['attempts']

Right: Apply appropriate regression

# GOOD - regress based on sample
reliability = attempts / (attempts + 300)
proj_y_a = reliability * observed + (1 - reliability) * 7.5

2. Ignoring Sample Size

Wrong: Treating all samples equally

# BAD - same projection for 50 vs 500 attempts
proj = observed_rate * 0.6 + league_avg * 0.4

Right: Adjust for sample

# GOOD - more regression for small samples
reliability = sample / (sample + stabilization)
proj = reliability * observed + (1 - reliability) * league_avg

3. Ignoring Context

Wrong: Projecting without team context

# BAD - ignoring OL change
rb_proj = historical_ypc * projected_carries

Right: Account for context changes

# GOOD - adjust for context
ol_adjustment = new_ol_quality - old_ol_quality
adjusted_ypc = proj_ypc * (1 + ol_adjustment * 0.1)

Evaluation Checklist

Before Projecting

  • [ ] Sufficient historical data (2+ seasons preferred)
  • [ ] Clear understanding of role/usage
  • [ ] Context factors identified
  • [ ] Appropriate stabilization points chosen

Projection Quality

  • [ ] Reasonable regression applied
  • [ ] Multi-year weighting used
  • [ ] Aging effects considered
  • [ ] Confidence intervals included

After Season

  • [ ] Compare projections to actuals
  • [ ] Calculate MAE and correlation
  • [ ] Check calibration of intervals
  • [ ] Identify systematic biases

Quick Reference Tables

Stabilization Points

Stat ~50% Reliable ~80% Reliable
QB Comp % 200 att 500 att
QB Y/A 300 att 750 att
QB TD % 500 att 1200 att
RB Y/C 200 carries 500 carries
WR Y/Target 100 targets 250 targets
WR Catch % 100 targets 250 targets

Typical Aging Curves

Position Peak Age Decline Rate/Year
QB 28-30 1-2%
RB 25-26 4-6%
WR 27-28 2-3%
TE 28-29 2-3%

Projection Hierarchy

  1. High Confidence: High usage, 2+ years, stable stats
  2. Moderate Confidence: Moderate usage or 1 year
  3. Low Confidence: Role change, limited data, volatile stats

Red Flags

Warning signs projection may be unreliable:

  1. < 100 opportunities: Very high regression needed
  2. Role change imminent: Historical data less relevant
  3. Age 30+ RB: Steep decline likely
  4. New team/scheme: Context shift
  5. Injury history: Availability uncertainty

Next Steps

After mastering player forecasting, proceed to: - Chapter 20: Recruiting Analytics - Chapter 21: Win Probability Models - Chapter 22: Machine Learning Applications