先抛一个很常见的场景。你手头有一枚来源不明的硬币,连抛 20 次,14 次正面朝上。现在有人问你:这枚硬币的正面概率是多少?放在几年前,我大概会直接回一句 0.7,再补一个置信区间就算了。但后来样本量小、业务追问又深的场景见得多了,越来越觉得这个答案有问题——样本少的时候 0.7 根本站不住脚,而且“真实概率是多少”这句话本身就预设了一个不存在的答案。贝叶斯参数学习就是在这个反思点上走出来的:它把参数当作一个有先验、有后验的随机变量,用证据一层层修正认识,而不是硬憋一个“最可能的数”。
这篇文章适合两类人:一类是刚接触贝叶斯统计、想搞清楚先验和后验到底在干嘛的新手;另一类是已经会跑现成机器学习库、但对后验分布、先验设定这些概念始终隔层纱的进阶者。我会尽量把公式掰开揉碎,配上可以直接抄作业的更新流程,最后把贝叶斯网络里的参数学习也串进来——毕竟很多资料里“贝叶斯参数学习”这个标题指的就是那件事。
1. 为什么要学贝叶斯参数学习:从“点估计”到“分布估计”
1.1 频率派的三个尴尬瞬间
频率派不是不能学,而是有些场景下它交出来的答案很别扭。第一个尴尬是小样本下的点估计飘忽不定。还是说抛硬币,只抛 5 次,结果 4 正 1 反,最大似然估计直接告诉你正面概率 0.8。但你我都清楚,5 次的样本根本撑不起这个结论,换一轮实验可能就变成 0.4。点估计本身没有“我心里没底”这个选项,它只会自信地给出一个数。
第二个尴尬是置信区间的含义太反直觉。95% 置信区间说的是“如果重复做很多次实验,大约 95% 的区间会套住真实参数”,它并不是“这个区间里有 95% 的概率包含真实参数”。前者是频率意义上的长期行为,跟眼前这个具体区间其实没有直接关系。可业务方几乎都会把它读成后一句话,每次解释都很费劲。
第三个尴尬是没有给先验知识留入口。你明明有之前跑过的历史实验数据,明明知道同类产品的转化率大概率落在某个区间里,频率派的框架里却没有自然的位置去放这些信息。它只能靠数据自己说话,而数据少的时候它说得又不够清楚。
1.2 贝叶斯视角下,参数是一个会成长的信念
贝叶斯参数学习的回答方式完全不同:它先给参数一个初始分布,叫先验;然后看到数据,数据通过似然函数去“检验”这个先验;最后得到修正后的分布,叫后验。整个过程可以概括成一个递推链条:
先验 → 看到数据 → 后验 → 把这个后验当新的先验 → 再看数据 → 更新的后验……
用个生活化的类比:这就像老刑警看监控。看之前心里通常已经有一个粗略的嫌疑人画像,这是先验;看几段监控之后,画像会调整——有些特征被强化,有些被淡化,这是后验。监控越清晰、证据越多,画像就往真实方向靠得越厉害;监控模糊的时候,初始画像的作用就非常明显。这个类比你品一品就会发现,它天然解决了频率派的三个尴尬:结果不是一个数而是一个分布,含义直观;先验有地方放了;样本少的时候,先验还能帮忙压住不合理的极端判断。
我一直觉得,贝叶斯参数学习真正的门槛不在数学,而在思维方式的转换:你能不能接受“参数本身不是固定不变的,只是我们认为它是随机变量”。一旦过了这关,后面所有公式都只是理所当然的展开。
2. 核心公式拆解:先验、似然、后验的关系
2.1 贝叶斯公式逐项拆开
贝叶斯参数学习的核心就一个公式:
P(θ|D) = P(D|θ) · P(θ) / P(D)
翻译过来就是:后验 = 似然 × 先验 / 归一化常数。
每一项的意义其实都很直白。P(θ) 是看到数据之前你对参数的主观信念,写成分布形式而不是单个数字。P(D|θ) 是似然,它在回答一个问题:如果参数真的是 θ,当前这堆数据出现的可能性有多大。P(θ|D) 就是后验,是看完数据之后你修正过的信念。分母 P(D) 是对整个参数空间做积分,作用只是让后验的总面积等于 1,保证它是个合法概率分布。
实操里我们几乎从来不算这个分母,因为分母跟 θ 无关,只是个比例常数。参数学习要的是后验的形状和位置,不是绝对数值。所以公式通常被简写成:
P(θ|D) ∝ P(D|θ) · P(θ)
这个“正比于”看着简单,却是整个贝叶斯推断的抓手:只要能把似然和先验乘起来,剩下的事就是归一化。
2.2 数据和先验是一场谈判
把公式两边取对数,能看出一件特别重要的事情:
log P(θ|D) = log P(D|θ) + log P(θ) + 常数
后验的对数等于似然的对数加上先验的对数,再加常数。这意味着,后验本质上是一场先验和数据的谈判:先验说“我觉得 θ 大概在 0.5 附近”,数据说“实测结果更偏向 0.7”,最后谁占上风,取决于双方的“底气”。
先验的底气来自它的集中程度,越集中的先验越难被拉动;数据的底气来自样本量,样本越多,似然函数越尖锐,几乎把先验按在地上摩擦。这也是贝叶斯推断里最经典的直觉:样本量小的时候先验主导,样本量大的时候数据主导。最有意思的中间态是,数据不多不少时,后验被夹在两者之间,形成一个比两者都更窄、更稳定的分布。
2.3 递推更新:昨天的后验,就是今天的先验
贝叶斯参数学习还有一个特别适合工程落地的性质:它可以分批更新。第一批数据算出的后验,直接作为第二批数据的先验,再做一次乘法,得到的后验和一次性看完所有数据再算完全一致。这个结论并不显然,但可以当作定理来用。
它带来的实际价值是,你可以做“在线学习”。今天来了 100 条数据,更新一次先验,存下后验的参数;明天又来 100 条,接着更新。系统永远不需要记住历史原始数据,只需要记住一个分布参数。这在很多实时场景里是巨大的存储和计算优势。
3. 共轭先验:把后验计算从积分变成加法
3.1 什么是共轭,为什么它重要
如果没有别的技巧,算后验一般要处理 P(D),也就是把分子对 θ 做积分。这个积分在很多模型里没有解析解,只能上数值方法,麻烦。共轭先验就是一类特别选出来的先验:它和似然相乘之后,得到的后验跟自己是同一个分布族,只是参数变了。
用大白话说,本来你要解一道积分题,做了共轭之后变成填一张参数更新表。后验和先验长得一样,换的只是几个数字。对新手来说,先记共轭组合是踏上贝叶斯参数学习最快的路径,没有之一。
3.2 伯努利/二项分布 + Beta 先验
最常见的组合是抛硬币问题。似然是伯努利分布(或推广到二项分布),先验取 Beta(a, b)。如果数据里有 s 次正面、f 次反面,后验就是:
Beta(a + s, b + f)
这个式子的直观意思非常美:先验 Beta(a, b) 相当于你事先看过 a 次正面、b 次反面,数据来了就直接往上加次数。a 和 b 因此被叫做“虚拟样本数”。Beta 分布的均值是 a/(a+b),方差是 ab/[(a+b)²(a+b+1)],这两个公式建议直接背下来,后面所有后验解读都会用到。
3.3 正态分布 + 正态先验
另一个高频组合是正态似然配正态先验,专门用来学一个未知均值。假设总体方差已知为 σ²,先验是 N(μ0, σ0²),观测了 n 个数据,均值是 x̄。定义精度 τ = 1/σ²,τ0 = 1/σ0²,那么后验均值是:
(τ0·μ0 + n·x̄/σ²) / (τ0 + n/σ²)
后验方差是 1 / (τ0 + n/σ²)。这个结果翻译成人话就是:后验均值是先验均值和样本均值的加权平均,权重分别是先验精度和样本精度。每多一个数据点,就在后验精度上加一份 1/σ²。这个“精度可加”的性质,让在线更新写起来极其清爽。
3.4 泊松分布 + Gamma 先验
第三个组合常用于计数事件的发生率。如果数据是单位时间内的到达次数,服从泊松分布,先验取 Gamma(a, b),后验就是:
Gamma(a + Σx_i, b + n)
其中 Σx_i 是全部观测次数之和,n 是观测个数。图形上,先验的中心会随着观测的总次数被拉向数据均值。Gamma 分布在这种场景下扮演的角色,和 Beta 在抛硬币场景里一模一样——它提供一套代数上封闭的更新规则。
3.5 常用组合速查表
| 数据分布 | 先验分布 | 观测统计量 | 后验分布 |
|---|---|---|---|
| 伯努利/二项 | Beta(a, b) | 成功次数 s,失败次数 f | Beta(a+s, b+f) |
| 正态(方差已知) | 正态 | 样本量 n,样本均值 x̄ | 正态 |
| 泊松 | 伽马 | 次数和 Σx,样本数 n | 伽马 |
| 多项式 | 狄利克雷 | 各类计数 n₁...n_k | 狄利克雷 |
最后一行狄利克雷先验是 Beta 在高维的推广,后面讲贝叶斯网络时会再见到它。把这四个组合记住,市面上八成参数学习例子你就能手推了。
4. 完整实战:一枚硬币的 10 次观测与后验迭代
4.1 问题设定与先验选择
假设我们要学一枚硬币的正面概率 θ。由于结果只有正反两面,用伯努利似然;先验选择一个温和的 Beta(2, 2)。Beta(2,2) 的密度中间高、两端低,均值正好是 0.5,等价于“预先看过 2 次正面、2 次反面”。它的标准差大约在 0.22 左右,属于比较宽、不太强硬的先验,适合场景是我们只知道硬币大概率公平,但不敢打包票。
4.2 分两个批次更新后验
现在开始抛硬币,第一批抛 5 次,结果是 3 正 2 反。套公式:
后验 = Beta(2+3, 2+2) = Beta(5, 4)
后验均值 = 5 / (5+4) ≈ 0.556。可以看到,跟初始的 0.5 相比,分布只是轻微右移,因为 5 条数据还不足以说服它“这硬币偏了”。
第二批继续抛 5 次,结果是 4 正 1 反。这时把 Beta(5,4) 当作新先验再更新:
后验 = Beta(5+4, 4+1) = Beta(9, 5)
后验均值 = 9 / 14 ≈ 0.643。分布的腰身也明显变窄了,说明 10 条数据让信念收敛了不少。如果你把 10 次观测一次性喂进去,得到的结果同样是 Beta(9,5)。分批更新和整体更新的等价性,在这里从计算结果上直观验证了一遍。
4.3 从后验里读出结论
拿到 Beta(9,5) 之后,我们能说什么?首先,θ 最有可能的取值,也就是众数 (a-1)/(a+b-2) = 8/12 ≈ 0.667,它比平均值更“跟着数据走”。其次,后验方差约等于 0.0153,标准差约 0.124。用正态近似粗略估一个 90% 可信区间,θ 大约落在 [0.44, 0.85] 这个范围里。
注意这里说的是“θ 落在这个区间的概率约为 90%”,这和频率派的置信区间是完全不同的话。在贝叶斯框架里,这个陈述是合法的,因为它描述的就是你对参数的主观信念。业务方问“到底是多少”的时候,你可以很自然地回答:最可能是 0.67 左右,但坦白讲范围还挺宽,介于 0.44 到 0.85。这个回答比“就是 0.7”诚实得多。
4.4 用纯 Python 实现参数更新
后验更新本身简单到不需要任何第三方库,核心就一个加法函数:
def update_beta(a, b, heads, tails): """用一批伯努利观测更新 Beta 先验参数""" return a + heads, b + tails # 先验 Beta(2, 2) a, b = 2, 2 print("先验: Beta(%d, %d), 均值 %.3f" % (a, b, a / (a + b))) # 第一批:3 正 2 反 a, b = update_beta(a, b, 3, 2) print("第一批后验: Beta(%d, %d), 均值 %.3f" % (a, b, a / (a + b))) # 第二批:4 正 1 反 a, b = update_beta(a, b, 4, 1) print("第二批后验: Beta(%d, %d), 均值 %.3f" % (a, b, a / (a + b)))输出结果分别是 0.5、约 0.556、约 0.643。这段代码虽然短,却完整演示了贝叶斯参数学习的核心流程。真实项目里,你只需要把“更新参数”这一步换成对应分布族的公式,原理一模一样。
5. 先验怎么设:三类常见做法和实战教训
5.1 无信息先验,其实没那么“无信息”
一上来最常被问的问题是:先验选什么。很多人第一反应是选“什么都不代表”的均匀分布,对应 Beta(1,1)。它看起来中立,但实际上“均匀”本身就是一种很强的假设——它等于在说,θ 取 0.01 和取 0.5 的可能性完全一样,这对大部分真实问题都过分悲观。
还有一类常用选择是 Beta(0.5, 0.5),它比均匀分布更往两端翘。小样本时,这两种“无信息”先验算出的后验会有肉眼可见的差异。所以别把“无信息”当成客观的代名词,任何先验都在传递假设,你能做的是把假设挑明,再评估它是否合理。
5.2 弱信息先验:我实际最常用的一招
比起追求“无信息”,我更推荐用弱信息先验。它的思路是:用一点靠谱的领域知识,把参数约束在合理范围内,但故意留足自由度让数据说话。
举个例子,假设你在评估某个功能的转化率。同类功能历史转化率基本落在 0.1 到 0.4 之间,那你就可以取一个均值在 0.3、尾巴别太长的 Beta(3, 7)。这等价于预先看了 10 次“历史实验”,虽然简单,但能非常有效地防止小样本时出现“转化率达到 100%”这种离谱结论。
我自己的经验是,先验的“虚拟样本量”最好控制在实际样本量的十分之一到三分之一。这个比例能压住极端抖动,又不会盖过真实数据。等你样本积累到几百上千,先验的影响会自然衰减到可以忽略。
5.3 先验太强的翻车现场
反面的教训我见过不少,典型的翻车是“先验强到数据完全失效”。假设你特别相信硬币公平,取了 Beta(100, 100) 做先验。这时哪怕实测连抛 10 次全部正面,后验也只是 Beta(110, 100),均值 110/210 ≈ 0.524,几乎还在 0.5 附近打转。
同一个数据,在 Beta(2,2) 先验下已经能让均值跑到 0.67,在 Beta(100,100) 下却纹丝不动。差别就在于先验自带了 200 次虚拟实验,10 个真实数据点根本没分量。这个例子提醒我们:越想“保持客观”,越要检查先验的有效样本量,别让历史自信压过眼前事实。
5.4 设先验前的检查清单
到这里可以整理一份我每次设先验前都会过的清单。第一,我有多少真实样本?样本越少,先验的影响越需要被认真审计。第二,我的先验等价于多少次虚拟观测?跟真实样本量比一比,是否合理。第三,如果业务方追问,我能不能用一句话解释清楚先验来自哪里?解释不清楚的先验,通常是拍脑袋拍的,要警惕。第四条是我个人补充的:先验不要设成单点或极窄分布,除非你有铁证,否则后验会变得比真实世界更自信。
6. 什么时候别用贝叶斯参数学习:认清楚边界
6.1 只需要一个数字、且样本量充足时
贝叶斯不是银弹,频率派也不是糟粕。如果你只需要向系统提交一个参数估计值,手里又有海量数据,那么最大似然估计又快又简单,后验分布的“福利”几乎体现不出来。因为大样本下后验会缩成一个极窄的分布,均值和点估计差不了多少,多出来的分布信息基本用不上。这种场景硬上贝叶斯,属于给自己加戏。
6.2 对方只想要一个“结论”时
另一个现实问题是你得向别人解释结果。后验分布对统计背景的人很亲切,对只看报表的业务同事则是负担。我的经验是,汇报时不要直接甩分布图,而是先给后验均值加可信区间,再补一句“当前证据还不够,区间比较宽”。如果对方连区间都嫌多余,那就说明这个场景天生不适合用分布思维,至少不适合把分布摆到台面上。
6.3 高维、非共轭模型的计算代价不可忽视
前面讲到的共轭组合都是手算友好的状态。一旦模型变复杂——参数上百个、层次多、先验后验不同族——解析后验基本不存在,就得请 MCMC 或变分推断这类采样和近似算法。计算量、调参难度、收敛诊断、每次更新要缓存的东西,全都上了一个量级。我的一般原则是:能用共轭就用共轭,不能共轭再考虑近似,近似成本超过收益时就回过头重新审视问题本身,别为了贝叶斯而贝叶斯。
上面三种情况之外,贝叶斯参数学习通常都很值得尝试,尤其是小样本、需要融入先验知识、需要把不确定性带进后续决策的时候。
7. 从单参数到贝叶斯网络:参数学习的两层延伸
7.1 第一层延伸:后验预测分布
学了后验不能只停留在“我知道了参数分布”,真正落地时要看它对未来数据的预测。后验预测分布的定义是:
P(x_new | D) = ∫ P(x_new | θ) · P(θ | D) dθ
可以理解为:对每个可能的 θ,都算一次它对未来数据的预测,然后以 θ 的后验概率为权重做加权平均。跟“先用点估计定死 θ 再预测”相比,后验预测分布把参数的不确定性也折进预测里了,所以它不会表现得过度自信。
回到抛硬币的例子。Beta(9,5) 后验下,下一次正面朝上的预测概率是 (a+s)/(a+b+n) = 9/14 ≈ 0.643,而不是拿点估计 0.7 去算。这就是参数不确定度在预测里的自然折扣。做实验评估、转化率测算时,这种折扣尤其重要——它帮你避免在小样本里早早下结论。
7.2 第二层延伸:贝叶斯网络中的参数学习
很多资料谈“贝叶斯参数学习”,实际场景是贝叶斯网络的结构已知、但条件概率表未知。这时候做的事情和前面完全同构,只是把单个参数换成了多个节点的参数组合。
如果某个节点有 k 个状态,其父节点组合确定了某个条件概率分布,那么给每个状态配一个狄利克雷先验 Dir(α₁, ..., α_k),观测数据统计出各状态数量 n₁, ..., n_k,后验就直接是:
Dir(α₁ + n₁, ..., α_k + n_k)
每一个条件概率表都独立地做这样一组更新。你会发现,这就是第 3 节那张速查表里“多项式 + 狄利克雷”那一行的实际应用。掌握了单参数的 Beta 更新,再往上理解贝叶斯网络的参数学习,差的只是一个“把每个条件当作独立小问题”的意识。结构化、可分解,是贝叶斯网络参数学习工程上能落地的根本原因。
再往外走,还有层次贝叶斯、模型选择、在线推断等方向,但它们的核心都离不开这张图景:先验进入,数据检验,后验输出,再作为下一轮的先验。这是我理解贝叶斯参数学习最顺手的心智模型。
7.3 我自己的一点实操心得
最后分享一个经验。早期我总想把先验设得越弱越好,觉得这样才“客观”;后来发现,弱先验在样本量只有十几个的场景下救不了场,后验照样可能被一两个离群点带偏。现在我倾向于给每个参数都配一个弱信息先验,并且把“先验等价于多少虚拟样本”写进分析文档里,逼自己说清楚每个数字的来源。
如果你正在处理小样本的转化率、留存率、点击率这类问题,建议先拿 Beta 二项这套流程跑一遍,把每次更新的均值、区间画成图,你会很直观地看到信念一步步收敛的过程。那感觉跟看一个新人分析师慢慢变成老手的过程有点像——不是一步到位,而是每一次数据都在修正认知。这就是贝叶斯参数学习最迷人的地方。