Skip to content
D1 Picks

How the model works

Every number on D1 Picks comes from one published model, fit to public results, tested on matches it had not seen, and graded in public. This page is the whole recipe for model vb-bt-1, the volleyball model running today. If the model changes, its version changes, and this page says how.

The short version

  • Each D1 team gets one rating, fit to every set of D1 against D1 volleyball played this season.
  • Two ratings and home court give the chance of winning a set; the set chance gives the match chance and the odds of every set score.
  • Raw match probabilities run hot, so we shrink them with a calibration fit only on out-of-sample predictions.
  • Each match is predicted once, before first serve, and graded after the final. The record started at zero.
  • The model knows results, opponents and home court. It knows nothing about injuries, lineups or travel.

The data

Results and schedules come from the NCAA.com Division I scoreboard, read once a day from the same JSON feed that page loads, one request per date and never more than one request a second. For each match we keep the two teams, which one is at home, the sets each won, the scheduled start, each team's conference and its AVCA poll rank, plus a link back to the NCAA.com match page. Every result shown on this site links there.

A team counts as D1 when NCAA.com lists it in one of the 32 Division I volleyball conferences. Matches against non-D1 opponents are dropped, and so are the few that did not finish as a best-of-five. Today's ratings use 2,602 D1 matches through Oct. 4 covering 348 teams.

We would rather read stats.ncaa.org directly, but it refuses scripted requests, so the scoreboard feed is the source. It has one known gap: it marks one team as home in every match, including the handful played at neutral sites, so the model gives home court to a team that may not have had it.

The rating model

The model is a Bradley-Terry model on sets. Team i has rating ri. When home team h plays away team a, the chance the home team wins any one set is:

p = 1 / (1 + exp(-(r_h - r_a + H)))

H is one home-court term shared by every team, fit from the data. Today it is 0.179, which means two evenly rated teams split sets 52.8% to the home side, and the home side wins the match 55.3% of the time after calibration.

The ratings are the values that make this season's set results most likely, with one guard: a prior that pulls every rating toward 0, the average D1 team. It is a normal distribution with precision 0.25 (a standard deviation of 2.0 rating points), and it is what stops a 3-0 team from getting an infinite rating in week one. The fit is solved with Newton's method.

A match stops when a team wins three sets, which sounds like it should bias a model that counts sets. It does not: because the stopping rule depends only on the set results themselves, the likelihood for the set probability is the same as if every set had been planned in advance.

Calibration

Turning a set probability into a match probability assumes sets are independent, and they are not quite: a team that is sharp on the night tends to win sets in bunches. Left alone, that makes the model overconfident. In the backtest, raw probabilities scored a log loss of 0.523; after calibration, 0.503.

So we shrink the raw match probability toward 50% with one number, k:

p_match = 1 / (1 + exp(-k * logit(p_raw)))

k is fit only on predictions the model made out of sample, before it saw those results. Today k is 0.629, fit on 1,853 out-of-sample predictions. The set-score odds are then recomputed from the set probability that matches the calibrated number, so the six set scores always add up to the headline probability.

Set-score odds and fair lines

With a set probability p for the home team and q = 1 - p:

home 3-0 = p^3
home 3-1 = 3 p^3 q
home 3-2 = 6 p^3 q^2
(and the same with p and q swapped for the away team)

A fair line is the match probability written as American odds with no bookmaker margin: a favorite at probability P is -100 P / (1 - P), an underdog is +100 (1 - P) / P. It shows what our number is worth as a price. Since we quote no market prices, it is never a bet call.

The backtest

A walk-forward backtest replays the season: for each match day from Sept. 5 to Oct. 4, the model is fit only on earlier days and predicts that day's matches, with calibration also fit only on earlier days. Scoring starts once the typical team has played 4 D1 matches. Across 1,853 matches the favorite won 75.0% of the time (the home team won 56.2%), with a Brier score of 0.165 against 0.250 for a coin flip. The calibration table is on the results page.

The prior strength was chosen on this backtest. Here is every value we tried:

Prior precisionLog lossBrierFavorite won
0.06255.4460.27768.6%
0.1250.5040.16475.3%
0.25 (used)0.5030.16575.0%
0.50.5060.16874.5%
10.5150.17273.3%
20.5290.17872.1%

Picking a setting on the same data you report flatters the result a little, so read the backtest as a sanity check and the live record as the real test. The weakest prior in the table shows why the prior exists: with almost no pull toward average, early-season ratings blow up and the predictions score worse than a coin flip.

Predictions and grading

  • Every morning the job rates every team and predicts every D1 match in the next 3 days that does not have a prediction yet.
  • A match is predicted once. The number is written to an append-only log with a timestamp before first serve (before midnight Eastern on match day when no start time is published) and is never revised.
  • After the final, the grade is appended: winner, set score, whether the favorite won, Brier score and log loss. A canceled or moved match is voided and does not count.
  • The record started at zero with the first logged prediction. There are no backfilled or preseason entries, and a check fails the publish if any logged line changes.

Which matches get a full preview

Most matches are a row on the predictions board. A match gets its own preview page only when both teams have played at least 6 D1 matches and at least one of these holds:

  • both teams are in the AVCA poll;
  • both teams are in our top 40;
  • it is an NCAA tournament match;
  • people measurably search for the matchup (from our keyword research).

At most 5 previews a day per sport and 12 across the site, and none at all if fewer than half of them are getting indexed by Google. Each preview's written analysis is generated from its numbers, and a check rejects the page if any number in the text cannot be traced to the saved model output or NCAA.com results. The editorial policy explains why these pages publish without a human edit.

What the model cannot see

  • Injuries, illness, lineup and rotation changes, or a starter sitting out.
  • Travel, rest and back-to-back weekends.
  • Neutral sites, which the feed marks as home games.
  • Anything from earlier seasons: ratings start from average every August.
  • Market prices. We quote none, so we make no claim of an edge over anyone.

If you know something the model does not, adjust from the number. That is what it is for.

Versions

vb-bt-1, introduced Oct. 4, 2026: Bradley-Terry on sets with one home-court term, a normal prior of precision 0.25 and walk-forward calibration.