选择并配置处理变量的先验类型

在 Meridian 中,有多种处理变量类型,即付费媒体处理变量自然媒体处理变量非媒体处理变量。您可以为每种处理变量类型指定先验类型先验类型是指您用来设置先验信念的具体指标,例如投资回报率、边际投资回报率、贡献率或系数。您可以选择自己最了解的指标(例如来自实验的指标),也可以选择在解读模型结果时最关心的指标。

Meridian 会根据一些普遍的业务逻辑,为每种先验类型设置默认先验分布。您可以根据自己的特定领域专业知识替换默认分布,以便更好地将先验与自己的业务直觉相契合。了解这些选项及其背后的逻辑,对于将您的领域专业知识融入 Meridian 至关重要。

先验类型定义

以下是 Meridian 中提供的先验类型的定义:

  • 投资回报率 (ROI):渠道带来的增量效果与该渠道的媒体支出的比率 (Incremental Outcome / Spend)。这通常是最直观的付费媒体指标,尤其是在使用实验结果进行校准时
  • 边际投资回报率 (mROI):在特定渠道上额外支出一个货币单位(例如 1 美元)所带来的投资回报率。在考虑预算优化时,此指标非常有用,因为渠道的边际投资回报率越高,就越值得投入更多预算。
  • 贡献率:可归因于某个渠道的效果在总效果中所占的比例 (Incremental Outcome / Total Outcome)。投资回报率先验和边际投资回报率先验只能用于付费媒体,而贡献率先验可用于没有相关支出的渠道,例如自然渠道非媒体处理变量
  • 系数:Meridian 回归模型中给定处理变量的底层统计系数。与投资回报率、边际投资回报率和贡献率(均为业务指标)不同,系数是一个更为抽象的统计形参,如果不结合其他模型形参和数据,很难将其转化为具体的业务洞察

下表总结了哪些先验类型可用于每种处理变量类型。

先验类型 付费媒体 自然媒体 非媒体处理变量
投资回报率 是*
边际投资回报率 是*
贡献率
系数

业务语言示例

为了更清楚地说明这些概念,下面以简单的业务语言介绍了可以如何表达每种类型的先验:

  • 设置投资回报率先验

    “根据我们最新的效果提升研究,我们确信,在搜索广告方面,每花费 1 美元,就能带来大约 1.50 美元的收入。我希望投资回报率先验围绕该值居中。”

  • 设置边际投资回报率先验

    “在社交媒体广告的当前支出水平下,如果我们再多支出 1 美元,预计会获得大约 1.10 美元的回报。我希望边际投资回报率先验围绕该值居中且紧密分布。”

  • 设置贡献率先验

    “我们认为,数字视频广告带来的收入约占我们总收入的 5%。我希望贡献率先验围绕该值居中。”

  • 设置系数先验

    对于企业用户而言,这种情况不太常见。这就像在说:“我认为相应变量的潜在回归 Beta 值应为 0.02。”这通常是为具有特定统计目标的数据科学家保留的,因为具体解读在很大程度上取决于对输入数据和输出指标的缩放。

选择处理变量先验类型时的注意事项

在本部分中,我们将介绍在付费媒体、自然媒体和非媒体处理变量中选择不同先验类型的业务和建模理由。

投资回报率先验是默认选项,因为它们通常与先验知识(例如实验结果)最为一致。这通常是设置有合理依据的先验时最直观的选项。

如果历史预算的设置依据了大量先验知识,或者广告客户希望获得更保守的预算建议,边际投资回报率先验通常会是一个不错的选择。它们通过引入一个先验,使最佳预算分配趋近于历史预算分配,从而对建议预算调整进行正则化。为此,您可以针对所有渠道设置一个共同的边际投资回报率先验平均值,并调整标准差。先验越强(标准差越小),最佳分配就越接近历史分配,建议的预算调整幅度也就越小。请注意,优化支出限制提供了另一种限制建议预算调整的方法,让用户无需使用边际投资回报率先验。如需了解详情,请参阅“使用边际投资回报率先验进行预算正则化”子部分。

贡献率先验与付费媒体的投资回报率先验非常相似。唯一的区别是,投资回报率先验的分母是渠道支出,而贡献率先验的分母是总观测结果。也就是说,对于付费媒体,任何贡献率先验都可以转换为投资回报率先验,反之亦然。

系数先验是线性回归模型中更为传统的形参化方式。在 MMM 上下文中,对系数的解读有些抽象,因此很难设置有依据的先验。即使是同一系数值,不同付费媒体渠道的投资回报率值也可能大相径庭,因为投资回报率取决于渠道在不同地理位置和时间段的投放分布、渠道的 Adstock 和回报递减形参的估算值,以及渠道的每媒体单位费用。

非收入效果的其他注意事项

如果效果并非收入(当 KPI 不以货币单位衡量且未提供 revenue_per_kpi 时),付费媒体先验的可用性和解读方式会发生变化。PriorDistribution 的每个形参都有一个默认分布。不过,有以下两种例外情况不会使用默认值,这两种情况都发生在效果并非收入时。

投资回报率先验的运作方式有所不同,因为无法计算货币比率。不过,如果您使用 media_prior_type = 'roi',系统会针对所有付费媒体渠道的总贡献率设置默认先验。这样一来,您就可以为付费媒体带来的非货币 KPI 总贡献率设置先验。如果使用投资回报率先验,则会根据一种特殊的付费媒体总贡献率方法指定默认值。

边际投资回报率先验表示以每一美元带来的效果单位数(例如每一美元带来的额外注册人数)衡量的边际回报。由于此值高度依赖于特定 KPI,因此无法设置通用的默认值。因此,当效果并非收入时,Meridian 不会提供边际投资回报率的默认先验,而是需要您根据自己的领域知识自行指定先验。在这些情况下,必须提供自定义分布。之所以没有默认值,是因为对于每项业务,合理的值范围会有很大差异。

贡献率先验在效果并非收入时通常是一个实用的选择,因为它们表示归因于渠道的效果在总效果中所占的比例。无论效果是否为收入,此定义都保持不变。

自然媒体注意事项

贡献率先验是默认选项,因为它们是设置有依据的先验时最直观的量。某些渠道的贡献率预计会高于其他渠道,因此请考虑以适合您的业务和营销策略的方式自定义先验分布。Beta 分布通常是有意义的,因为它限制在零到一的区间内。

系数先验是线性回归模型中更为传统的形参化方式。与付费媒体类似,对系数的解读有些抽象,因此很难设置有依据的先验。即使是同一系数值,不同自然媒体渠道的贡献率值也可能大相径庭,因为贡献率取决于渠道在不同地理位置和时间段的执行分布,以及渠道的 Adstock 和回报递减形参的估算值。

非媒体处理变量注意事项

贡献率先验是默认选项,因为它们是设置有依据的先验时最直观的量。配置先验分布始终是一个不错的选择。根据每个变量的指定基准值,您可以预计贡献率为正值还是负值,或者贡献率的符号可能未知。例如,您可能不清楚将价格设为给定基准值会对收入产生正面影响还是负面影响。或者,您可能有一个先验预期:在某个基准值下,该价格会产生正面影响,但在另一个基准值下,该价格会产生负面影响。

系数先验是线性回归模型中更为传统的形参化方式。与付费媒体和自然媒体类似,对系数的解读有些抽象,因此很难设置有依据的先验。即使是同一系数值,不同非媒体处理渠道的贡献率值也可能大相径庭,因为贡献率取决于处理变量在不同地理位置和时间段的值分布以及处理变量的基准值。

选择处理变量先验类型的流程图

以下流程图详细说明了您应根据付费媒体、自然媒体或非媒体处理变量做出的上述考虑。

付费媒体

流程图:详细说明了为付费媒体选择合适先验类型时的注意事项

自然媒体/非媒体处理变量

流程图:详细说明了为自然媒体和非媒体处理变量选择合适先验类型时的注意事项

配置处理变量先验类型

本部分将介绍付费媒体、自然媒体和非媒体处理变量的可用先验类型,以及在 Meridian 库中配置这些先验类型时的不同注意事项。我们提供了多个代码段和示例,用于配置不同处理变量类型中的先验类型。

配置付费媒体先验

付费媒体的先验类型由 ModelSpecmedia_prior_typerf_prior_type 实参指定。下表显示了哪些 PriorDistribution 形参与每种先验类型相关联。

media_prior_type/rf_prior_type PriorDistribution 中的形参
'roi'*(默认) roi_m*、roi_rf*
'mroi'* mroi_m*、mroi_rf*
'contribution' contribution_mcontribution_rf
'coefficient' beta_mbeta_rf

以下部分提供了假设示例,演示了如何为具有两个付费媒体渠道的模型配置这些先验。以下几点阐述了后续代码块中示例先验设置背后的原因。我们还提供了默认分布,以便您了解每种先验类型的配置过程。

  • 投资回报率 (roi_m):此处配置为对数正态分布,平均值分别为 1.72.5,以与实验提升研究保持一致。

    供参考,默认分布使用 LogNormal(0.2, 0.9),平均值为 1.22,中位数为 1.83。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution
# -----------------------------------------------------------------------------
# Option 1: ROI (Return on Investment)
# -----------------------------------------------------------------------------
# ROI (LogNormal) -> Means at 1.7 and 2.5
prior = prior_distribution.PriorDistribution(
    roi_m=prior_distribution.PriorDistribution.lognormal_dist_from_mean_std(
        mean=[1.7, 2.5], std=[0.3, 0.5]
    )
)
model_spec = spec.ModelSpec(prior=prior, media_prior_type='roi')
  • 边际投资回报率 (mroi_m):配置为紧凑分布,平均值为 1.0。 为这两个渠道选择了相同的平均值和较小的标准差,以帮助实现预算优化正则化。之所以选择 1.0 的平均值,是因为这两个渠道都被认为接近饱和。

    供参考,默认分布使用 LogNormal(0.0, 0.5),平均值为 1.13,中位数为 1。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution
# -----------------------------------------------------------------------------
# Option 2: mROI (Marginal Return on Investment)
# -----------------------------------------------------------------------------
# mROI (LogNormal) -> Means at 1.0
prior = prior_distribution.PriorDistribution(
    mroi_m=prior_distribution.PriorDistribution.lognormal_dist_from_mean_std(
        mean=[1.0, 1.0], std=[0.2, 0.2]
    )
)
model_spec = spec.ModelSpec(prior=prior, media_prior_type='mroi')
  • 贡献率(contribution_m):使用 Beta 分布来模拟特定“效果份额”为 3%4% 的情况。

    供参考,默认分布使用 Beta(concentration1=1.0, concentration0=99.0),平均值为 1%。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution
# -----------------------------------------------------------------------------
# Option 3: Media Contribution
# -----------------------------------------------------------------------------
# Contribution (Beta) -> Means at 3% and 4%
prior = prior_distribution.PriorDistribution(
    contribution_m=tfp.distributions.Beta(
        concentration1=[3.0, 4.0], concentration0=[97.0, 96.0]
    )
)
model_spec = spec.ModelSpec(prior=prior, media_prior_type='contribution')
  • 系数 (beta_m):使用具有更小尺度(1.01.5)的半正态分布来应用统计正则化。

    供参考,默认分布Normal(0, 5),被认为是弱信息先验。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution
# -----------------------------------------------------------------------------
# Option 4: Media Coefficient
# -----------------------------------------------------------------------------
# Coefficient (HalfNormal) -> Scales at 1.0 and 1.5
prior = prior_distribution.PriorDistribution(
    beta_m=tfp.distributions.HalfNormal(scale=[1.0, 1.5])
)
model_spec = spec.ModelSpec(prior=prior, media_prior_type='coefficient')

配置自然媒体先验

自然媒体的先验类型由 organic_media_prior_typeorganic_rf_prior_type 实参指定。选项包括 'contribution''coefficient',其中 'contribution' 是默认选项。

organic_media_prior_type/organic_rf_prior_type PriorDistribution 中的形参
'contribution'(默认) contribution_omcontribution_orf
'coefficient' beta_ombeta_orf

自然媒体配置示例

本部分提供了代码示例,演示了如何为自然媒体处理变量配置不同的先验类型。以下几点阐述了后续代码块中示例先验设置背后的原因。我们还提供了默认分布,以便您了解每种先验类型的配置过程。

  • 贡献率 (contribution_om):设置平均值为 3% 的 Beta 分布。

    供参考,默认分布Beta(1.0, 99.0),平均值为 1%

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution
# -----------------------------------------------------------------------------
# Option 1: Organic Media Contribution
# -----------------------------------------------------------------------------
# Contribution (Beta) -> Mean at 3%
prior = prior_distribution.PriorDistribution(
    contribution_om=tfp.distributions.Beta(
        concentration1=[3.0, 3.0], concentration0=[97.0, 97.0]
    )
)
model_spec = spec.ModelSpec(prior=prior, organic_media_prior_type='contribution')
  • 系数 (beta_om):使用半正态分布来应用更严格的统计正则化(尺度为 2.0)。

    供参考,默认分布HalfNormal(5),尺度为 5。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution
# -----------------------------------------------------------------------------
# Option 2: Organic Media Coefficient
# -----------------------------------------------------------------------------
# Coefficient (HalfNormal) -> Scale at 2.0
prior = prior_distribution.PriorDistribution(
    beta_om=tfp.distributions.HalfNormal(scale=[2.0, 2.0])
)
model_spec = spec.ModelSpec(prior=prior, organic_media_prior_type='coefficient')

配置非媒体处理变量先验

非媒体处理变量的先验类型由 non_media_treatments_prior_type 实参指定。选项包括 'contribution''coefficient',其中 'contribution' 是默认选项。

下表显示了与每个 non_media_treatments_prior_type 对应的 PriorDistribution 形参,该形参可用于自定义先验分布。

non_media_treatments_prior_type PriorDistribution 中的形参
'contribution'(默认) contribution_n
'coefficient' gamma_n

非媒体处理变量配置示例

本部分提供了几个代码示例,演示了如何为非媒体处理变量配置不同的先验类型。以下几点阐述了后续代码块中示例先验设置背后的原因。我们还提供了默认分布,以便您了解每种先验类型的配置过程。

  • 贡献率 (contribution_n):设置截断的正态分布,使质量集中在第一个处理变量的 (-5%) 和第二个处理变量的 (5%)。两者的不确定性都相对较大 (10%)。

    第一个处理变量的先验仅允许负贡献率,因为它被截断为在 (-100%, 0%) 范围内。如果非媒体处理变量是价格,而 KPI 是售出件数,那么这种做法可能比较合理。

    第二个处理变量的先验仅允许正贡献率,因为它被截断为在 (0%, 100%) 范围内。如果非媒体处理变量表示促销活动,而 KPI 是售出件数,那么这种做法可能比较合理。

    供参考,默认分布TruncatedNormal(0.0, 0.1, -1.0, 1.0),被视为弱信息性先验。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution
# -----------------------------------------------------------------------------
# Option 1: Non-Media Treatment Contribution
# -----------------------------------------------------------------------------
# Contribution (TruncatedNormal) -> Loc at -5% and 5%, Scale at 10%
prior = prior_distribution.PriorDistribution(
    contribution_n=tfp.distributions.TruncatedNormal(
        loc=[-0.05, 0.05],
        scale=[0.1, 0.1],
        low=[-1.0, 0.0],
        high=[0.0, 1.0]
    )
)
model_spec = spec.ModelSpec(
    prior=prior,
    non_media_treatments_prior_type='contribution'
)
  • 系数 (gamma_n):使用 Normal(0, 1),其标准差小于默认分布。有时,更强的正则化有助于减少后验方差。

    供参考,默认分布Normal(0, 5),被认为是弱信息先验。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution
# -----------------------------------------------------------------------------
# Option 2: Non-Media Treatment Coefficient
# -----------------------------------------------------------------------------
# Coefficient (Normal) -> Loc at 0.0, Scale at 1.0
prior = prior_distribution.PriorDistribution(
    gamma_n=tfp.distributions.Normal(
        loc=[0.0, 0.0], scale=[1.0, 1.0]
    )
)
model_spec = spec.ModelSpec(
    prior=prior,
    non_media_treatments_prior_type='coefficient'
)

指定适当的先验实参

PriorDistribution 对象针对每种处理变量类型和先验类型组合都有一个实参。对于每种处理变量类型,系统只会使用与所选先验类型对应的实参。其他实参会被忽略。

例如,与非 R&F 付费媒体对应的实参为

  • roi_m

  • mroi_m

  • contribution_m

  • beta_m

如果 media_prior_type'roi',则使用 roi_m,而忽略其他实参。

例如,用户为多种先验类型指定先验。不过,在此示例中,由于 media_prior_type='contribution',因此仅使用贡献率先验

在以下代码段中,请注意 roi_mmroi_m 的定义方式,但由于 media_prior_type 设置为 contribution,因此系统会忽略这些定义。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution

# Set custom prior for all paid media treatment parameters.
prior_dist = prior_distribution.PriorDistribution(
    roi_m=tfp.distributions.LogNormal(0.2, 0.9), # NOT used
    mroi_m=tfp.distributions.LogNormal(0.0, 0.5), # NOT used
    contribution_m=tfp.distributions.Beta(1.0, 99.0), # Used
    beta_m=tfp.distributions.HalfNormal(5.0), # NOT used
)

# Setting the treatment type to 'contribution' means that only the `contribution_m`
# prior will be used. The priors specified on `roi_m`, `mroi_m`, and `beta_m` will be ignored.
spec = spec.ModelSpec(prior=prior_dist, media_prior_type='contribution')

以下流程图还详细介绍了指定正确先验的相关行为。

流程图:详细说明了模型规范的正确形参用法

其他注意事项

本部分包含在 Meridian 中选择不同处理变量先验类型时可以考虑的其他高级事项。

自定义非媒体处理变量的贡献率先验

默认贡献率先验是截断的正态分布,它允许正值和负值。您可以针对截断的正态分布设置处理变量专用形参,以将概率质量调整到正值或负值区间。例如,以下代码段会为第一个处理变量分配对称截断的 Normal(0, 0.1) 分布,为第二个处理变量分配正向截断的 HalfNormal(0, 0.2) 分布,并为第三个处理变量分配负向截断的 HalfNormal(0, 0.1) 分布。

PriorDistribution(
    contribution_n=tfp.distributions.TruncatedNormal(
        loc=[0, 0, 0],
        scale=[0.1, 0.2, 0.1],
        high=[1, 1, 0],
    )
)

或者,您可以使用缩放的 Beta 分布来为某些处理变量指定正向分布,并为其他处理变量指定负向分布。例如,以下代码段会为第一个处理变量分配 Beta(1, 49) 先验,并为第二个处理变量分配负向 Beta(1, 99) 先验。

PriorDistribution(
    contribution_n=tfp.distributions.TransformedDistribution(
        tfp.distributions.Beta([1, 1], [49, 99]),
        tfp.bijectors.Scale([1, -1]),
    )
)

了解诱导先验和渠道对等性

如果您指定了一个指标(例如投资回报率)的先验,Meridian 会诱导出另一个指标(边际投资回报率)的先验。这种诱导先验不属于标准形参族,并且取决于其他模型形参,包括渠道在不同地理位置和时间段的媒体执行情况。

这对渠道对等性有重要影响:例如,即使您为所有渠道设置了共同的投资回报率先验,每个渠道的诱导边际投资回报率先验也会有所不同,反之亦然。因此,如果您的目标是假设特定指标在各个渠道之间保持一致,则应使用相应的形参化直接为该指标设置先验。

如果您想检查模型的诱导投资回报率先验和边际投资回报率先验,可以调用 sample_prior,然后使用实参 use_posterior=False 调用 Analyzer 类的 roimarginal_roi 方法。

from meridian.analysis import analyzer
from meridian.model import model
import numpy as np

mmm = model.Meridian(...)
mmm.sample_posterior(...)
analyzer_instance = analyzer.Analyzer(mmm)

# Get the prior distributions using `use_posterior=False`.
roi_prior = analyzer_instance.roi(use_posterior=False)

# This is the induced prior on mROI.
mroi_induced_prior = analyzer_instance.marginal_roi(use_posterior=False)

# The shape of the prior samples is (chains, draws, channels).
# We calculate the mean across the 'chains' and 'draws' axes.
print("Mean of ROI prior per channel:", np.mean(roi_prior, axis=(0, 1)))
print("Mean of induced mROI prior per channel:", np.mean(mroi_induced_prior, axis=(0, 1)))

高级:边际投资回报率与投资回报率之间的诱导关系

虽然诱导先验不属于标准形参族,但我们可以对诱导先验进行一些说明。请注意,边际投资回报率是指在给定渠道上额外支出一个货币单位(例如 1 美元)所带来的投资回报率。

对于基于展示次数的渠道(即没有 R&F 数据的渠道),系统会通过增加媒体执行量(例如展示次数)来分配额外的支出货币单位。

当渠道的 Hill 函数呈凹形(默认情况)时,渠道的总体投资回报率始终高于其边际投资回报率。这会导致指定先验与诱导先验之间存在可预测的关系:

  • 投资回报率先验会诱导出严格小于其数值的边际投资回报率先验。
  • 边际投资回报率先验会诱导出严格大于其数值的投资回报率先验。

对于具有覆盖面和频次 (R&F) 数据的渠道,系统会通过扩大覆盖面并保持平均频次固定不变,来分配额外的货币单位支出。

对于具有覆盖面和频次数据的渠道,边际投资回报率(按覆盖面计算)等于投资回报率,因为在 Meridian 模型下,媒体效应是随着覆盖面线性变化的。Meridian 的边际投资回报率先验是按覆盖面应用于边际投资回报率的;因此,对于这些渠道来说,选择投资回报率先验还是边际投资回报率先验对先验本身没有影响。不过,如果您使用的是默认分布,那么选择就非常重要,因为投资回报率先验和边际投资回报率先验的默认分布不同。

使用边际投资回报率先验进行预算正则化

您可以使用边际投资回报率先验,通过让预算优化建议趋近于历史预算分配来对其进行正则化。如果您认为历史预算已经接近最佳水平,则此功能非常有用。

为此,您可以针对所有渠道设置一个共同的边际投资回报率先验平均值,并使用较小的标准差。先验越强(标准差越小),最佳分配就越接近历史分配,从而使建议的预算调整幅度更小。例如,将边际投资回报率平均值设为 1.0 表明,在历史支出水平下,每增加 1 美元的支出会带来 1 美元的回报,这意味着相应渠道的预算接近最佳水平。

import tensorflow_probability as tfp
from meridian.model import spec, prior_distribution

# Assume 2 paid media channels.
# Set a common mROI prior mean of 1.0, suggesting budgets are near optimal.
# Use a very small standard deviation to create a strong prior.
mean_mroi = [1.0, 1.0]
std_mroi = [0.1, 0.1]  # A small std dev creates a strong prior.

lognormal_mroi_regularizing = prior_distribution.PriorDistribution.lognormal_dist_from_mean_std(
    mean_mroi, std_mroi
)

prior_mroi_regularizing = prior_distribution.PriorDistribution(
    mroi_m=lognormal_mroi_regularizing
)

# This ModelSpec will produce more conservative budget recommendations.
model_spec_regularized = spec.ModelSpec(
    prior=prior_mroi_regularizing,
    media_prior_type='mroi'
)

渠道的媒体执行量(以及饱和度)可能会在不同的时间范围内发生变化。因此,不同时间范围的边际投资回报率值可能会有所不同。如果您的目标是使用边际投资回报率先验来对预算优化进行正则化处理,请确保先验的时间范围与优化的时间范围一致。否则,正则化可能无法按预期运行。