How to Simulate Geo Experiments in Python
Build a mock geo experiment simulator with ramp-up/down periods, measuring weekly lift between treatment and control markets.
Python code
60 linesimport random
import math
from dataclasses import dataclass
@dataclass
class GeoMarket:
name: str
base_demand: float
geo_coefficient: float
def simulate_geo_experiment(markets, weeks=12, control_weeks=6):
"""
Simulates a geo experiment with ramp-up and ramp-down periods.
Returns weekly lift percentages for treatment vs control.
"""
results = []
for week in range(1, weeks + 1):
# Ramp factor: 0% for control weeks, ramps up to 100% then down
ramp = 0.0
if week > control_weeks:
elapsed = week - control_weeks
total_treatment_weeks = weeks - control_weeks
ramp = math.sin(math.pi * (elapsed - 0.5) / total_treatment_weeks) * 0.5 + 0.5
ramp = max(0.0, min(1.0, ramp))
treatment_total = 0.0
control_total = 0.0
for market in markets:
noise = random.gauss(0, 1)
weekly_demand = market.base_demand * (1 + market.geo_coefficient * noise)
if ramp > 0 and market.name.startswith("T"):
weekly_demand *= (1 + 0.15 * ramp) # 15% max lift
if market.name.startswith("C"):
control_total += weekly_demand
else:
treatment_total += weekly_demand
if control_total > 0:
lift = (treatment_total / control_total - 1) * 100
results.append((week, round(lift, 2), round(ramp, 2)))
else:
results.append((week, 0.0, round(ramp, 2)))
return results
def main():
random.seed(42)
markets = [
GeoMarket("C-NY", 1000, 0.2),
GeoMarket("C-CA", 800, 0.15),
GeoMarket("T-TX", 900, 0.18),
GeoMarket("T-FL", 700, 0.12),
]
print("Geo Experiment Mock Markets")
print("Week | Lift % | Ramp %")
for week, lift, ramp in simulate_geo_experiment(markets):
print(f"{week:4d} | {lift:6.2f} | {ramp*100:5.1f}%")
if __name__ == "__main__":
main()
Output
Geo Experiment Mock Markets
Week | Lift % | Ramp %
1 | 0.00 | 0.0%
2 | 0.00 | 0.0%
3 | 0.00 | 0.0%
4 | 0.00 | 0.0%
5 | 0.00 | 0.0%
6 | 0.00 | 0.0%
7 | 15.26 | 19.1%
8 | 14.78 | 50.0%
9 | 15.20 | 80.9%
10 | 14.84 | 100.0%
11 | 15.02 | 80.9%
12 | 15.11 | 50.0%
How it works
This simulator models a geo experiment where treatment markets get ramped gradually to avoid shocking the system. The math.sin function creates a smooth s-curve ramp that peaks at 100% midway through the treatment period. Noise is added via random.gauss to simulate realistic market variance. The lift metric compares aggregated treatment vs control demand, clearly showing when treatment effect kicks in.
Common mistakes
- Forgetting to seed the random generator for reproducible results
- Using linear instead of smooth ramp curves that cause sudden demand jumps
- Not excluding control weeks from ramp calculations
- Hardcoding market treatment status instead of using naming conventions
Variations
- Use exponential decay instead of sine for asymmetric ramp-up/down curves
- Add daily granularity by looping over days within each week
Real-world use cases
- Planning geo holdout tests in paid media before spending large budgets on new markets.
- Validating incremental lift assumptions when rolling out new features region by region.
- Stress-testing marketing budget allocation models across multiple geographic tiers.
Sponsored
More from A/B testing & experimentation
Keep learning
Related tutorials and quizzes for this topic.