Defoor Ratings Home 2026 weeks Method 2016–2025

How the ranking algorithm works

An in-depth, code-faithful description of the FBS ranking system: iterative game points, opponent-adjusted offense/defense, schedule strength, and how weekly revaluation works. Weights below match the current late-season-tuned config.yaml.

1. Motivation and design goals

Human polls (AP, Coaches) blend résumé, eye test, and narrative. This model aims to be comparable to those polls late in the season while remaining fully algorithmic and reproducible. Design priorities:

2. Data sources

All inputs come from ESPN public APIs (site + core), cached under data/{year}/:

No CollegeFootballData API key is required. If ESPN lacks team-stats for a season/team (notably parts of 2020), the model falls back to empty YPP metrics and game-derived scoring averages.

3. Weekly snapshot and retroactive revaluation

For any week W, the model uses only games completed through week W (plus postseason games for the final ranking). It then runs an iterative fixed-point procedure: opponent strengths are re-estimated until ratings stabilize. That means a Week 3 win over a team that later proves elite is re-valued upward as the season progresses — the same game contributes more once the opponent’s rating rises.

Through week W:
  Games = { g | week(g) ≤ W }  (final: also postseason)
  Repeat until max |rnew − rold| < 1e-06:
    1. Normalize current ratings → z-scores r̂
    2. Score every game using opponents’ current r̂
    3. Recompute opponent-adjusted O/D using current r̂
    4. Blend components → new rating; damp with λ = 0.82

Iteration cap: 100. Damping prevents oscillation.

4. Iterative game points

Each decided FBS-involved game adds points to the winner and (negative) points to the loser. Base values from config:

Opponent multiplier (centered near 1.0):

opp_factor(r_opp) = 0.45 + 1.1 · σ( opp_strength_scale · r_opp )
  where σ is the logistic sigmoid, opp_strength_scale = 1.15

Additional multipliers:

5. Opponent-adjusted offense and defense

For each team-game observation, points scored/allowed are compared to both league averages and the opponent’s season averages, then scaled by opponent unit quality:

off_base = wL·(pts − league_PPG) + wO·(pts − opp_PAPG)
off_val  = off_base · clip(1 + k·opp_def_z, 0.35, 2.0)

def_base = wL·(league_PAPG − allowed) + wO·(opp_PPG − allowed)
def_val  = def_base · clip(1 + k·opp_off_z, 0.35, 2.0)

wL = 0.45, wO = 0.55, k = 0.35

Opponent unit z blends season PPG/PAPG z-scores with the opponent’s current overall rating (rating_blend = 0.4). FCS opponents use fixed weak unit z (-1.0 / -1.0) and inflated/deflated average lines.

Schedule-weighted season O/D

Game O/D values are aggregated with weights that favor tougher opposing units:

weight(opp_z) = max( floor, (1 + softplus(opp_z))exp )
floor = 0.12, exp = 1.3

season_off = weighted_mean(off_val) · (1 + od_sos_weight · mean_opp_def_z)
od_sos_weight = 0.22

Offense then mixes a small raw YPP z-score (weight 0.12). Defense is the z-score of schedule-adjusted defensive values. Soft schedules cannot pad O/D ranks the way they can pad raw scoring averages.

6. Strength of schedule, record, H2H, preseason

7. Final score blend (current weights)

Component z-scores are blended into a rating, then mapped to a display score ≈ 50 + 15·z(rating) (+ H2H):

BlockWeightNotes
Game points (iterative)0.55Residual so weights sum to 1.0 among GP+Eff+SOS+Record
Efficiency (off + def)0.21Split evenly across O and D
SOS (conf-blended)0.17
Record0.07
Preseason prior0.05×priorAdditive; decays by week

8. Tuning history (brief)

  1. Levers 1–4 — raised SOS/conference role, stronger preseason prior through midseason, softened quality losses, tightened FCS cupcake wins. Snapshot: config_before_levers_1_4.yaml.
  2. Late-season tune (2016–2025) — optimized final + end-regular AP Spearman/overlap (train 2016–19 + 2021–23; holdout 2024–25), protecting a high final #1 match rate. Snapshot before: config_before_late_tune.yaml. Details in output/decade/late_tune_results.md.

Weights were kept modest to reduce single-year overfitting. Early-season agreement was not the optimization target.

9. Preseason = Coaches Poll

The preseason board sets ranks 1–25 equal to the AFCA Coaches Poll. After Week 1 games, the full model runs with Coaches as a decaying prior. Post–Week-1 boards are not forced to any poll.

10. Biggest Win (current season)

On the 2026 Top 25, Biggest Win is the win vs the highest-quality opponent (best/lowest converged model rank that week). Ties → higher game_points, then later week.

11. Limitations