The synthetic control method: building a better comparison group

When no single region trends like the one you treated, build one out of the others. Here's how the weights are chosen, what can go wrong, and a widget that fits them live.

Mike Taylor By Mike Taylor · Updated · 8 min read

The synthetic control method estimates the effect of an intervention on a single treated unit (a region, a country, a store) by building a weighted blend of untreated units that matches the treated unit’s history before the intervention, then reading the effect as the gap between the real unit and its synthetic twin afterwards. The weights are non-negative and add up to one, so the synthetic control is literally “34 percent of this region, 28 percent of that one and 38 percent of a third”, which makes it unusually easy to explain to a stakeholder.

Marketers mostly meet synthetic control through geo testing, because it’s the engine inside Meta’s GeoLift package, and through Google’s CausalImpact, which solves a closely related problem with a Bayesian time-series model. It’s the natural step up from difference in differences when your treated region doesn’t trend like any single comparison region, which in my experience is most of the time for the regions people actually want to test in. The widget below fits the weights in your browser, so you can watch the method work before trusting it with a real test.

Where the synthetic control method came from

The method was introduced by Alberto Abadie and Javier Gardeazabal in 2003, to estimate the economic cost of terrorism in the Basque Country by comparing it with a weighted combination of other Spanish regions. Abadie, Alexis Diamond and Jens Hainmueller then formalised it in a 2010 paper in the Journal of the American Statistical Association, estimating the effect of California’s 1988 tobacco control program (Proposition 99) on cigarette sales against a synthetic California built from other states. That paper also introduced the placebo-based inference that most practitioners still use, and Abadie’s 2021 review in the Journal of Economic Literature is the best practical guide to when the method is and isn’t appropriate.

The problem those papers solved is the same one a marketer faces with a regional test. You have one treated unit (or a handful), a long pre-period, and a pool of untreated units, none of which is a perfect match on its own. Difference in differences would average the pool equally and hope the trends line up; synthetic control lets the data choose which units to lean on.

How the weights are chosen

Write the treated unit’s outcome in pre-period week tt as yty_t and donor jj‘s outcome as xjtx_{jt}. The basic synthetic control picks weights wjw_j to make the weighted donors track the treated unit as closely as possible over the T0T_0 pre-period weeks, subject to two constraints:

min⁡w∑t=1T0(yt−∑j=1Jwjxjt)2subject towj≥0,  ∑j=1Jwj=1\min_{w} \sum_{t=1}^{T_0} \Big(y_t - \sum_{j=1}^{J} w_j x_{jt}\Big)^2 \quad \text{subject to} \quad w_j \ge 0,\; \sum_{j=1}^{J} w_j = 1

The constraints are what make it a synthetic control rather than just a regression. Non-negative weights that sum to one mean the synthetic unit is an interpolation of real units, never an extrapolation, so you can’t get a good fit by adding three times one region and subtracting twice another. They also tend to produce sparse answers, with most donors getting zero weight, which is easier to sanity check. The full method also matches on covariates and pre-period summaries with a second layer of importance weights; the version here fits on the outcome series alone, which is also how GeoLift works unless you add covariates. After launch, the synthetic line is a genuine out-of-sample forecast of what the treated unit would have done, because nothing after the pre-period went into choosing the weights.

Interactive
Build a synthetic control from eight donor regions

The treated region gets a campaign from week 41. The weights are fit live on weeks 1-40 only, so the synthetic line after launch is a genuine out-of-sample counterfactual. Re-roll to get a new world.

Pre-period fit (MAPE)
-
Estimated lift, synthetic control
-
True lift
-
Equal-weight DiD estimate
-
Donor weights (non-negative, sum to 1)
Placebo test: treated gap (green) vs each donor treated as fake (grey)

Seeded synthetic data: each region is a level times a mix of shared trend, seasonality and a slow cycle, plus noise. The treated region is built from three donors, so a good fit exists; real data is rarely that kind. Weights fit by projected gradient descent on pre-period squared error, with no covariates. The placebo test refits each donor from the other seven and ranks post/pre RMSPE ratios.

The widget fits the weights by accelerated projected gradient descent (take a step downhill on the squared error, then project back onto the set of non-negative weights that sum to one), which is a few lines of code and converges in milliseconds for eight donors. Donor regions tend to move together, which makes the problem badly conditioned, so whatever solver you use, check that the pre-period fit is as good as it should be before you read the result. Try turning the noise up: the pre-period fit degrades, the weights spread across more donors, and the post-period estimate wanders further from the truth. Then add the equal-weight average, which is the counterfactual a simple DiD would use. Because the donors have different trends, the equal-weight version usually drifts away from the treated region after launch and gets the lift wrong, which is the whole case for choosing weights.

