Every campaign data vendor will sell you a turnout score: a tidy number, 0 to 100, that says how likely each voter is to cast a ballot. Far fewer will tell you whether that number is any good — and most of the time, it isn’t.
Here’s the trap. A lot of state vote-history files aren’t a complete record of every election; they’re a participation ledger — one row for each election a voter actually turned out for, and nothing at all for the ones they skipped. New Jersey’s statewide file works exactly this way. Score turnout by dividing the elections a voter shows up for by the rows the file happens to carry, and everyone who has ever voted once looks like a 100% turnout voter. Do that and your “model” sorts almost the entire file into the top bucket — which is worse than useless when the whole point was to decide who actually needs a knock.
Romulus is built to not fall into that hole. Here’s how it models turnout, and — the part that matters — how it proves the score works before you act on it.
Measured against the calendar, not the file
Every turnout rate in Romulus divides ballots cast by the elections that actually happened in that voter’s jurisdiction since they registered — never by the rows the state file happens to list. A missing row isn’t missing data; it’s a skipped election, and it counts as one. That single decision is the difference between a score that separates reliable voters from occasional ones and a score that calls everyone reliable.
Out of the box, before you tune anything, Romulus scores your whole file with sensible defaults — recency, frequency, the overall shape of a voter’s history — so you have a working turnout score on day one. It also records how many elections each score rests on, because a 0.5 built from two elections is a very different thing from a 0.5 built from twenty-two, and it’s worth knowing which one you’re looking at.
A score that grades itself
Defaults are a starting point. When you’re ready for a real model, Romulus fits one to your electorate — and then does the thing almost no vendor does out loud: it grades itself.
It holds out one real past election, hides it, scores every eligible voter using only the elections that came before it, and then checks the prediction against what actually happened — who really turned out. You get the numbers a data scientist would ask for: how cleanly the score separates voters, how well its probabilities line up with reality, and how much lift you get in the top slice of the file. The fitted model is scored on voters it never trained on, side by side with the old default weights on those same voters, so you can see whether the fit is a real improvement or just a fancier way to be wrong.
Nothing gets promoted automatically. You read the comparison and decide. Publish a model and every turnout score becomes a calibrated probability — which is what finally makes the score histogram, and the “likely / persuadable / unlikely” cutoffs, mean what they say.
No peeking at the future
A model that grades itself is only honest if it can’t cheat, so Romulus enforces the boring, load-bearing rules that keep a backtest from lying to you. Features come only from elections before the one being predicted. Voters who registered after the held-out election are dropped — you can’t take credit for predicting a vote from someone who wasn’t on the rolls yet. And a voter’s current support ID is left out entirely, because you learned that after the election you’re trying to predict; leak it in and the score looks brilliant in testing, then falls apart in the field.
One more honesty rule: primaries and generals turn out differently. A model graded on a general holds its ordering against a primary electorate, but its raw numbers read high — so Romulus lets you grade against the election type you’re actually targeting, and the probabilities stay true.
From a hunch to a model
None of this requires a data team. The Scores library reads every number you carry on a voter — vendor columns, CSVs you import, models you train in-house — as the same 0–100 scale, so a cutoff, a crosstab, or a sort behaves identically across all of them. And Rosie, the campaign assistant, will draft a model straight from plain English: describe the voters you think turn out, and she lays it out as a set of toggleable assumptions, each with a confidence you can dial and a training pool that recounts live as you flip them on and off. Train it, and the report shows the weight you assumed next to the weight the data learned — so you find out which of your hunches actually held up.
Once a model is live, Romulus keeps it current on its own, re-scoring nightly as new vote history and contacts come in, so the number you’re targeting on is never quietly out of date.
A score is only worth as much as the evidence that it predicts anything. That’s the whole idea behind modeling in Romulus: not a black box that hands you a number, but a score that shows its work. The full detail lives in the docs under Scores & models; if you’d like to see it graded against your own district, request a demo and we’ll fit a model on the call.