Model card — Roof (roof-replacement)
Plain-language explainer. Numbers from model_v3_v221_trim (V22.1 + trim),
EVAL_T0=2025-10-31. Recompute, don't parrot. Full lineage: finding 85,
notes/Roofing/.
What it predicts
For each owner-occupied single-family home, the probability the owner pulls a roof-replacement permit in the next 6 months (T0+1..T0+6). This is the shipped CallZeke outbound list (who to mail). Status: shipped (v22).
- Label
y=1: aROOFINGpermit with actionREPLACEMENT, where the owner was occupying at permit time (client directive). - Horizon: 6 months. Score: 0–100, banded High/Med/Low for the client.
Who it scores (universe)
Single-family homes, individual owners, owner-occupied at T0, in the FL-7 training counties; delivery is Hernando / Pasco / Pinellas (50/25/25). Absentees, companies, PO boxes, and homes with a roof permit in the last 15 years are excluded before mailing.
How well it works
| Metric | Value |
|---|---|
| Base rate (eval) | 1.15% |
| Lift @ 15K | 10.0× |
| AUC-PR | 0.077 |
| Recall @ 15K | 13.6% |
| Features | 169 |
Variables that drive it (top by gain)
| # | Variable | Gain | Plain English |
|---|---|---|---|
| 1 | roof_age_months_est |
32.4% | Estimated age of the current roof — the single biggest driver. Old roof → due for replacement. |
| 2 | roof_cover_code |
8.5% | Roof material (shingle/tile/metal) — material sets the replacement clock. |
| 3 | n_pool_permits_lifetime |
5.5% | Lifetime pool permits — proxy for an owner who invests in the home. |
| 4 | roof_age_months |
3.4% | Roof age from permit history (companion to #1). |
| 5 | fips |
3.3% | County — captures regional roof-replacement regimes. |
| 6 | area_pct_wholeroofs_36m |
3.1% | % of nearby homes that re-roofed in 36 mo — neighborhood wave / storm aftermath. |
| 7 | nearest_storm_name |
2.6% | Which storm hit nearby — hail/wind damage drives reroofs. |
| 8 | property_age_yr |
2.4% | Home age — older home, older systems. |
| 9 | months_since_last_any_non_roof_permit |
2.4% | General permit-activity recency — active improvers. |
| 10 | roof_age_at_purchase_anniv_y12 |
1.9% | Roof hits the ~12-yr carrier-renewal trigger at next policy anniversary (insurance pressure). |
Variable families: roof condition/age (dominant), property physical (age, size), owner-investment behavior (pool/permit history), neighborhood + storm context, insurance-renewal timing. Roof age alone ≈ 40% of total signal.
What does NOT drive it / caveats
- Roof age is overwhelmingly #1 — the model is largely "how old is the roof, adjusted for material, storms, and owner behavior." Sensible but concentrated.
- Three date-diff features (
roof_age_months, listing duration, mortgage age) were under leakage audit; publication-lag shifts applied. - Lift@15K (10×) is over a 1.15% base rate; precision is ~11% at ship size.
Run / artifacts
scripts/roofing/retrain_with_v3.py (defaults target ROOFING). Ship pipeline
scripts/roofing/ship_callzeke_v22.py. Model model_v3_v221_trim.lgb;
finding 85; home notes/Roofing/.