Key Takeaways: Defensive Analytics
One-page reference for Chapter 10 concepts
The Defensive Attribution Challenge
| Challenge | Impact |
|---|---|
| 11-player coordination | Credit/blame shared |
| Weak link determines outcome | Best player may not matter |
| Dependent on offensive choices | Coverage depends on targets |
| High variance events | INTs, fumbles are noisy |
Team-Level Defensive Metrics
# EPA Allowed (core metric)
defense_epa = (plays
.groupby('defteam')
.agg(
epa_allowed=('epa', 'mean'),
success_allowed=('epa', lambda x: (x > 0).mean())
)
)
# Lower (more negative) is better
EPA Allowed Interpretation
| EPA/Play | Interpretation |
|---|---|
| < -0.10 | Elite |
| -0.10 to -0.05 | Above average |
| -0.05 to 0.00 | Average |
| 0.00 to 0.05 | Below average |
| > 0.05 | Poor |
Pass Defense Metrics
# Pressure rate estimation
passes['pressured'] = (
(passes['sack'] == 1) |
(passes['qb_hit'] == 1) |
(passes['qb_scramble'] == 1)
)
pressure_rate = passes['pressured'].mean()
# Coverage (team level)
comp_pct_allowed = non_sacks['complete_pass'].mean()
yards_per_target = non_sacks['yards_gained'].mean()
Run Defense Metrics
# Stuff rate (runs at/behind LOS)
stuff_rate = (rushes['yards_gained'] <= 0).mean()
# YPC allowed
ypc_allowed = rushes['yards_gained'].mean()
# Explosive prevention
explosive_10_rate = (rushes['yards_gained'] >= 10).mean()
Sack Rate vs Pressure Rate
| Metric | Measures | Limitation |
|---|---|---|
| Sack Rate | Actual takedowns | High variance |
| Pressure Rate | All disruptions | Includes QB escapes |
| QB Hit Rate | Physical contact | Doesn't include hurries |
Situational Defense
# Third down
third_conv_allowed = (third_downs
.groupby('defteam')
['third_down_converted']
.mean()
)
# Red zone
rz_td_rate = (red_zone
.groupby('defteam')
['touchdown']
.mean()
)
Turnover Analysis
Key insight: Turnovers are largely random
- Year-to-year INT rate correlation: ~0.25
- Fumble recovery is nearly random (~50% rate)
- Don't overweight turnover metrics
turnover_rate = (
plays['interception'] | plays['fumble_lost']
).mean()
Opponent Adjustment
# Simple adjustment
off_quality = plays.groupby('posteam')['epa'].mean()
expected_epa = plays.groupby('defteam').agg(
expected=('opp_offense_quality', 'mean')
)
adjusted_epa = raw_epa - expected_epa
Data Source Limitations
| Metric | Available In |
|---|---|
| EPA allowed | Standard PBP |
| Sacks, hits | Standard PBP |
| Individual coverage | PFF (subscription) |
| Pressures allowed | Film charting |
| Coverage targets | Tracking data |
| Win rate | ESPN/NFL |
Individual Evaluation Challenge
What we CAN'T measure from PBP: - Who was supposed to cover whom - Pass rush wins vs losses - Positioning and angles - Assignment correctness
Requires: PFF grades, SIS charting, or tracking data
Pass/Run Defense Split
pass_epa = passes.groupby('defteam')['epa'].mean()
run_epa = rushes.groupby('defteam')['epa'].mean()
# Positive = better pass defense
balance = run_epa - pass_epa
Common Pitfalls
| Pitfall | Better Approach |
|---|---|
| Over-weighting turnovers | Focus on EPA/success rate |
| Individual stats from PBP | Use film services |
| Ignoring game script | Filter to neutral situations |
| Raw stats without context | Opponent-adjust |
Deep Pass Defense
deep_passes = passes[passes['air_yards'] >= 15]
deep_comp_pct = deep_passes.groupby('defteam')['complete_pass'].mean()
# High-value area to defend
YAC Allowed
# Reflects tackling/pursuit
yac_allowed = (completions
.groupby('defteam')
['yards_after_catch']
.mean()
)
Evaluation Framework
1. Overall
- EPA per play allowed
- Success rate allowed
2. Pass Defense
- Pass EPA allowed
- Sack/pressure rate
- Comp % allowed
3. Run Defense
- Run EPA allowed
- Stuff rate
- YPC allowed
4. Situational
- 3rd down conversion
- Red zone TD rate
5. Context
- Opponent adjustment
- Game script filter
Key Limitations
- Individual attribution nearly impossible
- Turnovers are high variance
- Scheme effects not captured
- QB/WR quality affects results
- Sample sizes per player small
Preview: Chapter 11
Next: Special Teams Analytics - evaluating kicking, punting, and returns using EPA frameworks.