Skip to content

← ~/experiments

systemctl status homepesthealth.service

HomePestHealth

status stable
urlhttps://homepesthealth.com ↗
tags

Bedbugs have no national ground truth, so this compiles Census, HUD, PRISM, ACS, USDA and VA data into a pest-risk estimate for every US ZIP code. Where a number is modelled rather than measured, the site says so instead of quietly rounding it into fact.

Every so often you go looking for a dataset that obviously has to exist and find out that it doesn’t. Rodents were easy. The Census Bureau publishes experimental county-level estimates, so there is real survey data underneath. Termites were easier still. Mortgage lenders need an inspection standard and the VA maintains one. Bedbugs had nothing, and the gap turned out to be much smaller than a missing agency. The American Housing Survey asks households whether they have seen cockroaches and whether they have seen rodents, and then it stops asking. No question means no survey, no survey means no national estimate, and what is left is proprietary pest-company rankings, a handful of municipal complaint systems, and crowdsourced registries of the quality you would expect.

Proxies instead of observations

So the fourth grade is modelled. The research that does exist keeps landing on the same strongest predictor, multi-unit rental housing. The American Community Survey already publishes the housing-type breakdown per area, and the pipeline had that file on disk for other reasons. Each ZIP’s share of multi-unit rentals gets sorted into three tiers by national percentile, top quarter high and bottom quarter low with the middle fifty percent between them. That tier is the baseline score the dashboard grades against.

It is a socioeconomic model standing in for an observation, and the model has never seen a bedbug.

Grading your own data

This is the part I think is actually worth showing. The project has a rule that predates the bedbug problem. Every pest number that renders has to carry a source object with a name, a vintage year, a geographic resolution, and a quality of high, medium or low. Easy rule to agree with while all your data is real.

Applied honestly it produced an unflattering set of labels. The bedbug source is called “ACS Socioeconomic Proxy Model” and it says so on the page, next to the grade, where the reader sees the word proxy without having to go looking for it, and the quality field rides along in the API response at medium. Three of the four pests come out medium once you are being strict, since the rodent estimates are modelled too and the cockroach score leans on climate normals. Only termites grade high, and only because a federal pamphlet stands behind them. A grading scheme applied to your own work is considerably less generous than one designed for somebody else’s.

The alternative was leaving the card reading “Coming Soon” indefinitely, which is honest in the same way that saying nothing is honest.

The unglamorous half

ZIP codes are postal delivery routes rather than shapes on a map, so nothing lines up with the census geography the data arrives in. Every value is a weighted average across the overlapping areas, by residential ratio, from a HUD crosswalk. Where the survey has no coverage for an area the score falls back to the state average, and the territories get the middle baseline. The output is roughly forty-one thousand per-ZIP JSON files pushed to object storage, read by a small Worker API, and rendered by a Nuxt frontend that is the least interesting thing in the repository.

Forty-six numbered feature specs sit alongside it. The one I would point at is the document arguing that a proxy is allowed on the page as long as it is introduced as one.

Producing a bedbug number is an afternoon of percentiles. Deciding how much of a number you are allowed to claim took the rest of the project.