Set custom priors when outcome is not revenue

Meridian defines ROI as incremental outcome divided by spend. When the KPI is not revenue and revenue_per_kpi is not passed to InputData, outcome is not in terms of revenue. This can make it difficult to determine a custom ROI prior.

Consider the following options when setting a custom prior when outcome is not revenue:

Custom total paid media contribution prior

If you have intuition about the total proportion of the KPI that is incremental due to paid media, you can set a common ROI prior on all channels such that the total media contribution specific prior mean and standard deviation by doing the following:

p_mean = 0.5  # prior mean proportion of KPI incremental due to all media
p_sd = 0.15  # prior std dev proportion of KPI incremental to all media
roi_mean = p_mean * kpi / np.sum(cost)
roi_sd = p_sd * kpi / np.sqrt(np.sum(np.power(cost, 2)))
lognormal_sigma = np.sqrt(np.log(roi_sd**2 / roi_mean**2 + 1))
lognormal_mu = np.log(roi_mean * np.exp(-lognormal_sigma**2 / 2))
roi_prior = tfp.distributions.LogNormal(
    lognormal_mu.astype(np.float32),
    lognormal_sigma.astype(np.float32),
)

Where:

  • kpi is the sum of the entire KPI across geos and time.
  • cost is an array of the total cost per channel across geos and time.

In this example, the KPI contribution of all media is centered at 50% with a standard deviation of 15%. You then get an ROI prior that is consistent for all channels, such that the implied prior on the total paid media contribution has a mean at 50% and a standard deviation at 15%. The derived prior, roi_prior, can then be used by setting it in the PriorDistribution container for roi_m or roi_rf.

The total paid media contribution prior can be advantageous as it doesn't require intuition on each individual channel. However, if additional knowledge or intuition about each channel is available, then consider setting a IKPC prior or channel-level contribution prior.

Custom incremental KPI per cost (IKPC) prior

If you have intuition about a channel's incremental KPI per cost (IKPC), you can set a IKPC prior using roi_m or roi_rf in the PriorDistribution container. When revenue_per_kpi is not set, ROI is equivalent to IKPC in Meridian.

Example:

roi_prior = tfp.distributions.LogNormal([0.5, 0.6, 0.7], [0.5, 0.5, 0.5])

However, we only recommend doing this if you are going to set a custom IKPC prior for every media channel. This is because the default ROI priors with revenue_per_kpi=None likely won't make sense for your data as it designed for revenue KPIs where the ROI would be on the unitless scale. If you only have intuition on the IKPC for some channels, you still must set some reasonable default IKPC prior for the other channels. Meridian doesn't have a recommended default IKPC prior because IKPC is strongly dependent on the scale, for example, a new car or a candy bar.

Channel-level contribution prior

If you have intuition about the proportion of the KPI that is incremental due to a given channel, you can set a prior on the contribution of a given channel by setting media_prior_type='contribution' and rf_prior_type='contribution' in the ModelSpec and customizing the prior distributions on contribution_m and contribution_rf in the PriorDistribution. The following is an example.

prior = prior_distribution.PriorDistribution(
    contribution_m=tfp.distributions.Beta([1, 5], [99, 95]),
    contribution_rf=tfp.distribution.Beta(2, 98),
)
model_spec = spec.ModelSpec(
    prior=prior,
    media_prior_type="contribution",
    rf_prior_type="contribution",
)

In this example, there are two media channels. The first is assigned a Beta(1, 99) contribution prior, which has a mean of 1%. The second is assigned a Beta(5, 95) contribution prior, which has a mean of 5%. The R&F channels are each assigned a contribution prior of Beta(2, 98), which has a mean of 2%. (Note that tfp.distribution.Beta(2, 98) is a scalar distribution, so it is broadcast to all R&F channels).