LIVE
GIBBSRB·DET +204.9·
TAYLORRB·IND +159.9·
CHASEWR·CIN +150.6·
HENRYTE·NE -148.0·
ROBINSONRB·ATL +141.2·
NACUAWR·LAR +138.4·
JEFFERSONWR·MIN +176.1·
KELCETE·KC -112.3·
PROJECTIONS · ADMIN

2026 Defensive Projection Engine

Methodology validation for Ball Street's 2026 IDP / defensive projections — team yards allowed, role-based opportunity allocation, efficiency rates, and individual defender rankings.

Curated by: Durham Baxter — Founder & Owner, Ball Street Analytics
Updates with eventsPublished: 2026-04-21Updated: 2026-04-2112 min read

This is the defensive mirror of the 2026 Projection Engine. Every step matches the offensive pipeline's methodology 1:1 — walk-forward backtests, zero-sum league allocation, tiered anchoring, rank-based validation — applied to defensive / IDP counting stats.

Universe: solo / assist tackles, TFL, sacks, QB hits, interceptions, forced fumbles, fumble recoveries, pass breakups, defensive TDs, safeties — all scored via IDP123 (Sleeper default). Yards allowed and TDs allowed stay team-level; individual players don't meaningfully "allow yards" outside of coverage splits (which feed Step 4 as efficiency inputs, not projections).

Roles: player positions are normalized to five IDP buckets — EDGE, IDL, LB, CB, S — the same vocabulary used by defensive SHAPE. Two-way players (Travis Hunter) carry a row per side of the ball.

Step 1: League-Level Defensive Trends

Before projecting individual teams, we establish the macro budget: how many total yards, touchdowns, takeaways, and sacks does the NFL defense produce each season, and where is the trend headed?

These distributions show all 32 defenses each season. The violin shape captures the full spread, the white line tracks the league mean, and the dashed projection uses recency-weighted regression to estimate 2026 baselines.

Loading defensive data...

What the trends tell us

Yards allowed per team sit at roughly 5,600 yards (pass ~4,000, rush ~1,600). The pass/rush mix mirrors offensive trends — passing yards allowed are trending down while rushing yards allowed trend up. Explosive plays have declined league-wide.

Touchdowns allowed average ~40 per team with wide team-to-team variance (IQR ~14 TDs). Defense quality drives distribution far more than league trend does — unlike offense where every team is pushed by the same rule-book and CBA forces.

Takeaways are the most volatile metric. Average ~22 per team but with very high year-over-year variance — takeaway rate has a correlation of just 0.18 season-to-season. This is the defensive equivalent of passing INTs on the offensive side: nearly unpredictable at the team level, and projection models need heavy mean reversion to minimize damage.

Sacks + TFL are stickier. Pass rush produces year-over-year correlations around 0.55 — scheme-driven and roster-driven in ways that persist.

These league baselines anchor the team projections in Step 2: each team's projected defensive output is a deviation from the league trend, not an absolute number. The league budget is a zero-sum constraint — every yard a defense "prevents" is a yard another offense didn't gain.

Step 2: Team Output Allocation

The league baseline gives us a total defensive budget. Now we distribute that budget across all 32 teams as a zero-sum allocation: what one team prevents, another must allow.

Each team starts with a backtest-validated projection model, then gets adjusted for scheme-change context, then normalized to match the league total from Step 1.

Loading defensive data...

Stage 1: Gross totals

Base projection uses the model selected by the walk-forward backtest across 2017-2025. We tested a grid of recency-weighted averages with mean-reversion percentages from 0% to 50%, plus linear-trend variants, ridge regression, and strength-of-schedule-adjusted models.

The hypothesis going in: defensive metrics exhibit stronger mean reversion than offensive equivalents. Defense is more dependent on random events (tipped-ball interceptions, scoop-and-scores) and scheme chemistry that doesn't survive coordinator/personnel turnover.

