Methodology

How we compute behavioral mood and probabilistic race forecasts. Live model: lr-2026-06-10-chal-recal-twospeed, test Brier 0.119.

Three legs of the forecast

The VoteROI.com Mood Forecast is not a mood-only model. "Mood" is one of three legs, and the race forecast rests on all three:

  1. Structure (fundamentals). The partisan lean of the state, incumbency and the incumbent's prior personal vote, and candidate-level challenger money (the Democratic share of two-party pre-election Senate receipts). These are the slow-moving facts of a race.
  2. Behavioral mood. The cross-sectional state-mood index built from publicly reported behavioral data. This is the layer the name points to, and it moves the structural baseline, it does not replace it.
  3. The thermostat (long-run swing). A deep-estimated midterm correction: the president's party tends to lose ground in midterms, applied as a calibrated national swing.

Structure anchors the forecast, mood adjusts it, and the thermostat applies the long-run midterm regularity. Where a large mood signal runs against a decisive structural and incumbency lean, the race page says so plainly and treats the call with caution.

Core Premise

Polling measures stated opinion. We measure revealed behavior. People can lie to a stranger on the phone; they cannot lie to their unemployment filing, their voter registration record, their vehicle miles, or their gasoline receipt. The composite index and the forecast model are built entirely on publicly reported behavioral data, calibrated against historical election outcomes.

Composite Index (descriptive layer)

The state composite mood score for each state is built from 13 behavioral dimensions normalized cross-sectionally against the other fifty states. The score is descriptive: it tells you the current mood reading, not a prediction. The "National Weather Service for civic emotions" voice belongs to this layer.

The dimensions

DimensionWhat it measuresRepresentative source
MobilityVehicle miles, transit ridership, household movementFHWA TVT, DOL
SecurityFear, threat preparationFBI UCR, FBI NICS
EconomyUnemployment, gas prices, initial claimsBLS LAUS, EIA, DOL
SpendingRetail and household economic commitmentBLS CES, Census ACS
CivicTrustVoter registration, civic participationCensus CPS Voting Supplement, MIT EL turnout
DomesticStabilityHousehold formation, migration persistenceIRS SOI migration, Census ACS
IsolationWithdrawal, alienationCDC mortality (suicide), Census ACS
RiskSpeculation, bet-on-future behaviorMultiple (composite)
EscapeStress and fatigue retreatCDC overdose, Google Trends
InformationSearch interest, civic-anxiety queriesGoogle Trends
Information_candidatesCandidate-quality signal from polling/coverageVoteHub aggregates
Pulse (reserved)Dimension reserved for high-cadence stress signals(currently empty, see caveats)

Normalization (cross-sectional z-score)

Each indicator reading is normalized against the cross-section of the other fifty states, not against its own time series. This is a deliberate switch from the earlier v1.0 24-month rolling z-score because:

z_state_i = (x_state_i - mean(x_all_states)) / sd(x_all_states)

For slow-cadence dimensions (CivicTrust, DomesticStability, Isolation, Risk, Escape) we use latest-wins within a 60-day window rather than averaging, so a stale reading does not dilute a fresh one.

Forecast Model (experimental layer)

The race-level forecast is L2-regularized logistic regression mapping a 15-feature state vector to P(Democrat wins). It is labeled experimental everywhere it appears and always carries its current Brier score on a held-out test split. The forecast layer is the only place predictive language is permitted.

The 15 features

#FeatureWhat it carries
1state_leanContinuous partisan baseline from average of 2020 and 2024 presidential margin (D-R), scaled to [-1, +1]
2Mobility (z)Cross-sectional z of state Mobility composite
3Security (z)Cross-sectional z of Security composite
4Economy (z)Cross-sectional z of Economy composite
5Spending (z)Cross-sectional z of Spending composite
6CivicTrust (z)Cross-sectional z of CivicTrust composite
7DomesticStability (z)Cross-sectional z of DomesticStability composite
8Isolation (z)Cross-sectional z of Isolation composite
9Risk (z)Cross-sectional z of Risk composite
10Escape (z)Cross-sectional z of Escape composite
11Information (z)Search and engagement signal
12Information_candidates (z)Candidate-quality / polling-aggregate residual
13incumbent_party_dIndicator: +1 if D incumbent on the ballot, -1 if R, 0 if open or independent
14Economy_x_incumbentInteraction: Economy * incumbent_party_d (penalizes incumbent of party in power when economy is bad)
15personal_vote_spreadD candidate's prior-cycle margin minus prior-cycle presidential margin, for incumbents

Display dimensions vs model features

All 13 behavioral dimensions are computed daily and surfaced on the dashboard, state detail panels, and the public API. A strict subset is fed to the calibrated logistic regression that produces P(Dem) per race. Two dimensions are intentionally display only:

