1. 贝叶斯思维入门:频率学派 vs 贝叶斯学派、先验与后验、共轭先验、JAX生态介绍
1.1 两种统计世界观:你站哪边?
做机器学习这些年,我经常被问到同一个问题:「参数到底是不是随机的?」
这个问题看似简单,却把统计学家分成了两大阵营。说白了,频率学派和贝叶斯学派的根本分歧就在这里。
频率学派认为:参数是固定的、未知的常数。数据是随机的,我们通过重复抽样来估计参数。你想想看,抛硬币一万次,正面概率 p 就是那个固定的值,不会变。
贝叶斯学派则认为:参数也是随机的。我们用概率分布来描述对参数的不确定性。数据来了,我们就更新这个分布。
我在项目中遇到过这样一个场景:做A/B测试时,频率学派告诉你「p值大于0.05,不显著」。但业务方问:「那到底哪个版本更好?概率是多少?」频率学派没法回答这个问题——因为参数不是随机变量,不能说「A比B好的概率是85%」。但贝叶斯可以。这就是实战中的差异。
核心区别一句话总结:
- 频率学派:数据是随机的,参数是固定的
- 贝叶斯学派:参数是随机的,数据是固定的(我们观测到的)
1.2 先验与后验:贝叶斯定理的灵魂
贝叶斯定理其实就一个公式,但它的内涵很深:
P(θ|D) = P(D|θ) * P(θ) / P(D)
翻译成人话就是:后验 = 似然 × 先验 / 证据
我个人习惯这样理解:
- 先验 P(θ):在看到数据之前,我对参数的「偏见」
- 似然 P(D|θ):给定参数,数据出现的可能性
- 后验 P(θ|D):看到数据后,我对参数的「修正」
举个例子。我做一个点击率预估模型,先验认为新广告的点击率大概在2%左右(行业经验)。跑了1000次曝光,来了30次点击。后验就会把先验和观测数据融合起来,给出一个更精确的分布。
嗯,这里要注意:先验不是瞎猜的。我曾经见过有人用非常强的先验(比如「点击率肯定小于0.1%」),结果数据来了完全对不上,后验被先验带偏了。这叫「先验主导」,是贝叶斯建模的常见坑。
我的建议:先验可以弱一些,让数据说话。如果你不确定,用无信息先验(比如均匀分布)起步,逐步加入领域知识。
1.3 共轭先验:数学上的「天作之合」
共轭先验这个概念,说白了就是:先验和后验属于同一分布族。
为什么会这样?因为数学上方便啊!
举个例子:
- 似然是二项分布 → 共轭先验是Beta分布 → 后验也是Beta分布
- 似然是高斯分布(方差已知) → 共轭先验是高斯分布 → 后验也是高斯分布
- 似然是泊松分布 → 共轭先验是Gamma分布 → 后验也是Gamma分布
我记得刚学贝叶斯时,觉得共轭先验就是个数学技巧。后来做在线学习系统才发现,共轭先验可以让我们增量更新参数——来一条数据,更新一下后验,不用重新跑整个模型。这在实时系统中太重要了。
| 似然分布 | 共轭先验 | 后验形式 |
|---|---|---|
| 二项分布 | Beta(α, β) | Beta(α + k, β + n - k) |
| 高斯分布(已知方差) | 高斯(μ₀, σ₀²) | 高斯(加权平均) |
| 泊松分布 | Gamma(α, β) | Gamma(α + sum(x), β + n) |
避坑指南:共轭先验虽然方便,但不要为了数学优雅而牺牲模型表达力。我曾经为了用共轭先验,硬把非共轭的问题强行简化,结果模型效果很差。现在我的原则是:先用共轭先验快速迭代,再考虑更灵活的近似方法。
1.4 JAX生态:贝叶斯建模的「瑞士军刀」
聊完理论,咱们看看工具。JAX 不是另一个深度学习框架,它是一套可微分编程的工具链。
我个人觉得 JAX 最牛的地方有三点:
- 自动微分:grad() 函数一用,梯度就到手
- JIT编译:XLA编译器把Python代码编译成GPU/TPU上的高效计算
- 向量化映射:vmap() 让你轻松处理批量数据
在贝叶斯建模中,JAX 生态的核心库包括:
# 核心库
import jax
import jax.numpy as jnp
from jax import grad, jit, vmap, random
# 概率编程库
import numpyro
import numpyro.distributions as dist
from numpyro.infer import MCMC, NUTS, SVI
# 优化和自动微分
from jax.example_libraries import optimizers
你想想看,传统贝叶斯建模用 PyMC 或 Stan,虽然功能强大,但速度慢、扩展性差。JAX 生态把贝叶斯推断和深度学习结合起来了——你可以用神经网络做变分推断,也可以用 MCMC 采样,全都在 GPU 上跑。
我记得第一次用 NumPyro 跑一个分层贝叶斯模型,数据量 100 万行,传统工具要跑几个小时。JAX + GPU 只用了 15 分钟。那一刻我就知道,贝叶斯建模的「工业化」时代来了。
JAX生态的贝叶斯建模流程:
- 用 NumPyro 定义概率模型(先验 + 似然)
- 选择推断方法:MCMC(精确但慢)或 SVI(近似但快)
- 用 JAX 的 JIT 编译加速计算
- 后验分析 + 预测
1.5 本章知识体系
下面这张图是我自己梳理的,把本章的核心逻辑串起来了:
1.6 实战:用NumPyro跑一个贝叶斯模型
光说不练假把式。咱们用 NumPyro 跑一个最简单的贝叶斯模型——估计抛硬币的正面概率。
import numpyro
import numpyro.distributions as dist
from numpyro.infer import MCMC, NUTS
import jax.numpy as jnp
from jax import random
# 模拟数据:抛了100次,60次正面
n_trials = 100
n_success = 60
data = jnp.concatenate([jnp.ones(n_success), jnp.zeros(n_trials - n_success)])
# 定义模型
def coin_model(data=None):
# 先验:Beta(2, 2) 表示我们认为正面概率大概在0.5附近
p = numpyro.sample('p', dist.Beta(2, 2))
# 似然:二项分布
with numpyro.plate('data', len(data)):
numpyro.sample('obs', dist.Bernoulli(p), obs=data)
# 运行MCMC采样
mcmc = MCMC(NUTS(coin_model), num_samples=2000, num_warmup=500)
mcmc.run(random.PRNGKey(0), data=data)
# 查看结果
mcmc.print_summary()
跑完之后,你会看到 p 的后验均值大概在 0.58 左右,95% 可信区间大概是 [0.48, 0.68]。这个区间告诉你:虽然观测到 60% 的正面,但真实概率仍有可能是 0.5。这就是贝叶斯的不确定性量化——比单纯的点估计有用得多。
小技巧:先验的 Beta(2, 2) 相当于「虚拟观测」——2次正面、2次反面。如果你改成 Beta(1, 1)(均匀分布),后验就完全由数据驱动。试试看,结果会有什么变化?
好了,第一章就到这里。记住三个关键词:先验、似然、后验。后面的章节我们会一步步深入,从简单模型到复杂的分层模型,再到深度贝叶斯网络。JAX 生态会让这一切变得又快又灵活。