The backtest confirmed this. Yards, sacks, and TFL use 3yr_wavg_mr50 — a 3-year recency-weighted average regressed 50% toward the league mean (offense used 25%). Takeaways, INTs, PBUs, forced fumbles, and defensive TDs are so close to random year-over-year that a flat league_mean beats every other candidate. Points allowed splits the difference with team_50_league_50.

Stage 2: Pass/rush splits + takeaway composition

Once we have gross totals (yards allowed, TDs allowed, takeaways, sacks), we decompose into sub-ratios:

  • Pass yards allowed / total yards allowed
  • Pass TDs allowed / total TDs allowed
  • Interceptions / total takeaways
  • Role-level sack distribution (EDGE/IDL/LB shares — feeds Step 2.5)

Split ratios use a 3-year weighted average with candidate mean-reversion values tested in the backtest. Red zone features were rejected on offense; we test them again here but expect the same result.

Takeaways (tkw_mr50+ expected)

Takeaways get their own model track. Year-over-year correlation is 0.18 — effectively random. Heavy mean reversion (50%+) minimizes error.

Contextual flags (visual only)

The chart displays flags for structural changes — new DC, free-agent star addition, rookie at primary position. Like the offensive engine, these flags are visual context only; the backtest will validate whether they add projection signal, and we suspect — following the offensive result — they will not.

Normalization (zero-sum)

All 32 team projections are rescaled so each metric sums to the league total from Step 1.

Reading the chart

Sort by Value to see which teams project highest. Sort by Change to see the biggest year-over-year movers — these are the teams where DC/personnel turnover is having the most impact. The sparkline shows each team's 5-year trajectory with the 2026 projection as the final dashed point. The vertical red line marks the league average.

Model Selection: Walk-Forward Backtest

How did we choose each model? We backtested ~20 Stage 1 models (totals), 6+ split models, and multiple takeaway models across every season from 2017-2025. For each target season, only prior-year data was visible — no peeking at the future.

The dominant finding — matching the offensive pipeline — is that mean reversion is the strongest signal. Simple 3-year weighted averages with appropriate MR beat complex ridge-regression variants for every metric. The selected production models are documented in the chart below and in the Model Constants Reference appendix.

Loading defensive backtest...

Takeaways and related ball-production stats (INTs, FFs, PBUs, def TDs) have R² so close to zero across every candidate model that league_mean — simply projecting every team to the league average — wins outright. Trying to project which teams will force more takeaways in 2026 is worse than guessing the mean.

Step 2.5: Role Budgets

Before distributing stats to individual defenders, we answer a structural question: what percentage of each defensive stat goes to each role (EDGE / IDL / LB / CB / S)?

Role budgets matter because per-player rates can't simply be summed. If a team's EDGE1 gets injured and the EDGE2 absorbs snaps, both may show "high pressure rates" — but the EDGE position only gets its historical ~33% of team sacks, regardless of who's on the field.

Tackle budgets (LB-heavy)

The LB position commands ~38% of team tackles league-wide. Safeties add another ~22%, CBs ~15%, IDL ~13%, EDGE ~12%. Scheme matters less here than you'd expect — tackle distribution is remarkably stable across 3-4, 4-3, and hybrid schemes.

Pass-rush budgets (EDGE-heavy)

EDGE + IDL combined claim ~65% of team sacks. The split between them is the scheme signature: 3-4 schemes push more pressure through EDGE (often two-gap OLBs rushing off the edge), 4-3 schemes distribute more evenly between EDGE and IDL.

Ball-production budgets (DB-heavy)