py
Synthetic control script (Python)Fits the weights with the same accelerated projected gradient as the widget, reports pre-period MAPE and post-period lift, compares an equal-weight DiD and runs the placebo test. The widget's CSV download works as its input.
Download

Is the lift real? Placebo tests and pre-period fit

With one treated unit you can’t compute a standard error in the usual way, so Abadie and colleagues proposed placebo tests instead. Pretend each donor was the treated unit, build a synthetic control for it from the remaining donors, and look at the gap it shows after the launch date (when nothing actually happened to it). If the real treated unit’s gap is more extreme than nearly all the placebos, the effect is unlikely to be the kind of noise you’d see anyway. Comparing the ratio of post-period to pre-period error (RMSPE, root mean squared prediction error) rather than the raw gap stops a poorly fitted placebo from looking dramatic. The widget’s gray lines are those placebos.

This gives you a permutation p-value of the treated unit’s rank divided by the number of units, which has an important consequence for test design: with eight donors, the best possible p-value is one in nine, about 0.11. If your organization insists on 0.05, you need at least 19 donors before the method can even reach that threshold, which is one reason GeoLift’s guidance asks for 20 or more geographic units. The other habit I’d insist on is looking at the pre-period fit before looking at the result. If the synthetic line can’t track the treated unit before launch (a MAPE several times larger than the lift you’re hoping to detect is a bad sign), the post-period gap tells you nothing, and the honest answer is that this region can’t be tested this way.

Augmented synthetic control, and how GeoLift uses it

The weakness of the basic method is that a good pre-period fit isn’t always possible, especially when the treated unit is at the edge of the donor pool (your biggest region, or your fastest-growing one), since a weighted average can’t produce a value bigger than every input. Eli Ben-Michael, Avi Feller and Jesse Rothstein’s augmented synthetic control method (published in JASA in 2021) addresses this by fitting an outcome model, typically ridge regression, to estimate how much bias the imperfect fit leaves, then subtracting it from the synthetic control estimate. The trade-off is that the augmented version can put small negative weights on some donors, so it gives up a little of the “pure interpolation” interpretability in exchange for less bias.

GeoLift’s documentation describes its model as the augmented synthetic control method, and the package installs Ben-Michael’s augsynth R package as a dependency. In practice that means GeoLift is doing what the widget does, with the ridge correction on top, its own inference for confidence intervals, and a market selection routine that runs the method many times on historical data to find test markets that the rest of the pool can reproduce well. If you understand the widget, you understand what GeoLift is checking when it ranks market combinations, and you’re in a much better position to question its output.

CausalImpact: the Bayesian time-series cousin

CausalImpact comes from Kay Brodersen and colleagues at Google, published in the Annals of Applied Statistics in 2015, and it’s the other name you’ll see in this space. Instead of a convex combination of donors, it fits a Bayesian structural time-series model to the treated series, with a local level (and optionally trend and seasonal) component plus the control series as regressors, and forecasts the post-period from that model. The output is a counterfactual with a posterior interval for the cumulative effect, which marketers find easy to read. The original is an R package, and Google also publishes a Python version built on TensorFlow Probability (tfp-causalimpact on pip).

# pip install tfp-causalimpact
import pandas as pd
import causalimpact

df = pd.read_csv("synthetic-control-example.csv")        # from the widget above
data = df[["treated", "north", "south", "east", "west", "coast", "valley", "metro", "lakes"]]
# The first column is the outcome; the rest are controls. Rows 0-39 are the pre-period.
impact = causalimpact.fit_causalimpact(data=data, pre_period=[0, 39], post_period=[40, 51])
print(causalimpact.summary(impact, output_format="summary"))

The two approaches make different bets. Synthetic control assumes the treated unit is a stable mixture of the donors and gets its credibility from the transparent weights and the placebo test; CausalImpact assumes the regression relationship between the treated series and the controls stays stable, and its intervals depend on the model being right. CausalImpact is also often used with a single control series, or none at all, in which case it’s really a forecast of the treated series from its own history and the result is only as good as that forecast. Both share the same foundation as every incrementality method: the comparison units must not have been affected by the campaign. I’d run both on any important test and treat a disagreement between them as a finding, not an inconvenience.