The model's behavioral feature vector consists of state_lean, ten behavioral dimensions (Mobility, Security, Economy, Spending, CivicTrust, DomesticStability, Isolation, Risk, Escape, Information_candidates), incumbent_party_d, an Economy x incumbent interaction, personal_vote_spread, and a challenger two-party fundraising-share term (with a senate-money-present flag). On top of that block the live model is two-speed: it adds a deep-estimated national midterm thermostat term, then a selective Platt recalibration that holds a prediction unsharpened when the structural and mood signals disagree. Adding Information or Pulse later requires both a backfill and a fresh calibrated model_version.

Calibration

Coefficients are fit by gradient descent with per-feature L2 regularization. The live serving weights are fit on the 2022 and 2024 senate and governor races. The wider corpus of race observations across cycles 2014, 2016, 2018, 2020, 2022, and 2024 is the backtest and Brier-reporting set: every cycle is scored out-of-sample to track accuracy over time.

How the headline Brier is computed: it is not a single 2024 holdout. The reported number is a pooled out-of-sample score under a leave-one-cycle-out (prior-window) policy: each scored cycle is predicted by an identically specified model that did not train on that cycle, pooled across the 2014 to 2024 backtest and four pre-election cutoffs. Per-cycle Brier across 2014-2024 is the backtest record. The live model lr-2026-06-10-chal-recal-twospeed reports a pooled out-of-sample Brier of 0.119.

Brier history

VersionDateTest BrierWhat changed
v0 (baseline)2026-05-260.247Coin-flip baseline is 0.250. v0 used Economy + state_lean only.
v3 / v42026-05-290.155Added Mobility, Security, Information dimensions.
v52026-05-290.181Added candidate fit feature (broke calibration; rolled back).
v8 / v92026-05-300.137Fixed Information_candidates clip on uncontested seats.
v102026-05-310.135Added personal_vote_spread (incumbent personal-vote feature).
v11c2026-06-010.114 (retired)Apparent improvement was a broken-data ceiling. Inverse-signal CivicTrust registration_rate formula meant the model trained on noise that happened to correlate with outcomes.
v11d2026-06-010.135CivicTrust formula corrected (voters presumed registered per CPS skip pattern); turnout source switched from CPS delta to MIT EL absolute; state_lean made continuous from presidential margins; backtest corpus extended back to 2014. The 2 pp regression from v11c is the inverse-signal artifact going away.
A-complete (historical)2026-06-040.137Open-seat encoding (retiring=true treated as incumbent_party_d=0.5 and Economy_x_incumbent=0) applied symmetrically at training and inference, with the full state_incumbents backfill (49 confirmed retirements 2014-2026). Race universe expanded from 54 to 59 with the four missing 2026 governor races (AR, CT, HI, ID) and IL senate 2026 added. NC senate moved from 28.1% to 32.5% (Tillis retiring, no longer encoded as defended R incumbency). The +0.002 Brier vs v11d is a methodology cost the 2024 split could not recover; the open-seat encoding is correct for the six 2026 retirements the prior model mis-encoded. Superseded by the two-speed model below.
two-speed (current)2026-06-110.119Current serving model. Adds a challenger two-party fundraising-share feature and a deep-estimated national midterm thermostat term to the behavioral block, then a selective Platt recalibration that holds a prediction unsharpened when the structural and mood signals disagree. The 0.119 is a pooled leave-one-cycle-out out-of-sample Brier across the 2014-2024 backtest and four pre-election cutoffs (not a single 2024 holdout); the served weights are fit on 2022 and 2024.

This table is the historical version ladder. The Test Brier column is each version's reported score at the time it shipped; the current serving model is the two-speed row, whose 0.119 is a pooled leave-one-cycle-out out-of-sample number (see Calibration above), not a single-split test.

For each prior version, the trained coefficients remain queryable via API; /changelog lists the responsible commit.

Honest Caveats

Forecasting Accuracy (Brier Backtest)

Brier Score: 0.119
PUBLISHABLE
EXPERIMENTAL v1.0
on 2024 held-out races, never seen during training.

The Brier score measures forecast calibration. A perfect predictor scores 0. A random coin flip scores 0.25. Lower is better. Cited Brier values throughout this site refer to the 2024 held-out test score from model lr-2026-06-10-chal-recal-twospeed, trained 2026-06-11.

Training and Test Split

Trained on 2022 + 2024 Senate and Governor races (n=464 race-cutoff cells across four pre-election cutoffs). Held out 2026 (n=236). For each race we reconstruct the state-level dimension Z-scores at minus-90, minus-60, minus-30, and minus-7 days before the election using only raw readings dated on or before that cutoff. No leakage.

Model

L2-regularized logistic regression over 9 behavioral dimensions, a structural state-lean prior, an incumbent-party indicator (D / R / open), and an Economy x incumbent interaction term. The prediction is the probability the Democratic candidate wins.

The interaction feature was added in v4 to capture the textbook 'incumbent reward / blame' dynamic the prior model could not see (state_lean is a static structural prior, not who currently holds the seat). The positive coefficient on Economy x incumbent means a stronger economy boosts the incumbent's party, and a weak economy hurts them, independent of which party that is.

