如何将TensorFlow分布作为参数传入另一分布并构建过度分散泊松分布?
构建过度分散泊松分布(泊松-伽马混合)及TFP分布传参实现
核心逻辑梳理
过度分散泊松分布的本质是泊松分布的速率参数λ服从伽马分布——这种混合分布会让边缘分布的方差大于均值,也就是所谓的“过度分散”。在TensorFlow Probability(TFP)中,你可以直接将一个分布作为另一个分布的参数来构建分层模型,也可以用联合分布显式建模变量间的依赖关系。
具体代码实现
先导入必要的依赖库:
import tensorflow as tf import tensorflow_probability as tfp tfd = tfp.distributions
方式1:直接将伽马分布作为泊松的速率参数
TFP的泊松分布支持把rate参数指定为另一个分布实例,自动构建分层分布:
# 定义伽马先验:控制速率λ的分布,这里设置concentration=2.0,rate=1.0 gamma_prior = tfd.Gamma(concentration=tf.constant(2.0), rate=tf.constant(1.0)) # 构建过度分散泊松分布:泊松的rate参数直接传入伽马分布 overdispersed_poisson = tfd.Poisson(rate=gamma_prior) # 生成样本:先从伽马分布采样λ,再用该λ采样泊松样本 samples = overdispersed_poisson.sample(1000) # 生成1000个过度分散的泊松样本 # 计算x的边缘对数概率(通过蒙特卡洛积分近似,对λ积分) def marginal_log_prob(x): lam_samples = gamma_prior.sample(1000) log_probs = overdispersed_poisson.log_prob(x) return tf.reduce_logsumexp(log_probs) - tf.math.log(1000.0)
方式2:用联合分布显式建模
这种方式更清晰展示变量间的依赖关系,适合复杂分层场景:
# 定义联合分布模型,按顺序生成λ和x joint_model = tfd.JointDistributionSequential([ # 第一步:采样速率λ lambda: tfd.Gamma(concentration=2.0, rate=1.0), # 第二步:用采样得到的λ作为泊松的速率,采样x lambda lam: tfd.Poisson(rate=lam) ]) # 生成联合样本:(λ的样本集合, x的样本集合) lam_samples, x_samples = joint_model.sample(1000) # 计算联合对数概率:log P(λ) + log P(x|λ) joint_log_prob = joint_model.log_prob((lam_samples, x_samples)) # 计算x的边缘对数概率 marginal_log_prob_x = tf.reduce_logsumexp(joint_log_prob) - tf.math.log(1000.0)
关键细节说明
- 过度分散的来源:伽马分布给速率λ增加了随机性,原本泊松分布的方差等于均值,混合后边缘方差变为
均值 + 均值² / 伽马分布的concentration,方差大于均值,实现了过度分散。 - 分布传参的本质:TFP中分布的参数可以是张量或分布实例,当传入分布时,该分布会被当作参数的先验,原分布自动变为条件分布,调用
sample或log_prob时会自动处理分层逻辑。 - 等价性验证:这种泊松-伽马混合分布其实等价于负二项分布,你可以用
tfd.NegativeBinomial(total_count=2.0, probs=0.5)对比样本分布,结果完全一致。
内容的提问来源于stack exchange,提问作者Guilherme Namen
相关产品推荐
相关产品推荐