When to use synthetic control in marketing

Synthetic control fits best when you have one or a few treated regions, a long pre-period, a decent pool of untreated regions, and an outcome you can measure by region every week or day: a TV burst in one region, a new store format in one city, a national launch in one country with others as donors, or a geo holdout of a paid channel. It’s a weaker fit when the treated unit is unlike everything else (your capital city, say), when donors are contaminated by national media or spillover, or when the pre-period contains a structural break like a pricing change. If you can randomize across many regions, a randomized geo experiment with a simpler estimator is often more powerful and easier to defend; the statistical power page has a calculator for that trade-off.

The result should then go somewhere useful. A clean synthetic control estimate of incremental sales and iROAS is exactly the kind of evidence that should calibrate your marketing mix model, and the incrementality testing guide covers how to plan a program of tests around your biggest budget questions. If you’re new to the underlying ideas, the marketing mix modeling guide and the course’s MMM learning path put geo experiments in the context of the full measurement system, and the older geo models brief covers modeling at the regional level.

Downloads

py
Synthetic control script (Python)Constrained least squares weights (the same solver as the widget), lift estimate, equal-weight DiD comparison and a placebo-in-space test. Runs on a seeded example or your own wide CSV.
Download

Frequently asked questions

What is the synthetic control method?

The synthetic control method estimates the effect of an intervention on one treated unit, such as a region, by building a weighted average of untreated units that matches the treated unit's history before the intervention. The weights are non-negative and sum to one, and the gap between the treated unit and this synthetic version after the intervention is the estimated effect.

What is the difference between synthetic control and difference in differences?

Difference in differences compares the treated unit with an equally weighted comparison group and assumes their trends would have stayed parallel. Synthetic control chooses the weights so the comparison tracks the treated unit closely before the intervention, which relaxes the need for any one comparison group to trend like the treated unit.

What is CausalImpact?

CausalImpact is an open-source package from Google, based on Brodersen and colleagues' 2015 paper in the Annals of Applied Statistics, that predicts what a time series would have done without an intervention using a Bayesian structural time-series model with control series as regressors. It reports the estimated effect with a posterior interval. There is an R package and a Python implementation called tfp-causalimpact.

How does GeoLift use synthetic control?

GeoLift, Meta's open-source geo testing package, estimates lift with the augmented synthetic control method of Ben-Michael, Feller and Rothstein. It builds a synthetic control from untreated markets and then corrects for imperfect pre-period fit with an outcome model such as ridge regression, and it uses the same machinery to run power analyzes for market selection.

How do you test whether a synthetic control result is significant?

The usual approach is a placebo test: pretend each untreated unit was treated, build a synthetic control for it from the others, and compare the size of its post-period gap with the real treated unit's. If the treated unit's gap is more extreme than most placebos, the effect is unlikely to be noise. With few units the smallest achievable p-value is limited, for example one in nine with eight donors.

References

  1. Abadie & Gardeazabal (2003), The Economic Costs of Conflict: A Case Study of the Basque Country American Economic Review 93(1). The first synthetic control.
  2. Abadie, Diamond & Hainmueller (2010), Synthetic Control Methods for Comparative Case Studies JASA 105(490), 493-505. California's Proposition 99 and placebo inference.
  3. Abadie (2021), Using Synthetic Controls: Feasibility, Data Requirements, and Methodological Aspects Journal of Economic Literature 59(2), 391-425. Practical guidance.
  4. Ben-Michael, Feller & Rothstein (2021), The Augmented Synthetic Control Method JASA 116, 1789-1803. Ridge-augmented SCM; augsynth R package.
  5. Brodersen, Gallusser, Koehler, Remy & Scott (2015), Inferring causal impact using Bayesian structural time-series models Annals of Applied Statistics 9(1), 247-274. The CausalImpact method.
  6. google/tfp-causalimpact on GitHub Python + TensorFlow Probability implementation of the R CausalImpact package.
  7. GeoLift walkthrough Describes GeoLift's model as the augmented synthetic control method.
Mike Taylor
Mike Taylor

I've built marketing mix models for Monzo Bank, Booking.com, Time Out, The AA and others, advised Google, Appsflyer and Recast on MMM, and teach marketing mix modeling on LinkedIn Learning. Before that I co-founded a 50-person growth marketing agency. I write the Vexpower MMM course.

Keep reading

Learn MMM by doing itThe Vexpower course walks through thirty lessons on one invented brand, with simulators, Python labs and a decision case you can defend.
See the course