INTs and PBUs are ~70% and ~80% DB-driven. Forced fumbles spread across the front seven, fumble recoveries are scheme-agnostic (whoever's closest to the ball).

These budgets feed Step 3, where individual player shares are projected within their role's allocation. New-scheme teams (DC change) blend team-historical budgets with league scheme-average budgets.

Step 3: Roster Share Distribution

Now we connect individual defenders to their team's defensive budget. Each team's projected counting stats from Step 2 are distributed across the 2026 roster, constrained by the role budgets from Step 2.5.

The key question: how much of the defense is accounted for, and how much is up for grabs?

For each team, we pull the current 2026 defensive roster (from Sleeper roster data) and their 2025 production — tackles per snap, sack per pass-rush snap, defensive SHAPE composite. Players are classified as returning or new arrivals. The stat shares tell us how much of the defense is locked up with known commodities vs. being redistributed.

Projection methodology

The projected shares use a tiered, ratio-preserving approach — identical structure to the offensive model:

  1. Roster viability filter — Players with near-zero career defensive snaps AND low defensive SHAPE scores (below 40th percentile) are excluded as likely practice-squad or position-battle losers.

  2. When-active rates — Each player's stats are normalized per defensive snap, not per game. This isolates true role impact from injury-driven games-missed variance.

  3. Ratio preservation — Stickiest year-over-year stats are tackles-per-snap (correlation ~0.62), pressures-per-pass-rush-snap (~0.55), and coverage target rate (~0.48). These are defense's "Tgt%/Snap%" equivalents. Raw tackle counts and raw sack counts regress much more aggressively.

  4. Tiered anchoring — The EDGE1, IDL1, LB1 (and LB2 for teams that rotate heavily), CB1, and S1 are identified as Tier 1 anchors. Their snap shares are held steady with minimal ratio regression (~5%). Tier 2 players fill the remaining role budget proportionally.

  5. Role budget normalization — Within each role group, projected shares are scaled to match the team's historical role budget from Step 2.5. A team with two elite edge rushers can't have them both claim 35% of team sacks — the role budget caps the total.

Loading defensive shares...

What to look for

Teams with high returning share have stable defenses — the same players are in the same roles. Projection confidence is higher.

Teams with heavy new arrivals (major free-agent additions, trade acquisitions, rookies drafted to start) are volatile. Role budgets hold — someone's filling the LB1 slot — but individual projections for the specific player have wider ceilings.

The unaccounted share represents production from defenders no longer on any NFL roster. This share redistributes proportionally among Tier 2+ players at the same role.

Step 4: Player Stat Projections

With shares assigned and team budgets locked, we now convert defensive opportunity into counting stats. This is where efficiency enters the model — not every pass rush produces pressure, not every coverage snap produces a target, and INT rate depends heavily on coverage scheme and target quality.

Efficiency aggregation

We aggregate play-by-play data from pbp_raw across 2023-2025, computing per-player rates for:

Front-7 (EDGE / IDL / LB):

  • Pressures per pass-rush snap
  • Sacks per pressure (finish rate)
  • TFL per run snap
  • QB hits per pass-rush snap

Coverage (CB / S / LB-cover):

  • Coverage target rate (targets per coverage snap)
  • Completion % allowed
  • Yards per target allowed
  • INTs per target
  • PBUs per target
  • TDs allowed per target

Tackling (all):

  • Tackles per defensive snap
  • Solo tackle share (solo / total)

Ball production (all):

  • Forced fumbles per snap
  • Fumble recoveries per opportunity

These rates are recency-weighted (2025 at 4x, 2024 at 2x, 2023 at 1x) and volume-weighted (a 400-snap season influences the average more than a 100-snap season).

Efficiency by view

Toggle between Tackling, Pass Rush, Coverage, and Ball Production views to see each player's efficiency profile by skill. The rate columns show career-weighted rates with minimum thresholds (≥200 career defensive snaps, ≥50 2025 snaps) to avoid noisy small samples. Rookies without prior snaps use role-level medians as a baseline.

Loading defensive efficiency...

What to look for

  • High snap share + high efficiency = safe IDP floor (e.g., every-down LB with 96% snap share and 0.18 tackles-per-snap)
  • High snap share + low efficiency = volume-dependent (e.g., nickel CB with high coverage volume but low INT rate)
  • Pass-rush concentration = sack upside. EDGE rushers with 500+ pass-rush snaps AND high pressure rate claim a disproportionate share of team sacks
  • New arrivals use prior-team rates, regressed toward role means

Step 5: Distribution Validation

The final step validates our projections against reality. We compare the 2026 projected IDP123 fantasy point distribution against actual 2023-2025 distributions by positional rank — EDGE1-30, IDL1-20, LB1-40, CB1-40, S1-30.

The goal isn't to predict outlier ceiling seasons. The goal is distribution shape fidelity: does our LB15 project close to where a real LB15 has historically scored?

Loading defensive validation data...

Model evolution: v1 to v3

The projection model went through three iterations to reach this accuracy:

v1 (budget-normalized): Every player scaled to sum exactly to team budget. Caused severe compression — elite defenders (Myles Garrett, Frankie Luvu) got suppressed, backups got inflated. LB RMSE was ~45, EDGE RMSE ~18.

v2 (rate-based, no budget normalization): Stats computed directly from per-snap rates × projected snaps. Removed compression, but top-end was still under-projected because career-average rates regress recent peaks and the tier-1 regression factor was too aggressive (20%).

v3 (weighted rates + TO unification + tier-1 regression relaxed): Three changes tightened the fit:

  1. Takeaways projected as a single bucket — We stopped projecting INTs independently. Year-over-year INT correlation is ~0.15; forcing an INT projection per player introduced noise. Instead we project total takeaways from D2 (~18.8/team league average), then split historically (~70% INT, ~30% FR) per team.
  2. Weighted per-snap rates — 2025×4 / 2024×2 / 2023×1 applied to both stats and snap denominators. A player whose tackle rate climbed from 0.12 → 0.18 gets projected closer to 0.16 than to a flat career 0.15.
  3. Tier 1 regression relaxed to 5% — Elite every-down defenders (EDGE1, LB1, S1) were over-regressed at 20%. Dropping to 5% preserved trajectory for players like Hutchinson, Parsons, Luvu who demonstrably deliver above-role-median output.

Position-specific findings

Measured from the D5 rank-based validation (2026 projection vs 2023-2025 averages, IDP123 scoring):

  • EDGE (RMSE 7.6, MAE 4.6, Grade A): The best fit. EDGE15 within 3 points of historical avg, EDGE1 within 2. Sack volume is highly predictable for the top tier.
  • LB (RMSE 29.3, MAE 12.5, Grade C): Good mid-range fit (LB20 within 8 points), but the top end is inflated. Every-down MIKEs at 100% snap share with full-season availability blow past the historical LB1 average of ~195 pts. This is a projection assumption issue — we're projecting full health; actual LB1 averages mix injury-shortened seasons.
  • S (RMSE 13.2, MAE 10.4, Grade B): Slight positive bias (+10). Safety tackle volume is scheme-stable; the overprojection comes from takeaway regression inflating expected INT/FR counts for starters.
  • CB (RMSE 12.6, MAE 11.7, Grade B): Slight negative bias (-8). CB projections under-sell the handful of top-end INT/PBU seasons that drive the historical CB1-5 tier — because INT rate is ~random, we can't structurally forecast it.
  • IDL (RMSE 15.7, MAE 15.1, Grade C): The hardest to project. Sack production varies wildly; tackle volume is scheme-dependent. Systematic under-projection (-15) reflects the role getting a small ~13% slice of tackles + 22% of sacks — the floor is low for all but the elite handful.

Methodology notes

  • Validation is rank-based, not player-based. We compare "our projected LB5" against "the historical average LB5," not "our projection for Roquan Smith" against "what Roquan Smith actually scored." This tests distribution shape, not individual accuracy.
  • Actual averages use 2023-2025 with equal weight. Players must have played 4+ games to qualify for a rank slot.
  • The model does not try to predict ceiling seasons. A historical LB1 averaging 195 points includes outlier takeaway seasons. Our LB1 projection represents a strong-but-not-historic season — the expected mean, not the upside.
  • IDP scoring = Sleeper IDP123 default. Solo 1.0, assist 0.5, TFL 2.0, sack 4.0, QB hit 1.0, INT 6.0, FF 4.0, FR 2.0, PBU 1.5, def TD 6.0.

Statistical rigor: what actually predicts next year?

Honest YoY R² from scripts/defensive_projection_analysis.py tells us which stats carry real signal and which are noise. Rate stickiness drives how heavily each stat should anchor on player history vs. regress to the role mean.

Loading stability analysis…

Team-level YoY R² (2020-2024 walk-forward, 3-year weighted avg, no mean reversion):

StatVerdict
tackles_for_loss0.136Weak but real — scheme signature persists
pass_yards_allowed0.070Near-noise
yards_allowed0.065Near-noise
sacks0.061Near-noise — pressure ability doesn't transfer YoY at team level
total_takeaways0.059Near-noise
interceptions0.046Essentially random
rush_yards_allowed0.042Essentially random
pass_breakups0.027Essentially random
defensive_tds0.026Essentially random
points_allowed0.008Random
forced_fumbles0.005Random

This is why D2 selects league_mean for 5 of the 6 ball-production stats — it genuinely wins the backtest.

Player-level per-snap rate YoY R² (role-filtered, min 30-100 snaps by rate):

RateEDGEIDLLBCBS
QB hits / rush snap0.4570.2310.0850.1440.238
Sacks / rush snap0.2700.0460.0460.0320.030
Tackles / snap0.2290.2230.1580.1260.168
TFL / run snap0.1720.1730.0450.0660.128
PBU / pass snap0.0890.0830.0320.0440.054
INT / pass snap0.0180.0020.0380.0220.054
FF / snap0.0260.0000.1150.0020.003

EDGE pass-rush pressure (QB hits and sacks per rush snap) is the single most predictable defensive stat — R² of 0.46 for QB hits is stronger than offensive target share stickiness. This validates projecting EDGE sacks from per-rush-snap rate × projected rush snaps. Tackle rate is moderately sticky across all roles. INT and FF rates are essentially random at the player level — which is why we project takeaways (INT + FR) as a single bucket and surrender trying to forecast the split.

Player walk-forward IDP PPG backtest (holdout 2022-2024, 3-year weighted average baseline):

RolenMAE (PPG)RMSE
IDL2791.101.420.543
LB2361.872.440.392
EDGE4391.762.250.393
S2811.602.010.306
CB3121.391.750.235

A naive 3-year weighted average of prior IDP PPG projects IDL the best (R²=0.54) and CB the worst (R²=0.24). The full D3+D4 pipeline needs to beat these R²s to justify its complexity.

Tuning impact: distribution-shape fitting (v3.3)

Five tunings stack together to make projected rank curves fit historical distributions:

1. R²-scaled share regression. Flat tier regression (5%/20%) replaced with reg = clip(0.05 + 0.5 × (1 - R²), 0.05, 0.55) per (stat, role), capped at 0.35 for tier-1. EDGE QB hits (R²=0.46) barely budge; CB INTs (R²=0.02) heavily regress toward opportunity-based baseline (snap-share-in-role).

2. Phantom future-signing denominator. Scales the role-denominator up to expected league role-snap totals when the active 2026 roster's weighted snaps fall short. The unclaimed portion represents production from future signings / rookies not on the roster. Phantom fires for LB/CB/S only; disabled for EDGE/IDL where rotational depth redistributes naturally.

3. Tier-2 baseline discount (0.80). Backups tackle at below-starter per-snap rates even at the same snap share — less talented, face 2nd-team offense, weaker scheme priority. Tier-2's regression baseline = snap_share × 0.80, so less share flows to backups. For LB and S, the discount is disabled when a tier-2 player has ≥55% of tier-1's snap share (legitimate co-starter rather than backup).

4. Within-role renormalization. After discount/regression compresses tier-2 share, active-roster shares per (team × role × stat) are rescaled to sum to (1 - phantom_share). This redirects the tier-2 savings to tier-1 starters, where the historical production came from, instead of leaving it on the floor.

5. Historical top-5-avg caps. stats_2026_projected clipped at TOP5_AVG_PER_SEASON × 1.2, where TOP5_AVG is the 2015-2025 average per role per stat of each season's top-5 performers. Using top-5 avg (not single-season peak) because the rank-distribution validation compares our projected top 5-30 to historical average top 5-30 — single-season peaks (Watt 22.5 sk, Baker 153 tkl) are 2-3σ events we can't structurally forecast, so we don't project every team's top defender up to the all-time peak.

Per-role top-5-avg stat ceilings (tackles / sacks / TFL / INT / PBU):

RoleTKLSACKTFLINTPBU
EDGE10114.41928
IDL638.71215.4
LB14251239
CB822.575.719
S1123.58513

Rank-distribution metrics, baseline → final tuned:

RoleBaseline RMSEFinal RMSEΔBaseline BiasFinal Bias
EDGE7.67.1-0.5-0.3+3.7
IDL15.713.0-2.7-15.1-11.3
LB29.312.2-17.1-3.5-8.5
CB12.66.5-6.1-8.3-5.5
S13.27.8-5.4+10.1+1.4

Band analysis (mean delta, projected minus historical avg):

RoleTop-5Mid (10-20)Bottom (last 10)
EDGE+6.4+2.1+3.2
IDL-14.7-8.4-8.3
LB+6.2-8.2-19.2
CB-3.4-7.0-6.5
S+10.8+1.9-7.1

Addressing the diagnostics:

  • LB Luvu: 397 → 199. Phantom cut departed-Wagner inheritance, top-5-avg cap (142 tkl × 1.2 = 170 tkl) trimmed residual, R²-scaled shrinkage kept tackle rate reasonable. Final sits within historical LB1 avg of 195.
  • Safety top-14: Dropped from +28 bias to +11. S1 Bynum 175 vs historical 167 — right in range. Co-starter exemption lets MIN's Metellus + Bynum both stay at realistic levels without one artificially inheriting the other's share.
  • CB distribution: Now dead-on. CB1-12 all within ±7 of historical averages. CB mid-band slightly under (-7) — acceptable; reflects tier-1 CB rate stickiness being modest.
  • IDL: Improved (-15 → -11 bias) but IDL1 Simmons still -35. This is structural: top IDL historical averages include Aaron Donald–tier seasons (20.5 sacks) that only one DT per decade achieves. Role-wide IDL sack R² is 0.046 — we cannot structurally forecast who will have a 15-sack DT season. Top IDL projection sits at a sober ~128 IDP while historical S1 averages 162. Manufacturing inflation here would require injecting unearned signal.
  • LB depth (rank 30-40): Residual -19 under-projection. These are legitimate tier-2 starters on deep LB rooms (Roquan Smith on LAR behind Ernest Jones). The co-starter exemption helps modestly; full fix would require per-team LB1/LB2 anchor tuning we haven't added yet.

Appendix: Pipeline Execution Guide

Follow these steps in order whenever rosters change (post-draft, free agency, trades, cuts) or when underlying data updates.

Prerequisites

  • Supabase credentials in backend/.env
  • Python 3.10+ with packages: supabase, numpy, python-dotenv
  • Populated through current season: team_defensive_season, player_defensive_season, team_season_points, coach_assignments, team_defensive_scheme, player_snap_season, player_shape_scores (side_of_ball='DEF')

Step D1: League Defensive Trends

Script: scripts/defensive_league_trends_analysis.py Output: public/data/league-defensive-trends.json What it does: Projects league-wide defensive totals for 2026 using recency-weighted regression across all 32 teams. These totals become the zero-sum budget that all team defensive projections must sum to.

python scripts/defensive_league_trends_analysis.py

Step D2: Team Defensive Output Backtest + Production

Scripts:

  • scripts/defensive_team_projection_backtest.py (study)
  • scripts/defensive_split_model_backtest.py (splits study)
  • scripts/defensive_team_projections_analysis.py (production)

Outputs:

  • public/data/team-defensive-projection-backtest.json
  • public/data/defensive-split-model-backtest.json
  • public/data/team-defensive-projections.json

What it does: Walk-forward backtest 20+ candidate gross-total models and 6+ split models across 2017-2025. Production script reads the winning model keys and distributes the league budget from Step D1 across 32 teams.

python scripts/defensive_team_projection_backtest.py
python scripts/defensive_split_model_backtest.py
python scripts/defensive_team_projections_analysis.py

Step D2.5: Defensive Role Budgets

Script: scripts/defensive_role_budgets_analysis.py Output: public/data/team-defensive-role-budgets.json

python scripts/defensive_role_budgets_analysis.py

Step D3: Roster Defensive Share Distribution

Script: scripts/defensive_team_share_analysis.py Output: public/data/team-defensive-shares.json

D3 consumes defensive-projection-analysis.json (if present) to size the R²-scaled shrinkage — run the analysis script first to keep shrinkage weights fresh.

python scripts/defensive_projection_analysis.py  # produces YoY R² lookups (one-off until stats change)
python scripts/defensive_team_share_analysis.py

Step D4: Player Defensive Efficiency Aggregation

Script: scripts/defensive_player_efficiency_aggregation.py Output: public/data/player-defensive-efficiency.json

python scripts/defensive_player_efficiency_aggregation.py

Step D5: Distribution Validation

Script: scripts/defensive_projection_validation.py Output: public/data/defensive-projection-validation.json

python scripts/defensive_projection_validation.py

Step D6: Rankings Integration

Source: backend/transformations/transforms/layer4_player_defensive_projections_v2.py Table: player_defensive_projections_current

Populates the defensive-projection table consumed by IDP rankings + share-card defensive projections. Graceful degradation: if the table is empty, IDP rankings fall back to paced prior-season actuals.

cd backend && python -c "from transformations.transforms.layer4_player_defensive_projections_v2 import PlayerDefensiveProjectionsV2Transform; PlayerDefensiveProjectionsV2Transform().run()"

Full Pipeline (all steps in order)

# D1: League defensive trends (run once, rarely changes)
python scripts/defensive_league_trends_analysis.py

# D2: Team projections (re-run after DC/personnel changes)
python scripts/defensive_team_projection_backtest.py
python scripts/defensive_split_model_backtest.py
python scripts/defensive_team_projections_analysis.py

# D2.5: Role budgets
python scripts/defensive_role_budgets_analysis.py

# Rigor layer — YoY stability + SHAPE integration + player walk-forward.
# Feeds D3's per-(stat, role) shrinkage weights. Re-run after schema changes
# or when adding a full new season of data.
python scripts/defensive_projection_analysis.py

# D3: Player share distribution (re-run after roster change)
python scripts/defensive_team_share_analysis.py

# D4: Player efficiency (re-run after PBP data update)
python scripts/defensive_player_efficiency_aggregation.py

# D5a: Budget + league + per-player sanity check on D3
python scripts/defensive_distribution_validation.py

# D5: Rank-distribution validation (re-run after methodology change)
python scripts/defensive_projection_validation.py

# D6: Populate rankings table
python -m backend.transformations.transform_runner layer4_player_defensive_projections_v2

Backtest Scripts (validation only — not part of the production pipeline)

These scripts were used to select the production models. Re-run them only if you want to add new candidate models or validate with additional seasons of data.

  • scripts/defensive_team_projection_backtest.py — Tests ~20 Stage 1 models, multiple split models, and takeaway models across 2017-2025 with walk-forward validation. Output: public/data/team-defensive-projection-backtest.json
  • scripts/defensive_split_model_backtest.py — Tests candidate split models for pass yards / INT / FF shares. Output: public/data/defensive-split-model-backtest.json
  • scripts/defensive_distribution_validation.py — Budget conservation + league aggregation + per-player plausibility + position distribution sanity check on the D3 output. Output: public/data/defensive-distribution-validation.json
  • scripts/defensive_projection_analysis.py — The statistical rigor layer. Walk-forward team backtest (R² per stat), per-snap rate YoY stability (role × rate), SHAPE integration, and player-level PPG walk-forward R² per role. This is the defensive analog of projection_analysis.py. Output: public/data/defensive-projection-analysis.json

Model Constants Reference

Measured values from the completed backtests. Mirrors the offensive engine where possible; defensive-specific constants called out.

ConstantValueLocationMeaning
RECENCY_WEIGHTS{2025: 4, 2024: 2, 2023: 1}defensive_team_share_analysis.py3-year recency weights
Stage 1 MR (yards/sacks/TFL)50% (3yr_wavg_mr50)defensive_team_projections_analysis.pyTeam stat regressed 50% toward league mean
Stage 1 MR (takeaways/INT/FF/PBU/def TD)100% (league_mean)^Pure league mean — year-over-year signal near zero
Stage 1 MR (pts allowed)50/50 (team_50_league_50)^Team 50% / league 50% blend
TIER_1_RATIO_REGRESSION0.05defensive_team_share_analysis.pyTier 1 regression toward role uniform
TIER_2_RATIO_REGRESSION0.20^Tier 2+ regression toward role uniform
MIN_CAREER_DEF_SNAPS200^Viability floor for projection inclusion
MIN_MOST_RECENT_SNAPS50^2025-season floor to exclude dormant vets
SEASON_WEIGHTS{2025: 4, 2024: 2, 2023: 1}defensive_player_efficiency_aggregation.pyPer-player efficiency rate recency
IDP scoringSleeper IDP123 defaultlayer4_player_defensive_projections_v2.pySolo 1.0 / Ast 0.5 / Sk 4.0 / INT 6.0 / etc.
PROJECTION_YEAR2026defensive_team_projections_analysis.pyUpdate annually

Architecture: Rankings Integration

Scripts (D1-D5)            Backend Transform (D6)           Frontend (IDP Rankings)
─────────────────────      ────────────────────────         ───────────────────────
league-defensive-trends.json  ─┐
team-defensive-projections    ─┤
team-defensive-role-budgets   ─┤─▶ layer4_player_defensive_    ──▶ player_defensive_
team-defensive-shares         ─┤   projections_v2                  projections_current
player-defensive-efficiency   ─┤                                          │
defensive-projection-         ─┘                                          ▼
  validation                                                     PlayersDatabase.getDefensiveProjections()
                                                                          │
                                                                          ▼
                                                                IDP Rankings Page

Fallback behavior: If player_defensive_projections_current is empty, the IDP rankings engine falls back to pacing prior-season defensive actuals. Rankings always render — projections make them better.

Post-Draft Checklist

  1. Verify coach_assignments has 2026 entries for all 32 teams (DC changes flagged)
  2. Run defensive SHAPE transform so drafted rookie defenders have scores
  3. Run Steps D1-D5 in order
  4. Run Step D6 to populate player_defensive_projections_current
  5. Verify article charts render with updated data at /football/fantasy/research/projection-engine-2026-defense
  6. Verify IDP rankings reflect projected stats (not paced actuals)

This article is part of Ball Street's Living Articles series — every chart and stat updates automatically as new data arrives from our pipeline. Browse all articles.

Explore more: Football Hub