Skip to content

ConorMcNamara/GeoCausality

Repository files navigation

GeoCausality

Lint Python 3.13+ License: MIT codecov Ruff

A Python library for measuring the causal impact of geo-level A/B experiments. GeoCausality provides a consistent, chainable API across seven estimators — from simple difference-in-differences to augmented synthetic control.


Table of Contents


Installation

pip install geocausality

Requirements: Python ≥ 3.13


Available Methods

Class Module Description
GeoX geox Time-based regression matched markets (TBR)
DiffinDiff diff_in_diff Difference-in-differences via OLS
FixedEffects fixed_effects Two-way fixed effects (entity + time) via PanelOLS
SyntheticControl synthetic_control Classic synthetic control (constrained weights)
SyntheticControlV synthetic_control Synthetic control with learned V matrix
PenalizedSyntheticControl penalized_synthetic_control Synthetic control with pairwise penalty (Abadie & L'Hour)
RobustSyntheticControl robust_synthetic_control SVD-denoised synthetic control (Amjad, Shah & Shen)
AugmentedSyntheticControl augmented_synthetic_control Augmented SC with ridge bias correction (Ben-Michael et al.)

Quick Start

All estimators share the same three-step chainable interface: pre_process()generate()summarize().

GeoX (Time-Based Regression)

import pandas as pd
from GeoCausality import geox

df = pd.read_csv("geo_data.csv", parse_dates=["date"])

model = geox.GeoX(
    df,
    geo_variable="geo",
    treatment_variable="is_treatment",
    date_variable="date",
    pre_period="2022-06-30",
    post_period="2022-07-01",
    y_variable="orders",
    spend=500_000,
)
model.pre_process().generate().summarize(lift="incremental")

Difference-in-Differences

from GeoCausality import diff_in_diff

model = diff_in_diff.DiffinDiff(
    df,
    geo_variable="geo",
    date_variable="date",
    pre_period="2022-06-30",
    post_period="2022-07-01",
    y_variable="orders",
)
model.pre_process().generate().summarize(lift="relative")

Synthetic Control

from GeoCausality import synthetic_control

model = synthetic_control.SyntheticControl(
    df,
    test_geos=["geo_A", "geo_B"],
    date_variable="date",
    pre_period="2022-06-30",
    post_period="2022-07-01",
    y_variable="orders",
)
model.pre_process().generate().summarize(lift="roas")

summarize lift options

Value Description
"incremental" Total absolute lift over the post-period
"absolute" Per-period absolute lift
"relative" Percentage lift vs. counterfactual
"revenue" Incremental revenue (requires msrp)
"roas" Return on ad spend (requires spend)
"cost-per" Cost per incremental unit (requires spend)

API Overview

Every estimator accepts the same core constructor arguments:

Parameter Type Default Description
data pd.DataFrame | pl.DataFrame Geo-level time-series data
geo_variable str "geo" Column identifying each geo unit
test_geos list[str] | None None Geos assigned to treatment
control_geos list[str] | None None Geos withheld from treatment
treatment_variable str | None "is_treatment" Binary treatment indicator column (used when geo lists are not provided)
date_variable str "date" Date column
pre_period str "2021-01-01" Last date of the pre-treatment window
post_period str "2021-01-02" First date of the post-treatment window
y_variable str "y" Outcome metric column
alpha float 0.1 Significance level for confidence intervals
msrp float 0.0 Average sale price (for revenue lift)
spend float 0.0 Campaign spend (for ROAS / cost-per)

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines on setting up the development environment, running tests, and submitting pull requests.


References

  • Au, Tim. "A Time-Based Regression Matched Markets Approach for Designing Geo Experiments." (2018). PDF
  • Kerman, Jouni, Peng Wang, and Jon Vaver. "Estimating ad effectiveness using geo experiments in a time-based regression framework." Google, 2017. PDF
  • Brodersen, Kay H., et al. "Inferring causal impact using Bayesian structural time-series models." Annals of Applied Statistics 9.1 (2015): 247–274. Link
  • Abadie, Alberto, and Jérémy L'Hour. "A penalized synthetic control estimator for disaggregated data." Journal of the American Statistical Association (2021). Link
  • Ben-Michael, Eli, Avi Feller, and Jesse Rothstein. "The augmented synthetic control method." Journal of the American Statistical Association (2021). Link
  • Amjad, Mohammad, Devavrat Shah, and Dennis Shen. "Robust synthetic control." Journal of Machine Learning Research 19.1 (2018): 802–852. Link
  • GeoLift (Meta). Documentation

About

A package that allows users to understand the causal impact of their geo-experiments.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors