How the numbers are computed
Every number on this site is computed deterministically from the underlying source data. AI-generated text is labeled and validated by a separate model pass.
01Aggregation methods−
Every chart can switch between 6 methods. None are 'right' — each makes different tradeoffs.
- Simple mean
- Unweighted arithmetic average of polls in the rolling window. Every poll counts the same. Noisy but transparent.
- Weighted
- Weights = sample size √(n/600) × recency exp(-age × ln(2)/14d) × pollster accuracy weight (1.0 default; up to 4.0×).
- House-corrected
- Same as Weighted, but each pollster's measured signed bias is subtracted from each result before averaging. Production default for race pages.
- Trimmed
- Same weights as Weighted, but the highest and lowest 10% of polls per anchor date are dropped. Robust to outliers.
- LOESS
- Local polynomial regression (frac=0.3). Smoother visual trend, less reactive to single polls. Requires ≥3 polls per candidate.
- Kalman state-space
- Models the true value as a latent random walk and polls as noisy observations. The smoothest line — closest to what 538 / Silver Bulletin show.
02Race ratings+
Each race gets one of: Safe / Likely / Lean / Tilt × D/R, plus Tossup. Source priority: polls → markets → PVI baseline.
| Margin |D−R| | Rating |
|---|---|
| ≥ 15 pt | Safe |
| 5–15 pt | Likely |
| 2–5 pt | Lean |
| 0.5–2 pt | Tilt |
| < 0.5 pt | Tossup |
When no recent polls exist, we fall back to (a) prediction market implied probability or (b) the state's Cook PVI — one rating bucket more conservative than the PVI suggests.
03Pollster scorecards+
- Race scorecard — for polls within 21 days of an election with a known outcome, compute implied two-way margin (R% − D%) − actual margin = error. Mean error is the pollster's accuracy; signed mean error is the bias.
- Topic scorecard — for topic polls (approval, generic ballot, etc.) where there's no "outcome", compare each poll to the rolling consensus of all other pollsters on the same topic within ±30 days. The deviation is the pollster's house effect.
Pollsters with mean_error ≤ 4pt and ≥3 scored polls get an aggregation weight = 4 / mean_error, clipped to [0.25, 4.0].
04Chamber control probability+
Monte Carlo, 20,000 simulations. Each race draws independently from its rating-implied D-win probability:
| Rating | P(D wins) |
|---|---|
| Safe D | 99% |
| Likely D | 92% |
| Lean D | 78% |
| Tilt D | 60% |
| Tossup | 50% |
| Tilt R | 40% |
| Lean R | 22% |
| Likely R | 8% |
| Safe R | 1% |
Independent draws over-state polarization in close years. Real elections have national waves — a +3 R cycle moves all races, not each one independently. A correlated-swing model is on the roadmap.
05Backtest results+
Leave-one-cycle-out cross-validation: train on every cycle except one, then score the held-out cycle. Below is the most recent held-out cycle (2024, n=43 races) per model, sorted by mean absolute error. Lower is better.
| Model | MAE | RMSE | Brier | ECE |
|---|---|---|---|---|
| Ensemble (production) | 6.56pt | 12.00pt | 0.0622 | 0.0605 |
| Random forest | 7.53pt | 13.88pt | 0.0558 | 0.0575 |
| Gradient-boosted (qgbt) | 7.76pt | 15.09pt | 0.0560 | 0.0703 |
| Ridge regression | 8.35pt | 13.65pt | 0.0698 | 0.0724 |
| Kalman state-space | 8.38pt | 13.39pt | 0.0607 | 0.0418 |
| PVI baseline | 12.50pt | 17.01pt | 0.1204 | 0.1428 |
| Prediction markets | 18.50pt | 22.48pt | 0.2500 | 0.0814 |
Source: /data/backtest.json · generated 2026-05-04 · polagg-v1 · scored 21d before election. Full backtest →
Polling-industry error is correlated within a cycle: when polls miss, they tend to miss the same direction nationwide (2016 and 2020 both under-counted Republican support). The house-effect correction removes each pollster's persistent lean, but it cannot anticipate a fresh, cycle-wide systematic miss — that residual is the largest unmodeled source of error.
06AI-generated content+
Daily reports, race summaries, topic summaries, state briefings, ballot-measure explainers, weekly digests, and glossary entries are generated by Claude (via the local CLI). Each piece goes through a separate validator pass that checks every claim against the source data, and daily/weekly reports additionally go through an editorial reviewer gate. Content that fails validation or review iswithheld — only verified content is published.