P(Dem) = sigmoid(intercept + sum_j w_j * x_j)

Learned Coefficients

FeatureWeightWhat the sign says
state_lean+0.619Dem-leaning states predict Dem wins
Economy-0.383Stronger economy favors Republicans (direct effect, after incumbent interaction)
CivicTrust+0.353Higher civic participation favors Dems
DomesticStability+0.319Stable households favor Dems
Isolation-0.134Isolated populations favor Republicans
Security-0.116Favors Republicans
Spending-0.062Higher political spending favors Republicans
Mobility-0.003Higher mobility favors Republicans

Brier by Cycle

CycleBriern cells
2014train0.117288
2016train0.116184
2018train0.167284
2020train0.078184
2022train0.110280
2024train0.105184

Brier by Office

OfficeBriern cells
governor0.141568
senate0.104836
v10 calibrates 11 dim features: Mobility, Security, Economy, Spending, CivicTrust, DomesticStability, Isolation, Risk, Escape, Information (six fixed political-engagement terms), and Information_candidates (per-active-roster aggregate). The two Information signals were backfilled separately for 2018-2024 via Google Trends interestByRegion, then trained as independent features so the model learns each weight independently. Information_candidates z-scores are capped symmetrically at +/-1.5 at both training and inference time, after v9's 2018 OOS regression diagnosis showed extreme candidate-fame density in FL 2018 (z=+2.43) was driving wrong-direction P(Dem) shifts. The cap recovers half of the 2018 Brier loss while preserving the 2024 holdout improvement. Pulse and state-level Money remain live in current scoring but not in the backtest, pending historical backfill of their underlying sources. The model also uses incumbent_party_d and Economy x incumbent as derived features keyed on a hand-curated state_incumbents table (2018-2026 Senate and Governor).

Last calibrated: 2026-06-11. Full methodology in docs/brier_backtest_v1.md.

National Mood Index

The VoteROI National Mood Index aggregates the 50 state composite scores (plus DC) into a single number on a -50 R / +50 D scale, where 0 is a dead tie. The headline figure shown on /forecast is the population-weighted reading; an electoral-vote-weighted lens is published as a secondary view.

WeightingRoleWeight basisWhat it captures
Population-weightedHeadline2020 Census apportionmentWhere Americans live. The default "how does the country feel" reading.
EV-weightedSecondary lens2024 Electoral College allocationWhere presidential elections are actually decided. Useful for handicapping 2028, less so for everyday mood.
Competitive-weightedInternal diagnostic2026 competitive race count per stateWhere current-cycle action concentrates. Surfaced in the API but not in the hero readout.
EnsembleInternal diagnosticEqual-weight mean of the threeHeld in the API for backward compatibility with v1.0 consumers.

Each state contributes its composite score minus 50 (the temporal baseline), weighted by the method. The sign for the state is +1 if the state's relevant 2026 incumbent is Democratic, -1 if Republican, 0 if independent or unknown. The per-state pull is then (composite - 50) * sign * weight. A high mood reading in a Democratic-incumbent state reads as Democratic reward (positive on the index); the same high mood reading in a Republican-incumbent state reads as Republican reward (negative). This captures the textbook incumbent-reward and incumbent-blame dynamic at state granularity rather than averaging it out.

The headline convention (population-weighted) reflects everyday civic mood. The electoral-vote lens is reported alongside because the same mood translates differently into a presidential outcome depending on which states feel it most. When the two diverge, that gap is itself information.

vs. Kalshi KPOW

Both VoteROI National Mood Index and the Kalshi American Power Index (KPOW) aim to be a single-number readout of where US political power sits. They use different signals and answer different questions:

VoteROI National Mood IndexKalshi KPOW
InputBehavioral data (FEC, BLS, Census, CDC, FHWA, etc.)Prediction-market prices (Kalshi)
RefreshDaily, after composites recomputeReal-time, tick by tick
ReadsState-level fundamentals (the "why")Market consensus (the "what")
Scale-50R / +50D, signed by federal incumbent-50R / +50D, market consensus mapping
StrengthCaptures structural shifts before markets price them; works without an active liquid marketCaptures news shocks in real time; price discovery in liquid contracts
WeaknessMood-to-partisan translation needs an incumbent-sign convention; lagged by composite cadenceReflexive (reads its own market); requires liquid contracts to exist

The two indices are complementary, not competing. KPOW tells you where the market thinks power is. VoteROI tells you where the behavioral fundamentals say it ought to be heading. When they disagree, that gap is itself information.

What We Are Not

Model Versioning and Audit

Every composite score, forecast, and fit calculation carries a model_version field. The current version is the two-speed model (model_version lr-2026-06-10-chal-recal-twospeed), calibrated June 2026. Methodology changes are documented in /changelog and any change to a coefficient or feature definition is logged before going live. Prior versions remain queryable so independent reviewers can reproduce older calls.

Methodology version: two-speed (lr-2026-06-10-chal-recal-twospeed). Questions: press@voteroi.com.