资讯详情

从抛硬币理解贝叶斯公式、MLE与MAP:参数估计与正则化实战

📅 2026/9/16 1:08:42 | 华诺云谱 👁 阅读
从抛硬币理解贝叶斯公式、MLE与MAP:参数估计与正则化实战
作为一个在机器学习模型优化和算法落地之间反复横跳的工程师我这些年有一个很深的体会最大似然估计MLE、最大后验概率估计MAP和贝叶斯公式这三个概念在教科书里各占一章看似独立大量初学者也习惯把它们当成三个知识点分开背但真正到了做模型、调参数、选损失函数的时候才发现它们本质上是同一条思路在不同约束下的变体。你只要把那条主线抓住了后面这堆公式全都是自然推导出来的根本不需要死记硬背。这篇文章我不打算搞学院派堆积木式的讲法而是想用一个抛硬币的例子把贝叶斯公式、MLE、MAP全部穿起来中间会补上似然函数、先验分布、后验分布、正则化这些绕不开的邻居最后给出一份可以直接跑的 Python 代码和我在实际项目里踩过的坑。适合正在学机器学习基础但被这三个概念反复劝退的人也适合想把自己理解的模型参数训练逻辑重新梳理一遍的从业者。全文不会出现任何需要背的“口诀”你只需要跟着推导走一遍就能理解为什么 MLE 对应着“用数据说话”而 MAP 对应着“用数据加上一点先验偏见说话”。1. 先理解贝叶斯公式的骨架1.1 为什么贝叶斯公式是“认知更新”公式贝叶斯公式长这样P(H|D) P(D|H) × P(H) / P(D)这玩意儿初看就是条件概率的变形好像没什么特别。但从建模角度去品一下它其实描述了一个极其朴素的认知过程你在观察数据 D 之前心里对某个假设 H 有个底这个底叫先验概率 P(H)。然后你看到了数据 D数据告诉你在 H 成立时看到这种数据的可能性有多大这个可能性就是似然 P(D|H)。两者一综合你更新出对 H 的新认识也就是后验概率 P(H|D)。我经常跟同事用这样一个生活化的类比你平时觉得一家街边小店味道好的概率是 20%先验因为你被网红店坑过太多次。后来朋友强烈推荐你决定去试一次结果发现排队的人特别多、菜品卖相也好数据那么你会调整对它“味道好”的判断后验概率会显著高于 20%。这个“调整”的过程就是贝叶斯更新。所以贝叶斯公式的核心价值不在于求一个概率而在于它给了我们一个统一的框架先验 数据 后验。这正好也是所有机器学习的参数估计逻辑。你在训练模型之前心里往往已经有了一些预设网络结构、参数范围、正则化强度然后训练数据会帮你把参数从先验调整到后验。1.2 条件概率与全概率的直觉贝叶斯公式的推导并不复杂它来源于条件概率的定义式P(H|D) P(H ∩ D) / P(D)同时又有 P(D|H) P(H ∩ D) / P(H)所以 P(H ∩ D) P(D|H) × P(H)代入就能得到贝叶斯公式。分母 P(D) 在这里是归一化因子保证左边后验概率加起来等于 1。很多人在工程里不关心 P(D)因为在比较不同假设的后验大小时分母是常数直接约掉。但理解 P(D) 仍然有意义尤其是你碰到贝叶斯模型选择或者需要计算模型证据的时候。P(D) Σ_H P(D|H)P(H)也就是说观察数据在整个假设空间下的平均可能性。它就像一个校准器负责把后验概率按比例缩放让所有假设的后验之和成立。1.3 贝叶斯公式的三种应用套路把贝叶斯公式用到参数估计里基本有三种套路理解了对后面 MLE 和 MAP 的定位特别有帮助。第一种称为后验推断我们把参数 θ 当作随机变量用贝叶斯公式计算完整后验分布 P(θ|D)然后可以去求分布的各种统计量。这种方法信息最全但计算量也最大因为要处理整个分布这就是贝叶斯学派的主场。第二种是最大后验概率估计 MAP既然完整后验分布不好求那我只求让后验概率最大的那个 θ把分布问题退化成一个优化问题这是后验推断的“单点近似”。MAP 的思想非常实用后面我们会细讲。第三种是最大似然估计 MLE干脆更进一步忽略先验认为 P(θ) 是均匀分布或者直接认为参数是一个固定的未知常数然后用最大化 P(D|θ) 的方式来估计 θ。这是频率学派的经典做法也是深度学习中绝大多数损失函数设计的基石。注意MLE 在贝叶斯视角下可以理解为先验退化为均匀分布之后的 MAP这是理解两者关系最优雅的角度也是后面推导的关键。2. 最大似然估计 MLE把“可能性最大化”做到极致2.1 似然函数到底在说啥很多人在初学 MLE 时会对“似然”这个词感到陌生。你把它翻译成大白话就很好懂了似然就是“在给定参数 θ 下我手上这份数据出现的概率”。MLE 做的事情就是反推“既然数据已经出现了那最合理的 θ 应该是让这个出现概率最大化的那个”。这里有一个容易混淆的点P(D|θ) 作为 θ 的函数时叫似然函数写作 L(θ|D)它作为 D 的概率分布时又能对 D 求积分。所以同样是 P(D|θ)横看成岭侧成峰——当 θ 固定、D 变化它是概率分布当 D 固定、θ 变化它是似然函数。MLE 关心的是后者。MLE 的思路本质上遵循一句很朴素的话不要用低概率的参数去解释已经发生的事实。比如你抛一枚硬币 10 次8 次正面朝上你说这枚硬币正面概率是 0.1虽然也不是完全不可能毕竟 0.1^8 × 0.9^2 还是正数但正常人都会觉得这解释太牵强了。MLE 会老老实实地找出最让“8 次正面”这个事实发生的概率 p。这就是 MLE 的朴素哲学。我自己的经验是如果你在面试里被问“什么是最大似然估计”用这个 8 正 2 反的抛硬币例子现场推一遍比背任何定义都管用因为面试官想看到的就是“你能把抽象的数学还原到具体的问题里”。2.2 为什么偏偏要取对数MLE 的目标是最大化 L(θ|D)但实际操作中我们几乎不会直接对 L 求导而是先取对数变成最大化对数似然 log L(θ|D)。原因主要有三个。第一L 通常是大量概率的连乘比如 n 个样本的似然 L(θ|D) Π P(x_i|θ)连乘求导会非常繁琐乘积法则展开到怀疑人生而取对数之后连乘变成连加求导瞬间变成简单的累加。第二概率值往往在 0 到 1 之间多个小于 1 的数连乘后结果会非常小小到甚至可能超出浮点数的有效表示范围导致数值下溢而取对数可以把极小的数拉伸成合理的负数稳定得多。第三对数函数是严格单调递增的所以 log L 取最大值的点和 L 取最大值的点是同一个改变目标函数不改变解。在代码里这一点尤其明显。你用 Python 的numpy.float64去乘 1000 个条件概率结果直接变成 0.0 也不是危言耸听但取对数之后就稳妥许多。很多深度学习框架里的 CrossEntropyLoss本质就是在算负对数似然intuition 上也和 MLE 完全一脉相承。2.3 手推一个经典案例抛硬币回到抛硬币的例子假设我们抛了 n 次其中正面朝上出现了 m 次。设单次正面概率为 p那么似然函数是L(p) p^m × (1-p)^(n-m)取对数之后log L(p) m × log(p) (n-m) × log(1-p)对 p 求导并令导数为零m / p - (n-m) / (1-p) 0解这个方程m × (1-p) (n-m) × pm - mp np - mpm npp m / n结果非常直观用 MLE 估计出来的硬币正面概率就是样本中正面的频率。这个结论看似平凡但它给了我们一个强力的直觉MLE 在小样本情况下的估计结果完全由数据主导如果你只抛了 2 次都是正面MLE 会告诉你 p 1.0也就是硬币 100% 出正面。这显然不合理但这正是 MLE 的局限——它对数据过度自信缺乏“常识”的约束。后面我们引入 MAP 就是来解决这个毛病的。2.4 真正用代码跑一遍 MLE理论推完我们用代码把刚才的过程复现一遍。下面这段代码会随机生成一枚“真实概率为 0.35”的硬币的抛掷结果然后用 MLE 从观测数据中估计正面概率并画出不同样本量下估计值的变化。import numpy as np import matplotlib.pyplot as plt np.random.seed(42) true_p 0.35 n_samples 2000 observations np.random.rand(n_samples) true_p def mle_estimate(obs): return np.mean(obs.astype(float)) sample_sizes [10, 50, 100, 200, 500, 1000, 2000] estimates [mle_estimate(observations[:n]) for n in sample_sizes] plt.figure(figsize(8, 5)) plt.plot(sample_sizes, estimates, markero, labelMLE estimate) plt.axhline(true_p, colorred, linestyle--, labeltrue p0.35) plt.xlabel(number of samples) plt.ylabel(estimated p) plt.title(MLE estimate converges to true p) plt.legend() plt.grid(True) plt.show()跑出来就能看到当样本量很小的时候MLE 的估计值波动非常剧烈可能一下子是 0.5一下子是 0.2随着样本量增大它会逐步逼近真实的 0.35。这就是统计学习里说的“一致性”。但是注意它逼近的速度完全取决于数据量如果样本很少MLE 给出的结果极不可靠。我在实际项目中有一个体会MLE 是深度学习训练的主力军因为它公平、简单、可计算你给多少数据它就学到多少规律。但当数据量不够、或标注噪声很大的时候MLE 很容易过拟合因为它无条件相信数据里的一切包括噪声。这时候就要请出 MAP 了。3. 最大后验概率估计 MAP给估计加一点“先验”的锚3.1 后验分布与 MAP 的定义MAP 的出发点回到贝叶斯公式P(θ|D) P(D|θ) × P(θ) / P(D)由于 P(D) 是常数求后验最大时直接忽略于是θ_MAP argmax_θ log P(D|θ) log P(θ)这里出现了两个关键部分log P(D|θ) 就是对数似然和 MLE 的目标一致而 log P(θ) 是先验的对数。所以说到底MAP 就是在 MLE 的基础上目标函数里多加了一个先验项。如果先验是均匀分布log P(θ) 是一个常数MAP 就退化成 MLE。从数学形态上看这个多出来的先验项天然起到了约束参数范围的作用。你在训练一个深度神经网络时如果把权重初始化为一个很小的随机值并加一个 L2 正则项你其实就是在做一个高斯先验下的 MAP 估计。这一点很多人初学时没想通等想通之后会有一种“原来正则化不是拍脑袋加的”的顿悟感。3.2 从贝叶斯公式推导 MAP 的目标函数我们来推导一下。假设数据 D {x_1, x_2, ..., x_n} 是独立同分布的那么P(D|θ) Π_i P(x_i|θ)于是 MAP 目标写成θ_MAP argmax_θ log( Π_i P(x_i|θ) ) log P(θ) argmax_θ Σ_i log P(x_i|θ) log P(θ)你看这个式子其实非常好理解第一部分是“数据要我往哪走”第二部分是“先验经验拉着我不许乱跑”。这两个力的合力方向决定了最终参数落点。如果把它写成最小化问题常见形式是θ_MAP argmin_θ - Σ_i log P(x_i|θ) - log P(θ)很多机器学习损失函数就是这样来的。比如你在做线性回归时假设噪声服从高斯分布那么 -Σ log P(x_i|θ) 就是 MSE再假设权重服从高斯先验那么 -log P(θ) 就变成 λ × ||θ||²。于是最小化 MSE L2 正则本质上就是高斯似然 高斯先验下的 MAP。这个推导非常优雅建议每个人都亲手写一遍对后面理解正则化选取特别有帮助。3.3 先验怎么选Beta 分布、高斯分布用 MAP 就绕不开先验分布的选择。这里有一个简单但实用的原则先验应该反映你对参数的“合理预期”。如果你完全没概念就选均匀分布如果数据量很大先验的影响会自然减弱如果数据量很小先验就是你拉回正确方向的生命线。拿抛硬币来说如果我们假设硬币是物理世界里常见的那类硬币大概率比较公平也就是正面概率 p 大概率在 0.5 附近。这个“大概率在 0.5 附近”的信念用数学分布描述就适合用 Beta 分布。Beta 分布以两个参数 α 和 β 控制形状当 α β 10 时曲线在 0.5 附近呈现一个钟形表达了“硬币约莫公平但不绝对锁死在 0.5”的先验。Beta 分布还有一个极大的便利它是二项分布似然的共轭先验。换句话说Beta 先验乘以二项似然之后后验仍然是一个 Beta 分布只是参数更新成 α m 和 β (n-m)。这种“先验参数直接加计数”的性质让推导简单到离谱也让我们能直观看到先验强度如何影响估计结果。再看连续参数场景比如线性回归的权重 w我们通常会假设 w 的先验是一个均值为 0、协方差为 λI 的高斯分布。为什么选高斯因为高斯分布在数学上处理起来方便而且它在实数范围内合理既能表达参数靠近零的倾向又没有把参数限制在某个硬区间内。高斯先验在 MAP 里对应 L2 正则拉普拉斯先验对应 L1 正则。实际用哪个取决于你希望参数整体偏小还是希望参数被压缩到稀疏的零上。3.4 代码对比 MLE 与 MAP 在少样本下的差异我们用抛硬币这个场景对比一下少样本时的 MLE 和 MAP。假设先验是 Beta(10, 10)这表示我们相信硬币大概率在 0.5 附近。再假设观测只有 2 次并且全是正面。这时候 MLE 会给出 p 1.0MAP 则会把先验的 0.5 和观测数据融合起来给出一个折中的估计。import numpy as np alpha_prior, beta_prior 10.0, 10.0 # 观测: 2次抛掷1次正面1次反面 m, n 1, 2 # MLE p_mle m / n print(fMLE estimate: p {p_mle:.3f}) # MAP: 后验 Beta(alpha_prior m, beta_prior (n-m)) alpha_post alpha_prior m beta_post beta_prior (n - m) # Beta 分布的最大值点在 (alpha-1) / (alphabeta-2)如果 alpha1 且 beta1 p_map (alpha_post - 1) / (alpha_post beta_post - 2) print(fMAP estimate: p {p_map:.3f})输出会大约是 MLE 0.500因为 m/n 1/2等等这里我写的是 2 次抛掷、1 次正面那 MLE 就是 0.5看不出差异。我们把例子改成 5 次抛掷、4 次正面这样 MLE 0.8而 MAP 会向 0.5 靠拢。import numpy as np alpha_prior, beta_prior 10.0, 10.0 # 观测: 5次抛掷4次正面1次反面 m, n 4, 5 # MLE p_mle m / n print(fMLE estimate: p {p_mle:.3f}) # MAP alpha_post alpha_prior m beta_post beta_prior (n - m) p_map (alpha_post - 1) / (alpha_post beta_post - 2) print(fMAP estimate: p {p_map:.3f})结果大概是 MLE 0.800MAP (104-1)/(104101-2) 13/23 ≈ 0.565。可以看到Bayes/MAP 的估计明显比 MLE 保守没有直接冲到 0.8而是更靠近先验的 0.5这就是先验在起“锚定”作用。初学者往往会震惊于 MAP 在这种场景下“更像正常人”——确实根据 5 次实验就说硬币正面概率 80%这是过度自信了。去年我在公司做一个点击率预估模型的冷启动问题新广告只有几百条点击数据、甚至几十条点击数据纯用频率估计点击率就是个小样本噪声估计器。当时我就是用类似 Beta 先验的方式做了一版“工业级 MAP 点击率估计”效果立竿见影冷启动阶段的排序稳定性和离线 GAUC 都比 MLE 方案好了一大截而且实现起来非常便宜。这就是 MAP 在真实业务里最典型的应用之一。4. MLE 与 MAP 的高频对比和现场选择题4.1 一张表说清 MLE 与 MAP 的不同虽然我们在推导里已经看到MAP 就是 MLE 加了一个先验项但工程选型时还是需要把差异摆在台面上看清楚。对比维度MLEMAP目标函数argmax Σ log P(x_i|θ)argmax Σ log P(x_i|θ) log P(θ)是否引入先验不引入只有数据引入有先验正则对参数的观点参数是固定的未知常数参数是随机变量服从某个分布小样本表现容易过拟合估计剧烈波动更稳先验能拉回合理范围大样本表现渐近无偏且一致通常很好与 MLE 趋同先验影响减弱与正则化关系无内置正则高斯先验L2拉普拉斯先验L1典型应用深度网络损失函数、线性回归最小二乘贝叶斯线性回归、冷启动估计、正则化模型这张表基本覆盖了我在面试候选人时最常考察的几个点。不过你注意一个关键逻辑如果数据量足够大MAP 和 MLE 会越来越接近因为对数似然项的规模随样本数线性增长而先验项是一个固定值最终数据会压过先验。这是所谓的“先验被数据冲淡”也说明了在大数据时代为什么 MLE 依然占据统治地位。4.2 什么时候该用哪个选择 MLE 还是 MAP我个人的判断依据主要看三点。第一点看数据量。数据充足、标注可靠时优先 MLE。它简单、稳定、渐进性质好而且你用深度学习训练大模型时本质上都是 MLE 框架因为没有哪个任务能先验到给几亿参数每个都配一个严格合理的分布。数据稀缺、有强领域知识时MAP 几乎是必然选择。第二点看任务是否对不确定性敏感。如果你只是预测一个点估计MLE 通常够用但如果你需要预测分布、做在线更新、或在贝叶斯优化里评估采集函数那完整后验或至少 MAP 加近似不确定性更合适。第三点看你是否需要正则化。在绝大多数传统机器学习模型里L1/L2 正则项就是 MAP 的先验。如果你只是想要一个“公平”的估计器MLE 就好如果你怀疑特征之间存在大量无意义噪声请果断上带有稀疏先验的 MAP。我记得早年在做推荐系统召回模型时遇到过一个 CTR 特征非常多、但很多特征出现次数极少的场景。全量用 MLE 就会出现“某个特征只出现一次且刚好被点击于是模型认为它点击率 100%”的荒谬现象。后来引入 Bayesian smoothing本质就是给每个特征套一个 Beta 先验做一个 MAP 估计马上解决了冷启动和稀疏特征估计的问题。你要是没见过这种场景可能觉得 MAP 只是“理论上的选项”但真实工程里它就是用得非常频繁。4.3 面试题与工程场景中的判断面试里常出现这样一道题“给定一堆数据你是选 MLE 还是 MAP”说实话这题没有标准答案但面试官想听的是你能否把条件说清楚。我见过的比较好的回答套路是先声明结论取决于数据量和先验置信度然后举一个具体例子比如 10000 条样本下 MLE 和 MAP 差异很小但 10 条样本下 MAP 必不可少最后最好能引申到“MAP 等于 MLE 加正则化”这个洞察再补一句“如果先验选均匀分布两者完全等价”。这样逻辑完整、知识面广基本能让人眼前一亮。工程场景里的判断还要更实际一些。比如你在做 A/B 实验的转化率估计时新版本上线第一天样本很少直接算转化率方差极大等腰砍流量都来不及你如果用 MAP 加上一个“过去 30 天大盘转化率”作为先验第二天就能给出一个相对稳定的早期估计。这种场景下MAP 给的“偏保守但可信”的估计就是业务负责人最需要的信息。相反如果你在训练大语言模型几万亿 token 的数据量面前任何人工先验都显得苍白老老实实用 MLE 式的 next token prediction 就是最优选择。5. 实操心得和常见误区5.1 常见问题速查这些年我看到初学者在 MLE/MAP/Bayes 上踩的坑概括下来基本就下面几类。第一类混淆似然和后验。我经常看到有人把 P(θ|D) 写成“在 θ 下 D 的概率”这是完全相反的方向。判据很简单见到数据 D 之后讨论参数 θ 的分布就必须是后验 P(θ|D)绕不开 P(D|θ) 的只能是似然。第二类忽略分母 P(D)。在比较不同 θ 时分母确实无所谓但如果真的要输出一个概率值比如 P(θ0.5|D)那就不能跳过归一化分母。初学者做 MAP 推到了后验的形式就把分母丢了结果输出一个大于 1 的“概率”这是很常见的低级错误。第三类把 MAP 的估计值当成完整后验。MAP 只给了后验分布最高峰的位置完全不包含不确定性信息。你如果要用后验的方差去衡量置信区间那必须回到真正的贝叶斯后验推断而不是把 MAP 当一个分布去采样。这个混淆在实际模型评估里挺坑的我有一次调试一个在线学习系统就是错把 MAP 的“点估计”当成“后验均值”结果对不确定性估计严重偏差导致探索策略几乎失效。第四类以为先验只能靠人工拍脑袋。其实先验可以从历史数据、业务常识、前序模型输出里来。甚至有一种做法叫经验贝叶斯先兜底用数据估出一个先验再做 MAP。比如在推荐系统里用全量数据统计一个全局点击率分布这就是一种“从数据里学出来的先验”。不要一提先验就觉得是主观的先验也可以很数据驱动。第五类忽略先验的尺度。先验强度直接影响 MAP 估计的偏移方向如果先验选得过于尖锐比如 Beta(1000, 1000)那即使你有 1000 条新数据都掰不过这个先验。这个时候模型对真实数据变化的响应会极慢业界有个词叫“过平滑”。反过来说先验太弱又没有约束效果。先验的强度和样本量之间的关系你必须有意识地去调。5.2 我在实际项目里的使用经验最后分享几个实操层面的经验算是我踩坑之后沉淀下来的“肌肉记忆”。第一在写似然函数前先用一句话把“我假设数据服从什么分布”说清楚。线性回归假设高斯噪声MSE 就是负的高斯对数似然分类问题假设类别服从伯努利/多项分布交叉熵就是负的对数似然。如果你上来就写损失函数不明白背后的概率假设后面调参很容易抓瞎。第二在做 MAP 时不要直接对目标函数做梯度下降最好先从概率图模型的角度把先验分布和似然的积写出来再取对数、再展开。多展开一步你就能少错一个符号。我见过有同事在代码里把 L1 正则写成加权了一个拉普拉斯分布的对数结果符号不对导致整个模型发散排查到凌晨才发现是少了个负号。第三用 MAP 做贝叶斯平滑时先验参数不是随便设定的可以使用矩估计法从历史数据里反推。具体做法是取历史所有样本的均值 μ 和方差 σ²然后解 Beta 分布的两个参数 α 和 β。公式是 α μ × ((μ × (1-μ) / σ²) - 1)β (1-μ) × ((μ × (1-μ) / σ²) - 1)。这个经验公式在点击率、转化率、存活率等场景非常好用可以避免手动调先验的尴尬。第四小样本测试模型时务必把 MLE 和 MAP 的结果同时打印出来对比。如果两者差异巨大说明当前先验影响过强或者样本量太小你需要加倍小心。这个对比不需要额外写复杂代码就调两个函数的事情但对诊断模型稳定性非常有价值。我基本每个新项目上线前都会跑一下这个对比算是自己的习惯。贝叶斯公式给出了认知更新的一般框架MLE 是它“只信数据”的极限状态MAP 是它“先验加数据”的实用折中。我自己在学习这条线时最深的感受是把这三个概念串成一条线远比单独背公式要轻松得多也不容易忘。如果你也被它们绕得头疼不妨拿出笔把抛硬币的例子从头推导一遍再跑一遍代码我相信你会有完全不同的感觉。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。