THE MODEL DUEL
How this works

Methodology

The same pipeline runs for every Chase race. The only thing that changes race to race is the input data — never the model spec or the scoring rules, so the end-of-season comparison stays honest.

The two models

Both are RandomForestRegressor (scikit-learn), n_estimators=100, regularized to max_depth=5, min_samples_leaf=3. Target is average finish position.

  • Basic — box-score inputs: average start, win %, top-10 %, finish %, success rate.
  • Advanced — engineered loop-data inputs: speed score, pass-gain above expected, cumulative production over multiple starts (cPOMS), weighted average running position (wARP), average position vs. expected.

Training set

Each model trains on the full intermediate-track field for the 2026 season — every car with data, not just the current entry list. Restricting to entrants happens only when building the per-driver profile that gets fed in for the projection, so no training rows are wasted and non-entrants never leak into the output.

Blending history with current form

A driver's input profile is a weighted blend of their track-specific history and their track-type season form. Darlington ran 60% season form / 40% track history — small track-history samples are noisy and current-year pace is the better signal, but Darlington is enough of a specialist track that history still gets real weight. Drivers with no track history get a form-only projection, flagged separately.

Cross-validation

In-sample error on a Random Forest looks near-perfect and means nothing on a ~40-row dataset. The trustworthy pre-race number is 5-fold cross-validated MAE. Expect it to be optimistic versus race day: a single 38-car race carries attrition, cautions, and upset winners that no pre-race model prices in.

Scoring

Once the results are in, each model is graded on the full field:

  • MAE / RMSE — average and outlier-weighted miss, in positions.
  • R² — variance in actual finish explained by the projection.
  • Top-5 / top-10 hit rate — how many predicted top finishers actually finished there.

The model with the lower MAE “wins” that race. Feature importances are stored per race and aggregated into the end-of-Chase writeup.

Data pipeline

Models are run locally in Python race week; projections and, after the race, finishing order plus loop data are loaded into Supabase (Postgres). This site reads that schema directly — races, drivers, predictions, results, model_scores, and feature_importances — with row-level security set to public read-only.