Skip to main content
Open llms.txtCopy tools

Geo-Causal Experiment Models

CartoBoost geo-causal tools estimate intervention effects on geographic panels. They are for questions such as marketing lift, policy rollout impact, store openings, and network changes. They do not forecast future demand and should not be reported as forecast accuracy evidence.

Models

ModelUse
SyntheticDIDEstimatorEstimate post-intervention treatment effect from treated geos and weighted controls.
GeoLiftEstimatorAlias for GeoLift-style experiment design helpers.
GeoExperimentDesignerChoose candidate test geos, check balance, estimate detectable lift, and run placebos.
SpatialPlaceboTesterRun deterministic placebo assignments and spillover diagnostics.
InvariantRiskEncoderRepresentation supplement for held-out-region diagnostics; not a causal estimator.

All fitting and causal scoring behavior is implemented in Rust under crates/cartoboost-geo-causal. Python wraps the native routines and only adds data coercion, .plot(), and ergonomics.

Representation supplements such as InvariantRiskEncoder, DomainAdversarialGeoEncoder, CounterfactualRepresentationNet, and TreatmentEffectRepresentationHead can reduce held-out-region prediction error in domain-shift diagnostics, but they do not identify causal effects by themselves. Use them only alongside an identified design such as SyntheticDIDEstimator or GeoExperimentDesigner, and keep the estimator's assumptions, placebo checks, and spillover diagnostics in the causal report.

Panel Contract

GeoCausalPanel requires:

FieldMeaning
unit_idStable geographic unit such as pickup zone, store catchment, district, or network node.
timeComparable ordered timestamp label. ISO strings sort correctly and are recommended.
outcomeNumeric outcome such as trips, revenue, visits, policy incidents, or throughput.
treatmentBoolean flag for treated unit-period rows.
covariatesOptional numeric controls retained in the panel contract.
latitude, longitudeOptional coordinates for distance diagnostics.
region_idOptional stable region identifier when coordinates are not the primary geography.
spatial_weightsOptional weighted adjacency used for spillover diagnostics.

Missing required inputs fail clearly. CartoBoost does not synthesize controls, drop invalid geos, or replace failed experiment designs with weaker defaults.

Synthetic DID

SyntheticDIDEstimator splits rows into pre and post periods using intervention_time, partitions units into treated and controls, builds control unit weights from pre-period outcome balance, assigns deterministic pre-period time weights, estimates the post-period treatment effect, and can run placebo assignments.

from cartoboost.geo_causal import GeoCausalPanel, SyntheticDIDEstimator

panel = GeoCausalPanel(
rows,
unit_col="pickup_zone",
time_col="date",
outcome_col="trips",
treatment_col="campaign_live",
covariate_cols=["avg_trip_distance", "pickup_hour_share"],
latitude_col="lat",
longitude_col="lon",
spatial_weights=[("zone_101", "zone_102", 1.0)],
)

estimator = SyntheticDIDEstimator(intervention_time="2026-03-08", seed=11).fit(panel)
effect = estimator.estimate_effect()
placebos = estimator.placebo_test(n=100)
summary = estimator.summary()

Every summary includes assumptions. Interpret the effect only when those assumptions are defensible for the study:

  • No unmeasured post-intervention shocks differentially hit treated geos.
  • Control geos represent the untreated counterfactual.
  • Spillovers from treated to control geos are absent or small.
  • The result is a causal estimate, not a forecast.

GeoLift-Style Design

Use GeoExperimentDesigner or GeoLiftEstimator before launching a geographic test. The designer ranks candidate test geos by pre-period balance, estimates detectable lift from placebo dispersion, and reports spillover warnings.

from cartoboost.geo_causal import GeoExperimentDesigner

design = (
GeoExperimentDesigner(intervention_time="2026-03-08", seed=11)
.fit(panel)
.summary(candidate_count=2, placebo_n=200)
)

Use this for marketing lift when selecting treated media markets or taxi pickup zones, policy rollout when choosing districts, store openings when choosing candidate catchments, and network changes when selecting treated corridors or nodes. The design helper is not proof that the intervention will work; it only checks whether the historical panel can support a measurable experiment under the stated assumptions.

Spillover Diagnostics

SpatialPlaceboTester.summary() reports:

DiagnosticMeaning
adjacent_treated_control_pairsTreated/control pairs connected by spatial weights.
min_treated_control_distanceClosest treated/control distance when coordinates are available.
mean_treated_control_distanceAverage treated/control distance.
treated_weight_exposureTotal weighted adjacency exposure involving treated units.
control_weight_exposureTotal weighted adjacency exposure among controls.
warningsExplicit spillover warnings that should appear in reports.

Adjacent treated/control units are a warning, not an automatic correction. Move geos, buffer controls, redefine spatial weights, or treat the estimate as potentially contaminated.

WASM And Model Lab

The browser/WASM surface exposes runGeoCausalExperiment(request). The request matches the native panel contract and returns a JSON-compatible summary with effect, weights, placebos, assumptions, and warnings.

const response = wasm.runGeoCausalExperiment({
interventionTime: "2026-03-08",
seed: 11,
placeboN: 100,
rows,
spatialWeights: [
{fromUnit: "pickup_zone_101", toUnit: "pickup_zone_102", weight: 1.0},
],
});

See examples/model_lab_geo_causal_request.json for a complete model-lab request payload and examples/06_geo_causal_lift.py for the Python workflow.

Reporting

Reports should include the exact intervention time, treated geos, control weights, placebo distribution, spillover warnings, and assumptions. Do not combine causal estimates with forecast benchmark tables unless the table clearly separates intervention effects from prediction metrics.