☰
PRML中文版精读:贝叶斯线性回归与过拟合复现指南
2026/10/15 8:03:49 网站建设 项目流程

简介:《模式识别与机器学习》(PRML)中文版PDF是机器学习领域的经典教材,由Chris Bishop撰写,适合系统学习概率模型、贝叶斯推断与模式识别基础的学生、研究者及工程师。书中从多项式曲线拟合、概率论、概率密度讲起,逐步覆盖期望与协方差、贝叶斯概率、高斯分布、贝叶斯曲线拟合、模型选择、维度灾难、决策论、信息论等核心主题;同时包含最小化错误分类率、期望损失、拒绝选项、相对熵与互信息等细化内容,并以贝叶斯视角重新审视回归问题,帮助读者建立从数学原理到算法实践的完整认知。压缩包内为1个PDF文件,大小11.56MB,便于按章节翻阅与批注;目前已有348人学习下载。此版本含完整目录导航,适合作为课程参考书、备考复习或案头工具书,长期研读。

1. PRML 中文版是什么,和花书有什么关系,谁需要啃这本老书

在一些资源站里,经常能看到“PRML模式识别和机器学习-Chinese-Edition花书中文版1”这样的打包标题。第一眼很容易把 PRML 当成花书的中文版,其实两本书的定位完全不同。PRML 是概率视角下的机器学习经典,书里几乎每个方法都从贝叶斯公式出发;花书是深度学习的另一本经典,名字被资源打包的人硬塞在一起,多半是为了增加搜索命中。真正值得花时间的,是前者中文版里那套怎么把线性模型、高斯分布和不确定性揉到一起的思考方式。读者里面,准备算法面试的、想从调包转向推导的、需要给模型输出一个可靠置信度的人,都能从这本书里拿到硬通货。

2. 动手读 PRML 之前,先把概率论和矩阵求导的骨架搭起来

PRML 不是一本零基础书,中译本也默认读者已经学过概率统计和线性代数。直接读正文,很多人会在第三章的贝叶斯线性回归里被积分和矩阵符号劝退。我的做法是:读每一章之前先花半天把手边几个基础等式推熟,而不是系统重学一门课。下面这组骨架,覆盖了从第一章多项式拟合到第九章混合模型的绝大多数公式推导。

2.1 概率论:必须亲手推一遍的 6 个等式

PRML 通篇就干一件事:把现实场景翻译成概率模型,然后做推断或决策。所有推断都压在这几个等式上。

第一个是贝叶斯定理:p(Y|X) = p(X|Y)p(Y) / p(X),分母 p(X) 是所有可能原因的积分或求和。这本书里“后验 ∝ 似然 × 先验”往往只写分子,分母当成归一化常数。如果你只记住分子,后面做数值计算很容易把后验密度越乘越大。

第二个是乘积规则:p(X,Y)=p(Y|X)p(X),反过来也成立。第三个是边缘化:p(X)=∫p(X,Y)dY。贝叶斯定理的分母就是对分子做边缘化。这三条在第一章多项式拟合里就全部出现。

第四个是条件独立:p(X,Y|Z)=p(X|Z)p(Y|Z)。意思是已知 Z 后 X 和 Y 不再互相影响。这是朴素贝叶斯和图模型里反复用的假设。

第五个是高斯分布乘积。这个比前面更难,但在贝叶斯线性回归中是核心。两个关于同一变量 x 的高斯密度相乘,结果正比于另一个高斯密度:

N(x|a,A) N(x|b,B) ∝ N(x | (A^{-1}+B^{-1})^{-1}(A^{-1}a+B^{-1}b), (A^{-1}+B^{-1})^{-1})

这里 A、B 是协方差矩阵,a、b 是均值向量。这个公式能让你不翻书就写出后验均值和后验协方差。

第六个是矩阵求导链式法则在概率里的对应,说白了就是对数似然对参数求导,这个在下一小节单独说。

这些公式不建议只看。我一般会拿一张 A4 纸,合上书把“乘法规则 → 贝叶斯 → 边缘化 → 高斯乘积”这条链从第一性原理推一遍。只推一遍不够,至少推三遍:第一次看着公式抄,第二次合上书写步骤,第三次尝试给每个步骤加一句“这一步在书里哪一节出现过”。这个过程能帮你把模糊的直觉变成可复用的推导路径。

2.2 矩阵求导:三个必会结论和一套验证习惯

PRML 的推导风格是用向量和矩阵写目标函数,然后对 w 求导置零。这一板斧从线性模型到相关向量机都是适用的,只要记住三个结论就能应付大部分推导。

第一个是线性项求导:对 w^T φ 求导得到 φ。这个结论是基础,在线性回归的目标函数里反复出现。

第二个是最小二乘目标求导。对 (t - Φw)^T (t - Φw) 关于 w 求导,结果是 -2Φ^T(t - Φw)。设为零就得到正规方程,这个方法贯穿前两章。

第三个是二次型求导:对 (x-μ)^T Σ^{-1}(x-μ) 关于 μ 求导,结果是 2Σ^{-1}(x-μ),注意符号方向。如果 Σ 是对称的正定协方差,这个结论可以直接用。

这三个结论看起来简单,但推导时最容易出的问题是维度。导数结果的维度必须与分母的变量一致。w 是 D 维,Φ^T(t-Φw) 是 D 维,这本身就是一次维度校验。如果推导出来一个 D×D 的矩阵,大概率是在求导过程中把转置写错了。

为了不纸上谈兵,我习惯用符号计算快速验证。下面的代码用 sympy 验证对称矩阵下二次型求导等于 2Ax。

import sympy as sp # 2x2 对称矩阵 A,向量 x x1, x2 = sp.symbols('x1 x2') A11, A12, A22 = sp.symbols('A11 A12 A22', real=True) A = sp.Matrix([[A11, A12], [A12, A22]]) x = sp.Matrix([x1, x2]) # 标量二次型 f = (x.T * A * x)[0, 0] # 逐元素求导 grad = sp.Matrix([sp.diff(f, x1), sp.diff(f, x2)]) # 理论值:2*A*x(因为 A 对称) theo = 2 * A * x # 化简差,结果为零矩阵就代表验证通过 sp.simplify(grad - theo)

这里的关键点有三个。A 必须显式声明为对称,代码里定义 A12 同时出现在 (0,1) 和 (1,0) 位置,正好让 A 对称。f 取 [0,0] 是因为矩阵乘法得到一个 1×1 矩阵,sympy 里需要取出这个标量。sp.diff 对向量里的每个元素分别求导,最后可以把 grad-theo 化简成零矩阵。如果不加 real=True 的符号声明,sympy 可能不认为某些化简成立。

这套验证习惯的工程价值在于:PRML 中文版里矩阵公式偶有排版缩排甚至错误,用符号计算验证一遍,等于给自己做了一份勘误表。我读第三章时把遇到的矩阵求导公式全部重算了一遍,之后再看后面几章的推导就不怕了。

3. 从线性回归到贝叶斯线性回归:用 30 行代码把 PRML 的公式链跑通

PRML 第三章的核心不是教你调线性回归,而是把“给一个点预测换成给一个分布预测”这个思路讲透。我接触过不少做算法的同学,能用 sklearn 调出回归模型,但一问正则化系数从哪来、为什么这样定,就说不清楚。原因大都是只看了黑匣子 API,没有把公式链走一遍。这一章用一个小数据集把最大似然和贝叶斯后验都写出来。

3.1 符号对照表:书里的 w、Φ、α、β 对应到代码里是什么

动手写代码之前,先把书里的符号和代码变量对应起来。表里这一套就是后面公式链的地图。

PRML 符号含义代码变量
φ(x)基函数映射,把原始 x 变成特征向量make_features 的返回值
Φ设计矩阵,每一行是一个样本的基函数向量Phi
t观测目标值t
α权重先验精度,是方差的倒数alpha
β噪声精度,1/β 是噪声方差beta
S_N^{-1}后验协方差的逆,也叫后验精度矩阵S_inv
m_N后验均值m_N

为什么要用精度而不是方差?因为 PRML 里高斯分布为了推导简洁多用精度参数。精度大意味着分布窄、确定性高。你可以把 alpha 理解为对权重的一坨约束:alpha 越大,权重越不敢离开 0;beta 越大,说明观测噪声越小,模型越信任数据。

3.2 最小闭环:生成数据、最大似然解、贝叶斯后验一次跑通

下面的代码完全用 numpy 实现,不碰 sklearn,目的是让你亲手写出 PRML 第三章的公式链。我把步骤拆成四步:生成数据、构造基函数、最大似然解、贝叶斯后验,再顺带算预测方差。

import numpy as np def make_features(x, M): # 多项式基函数:1, x, x^2, ..., x^M return np.column_stack([x**m for m in range(M+1)]) # 固定随机种子,结果可复现 rng = np.random.default_rng(42) N = 10 x = np.linspace(0, 1, N) t = np.sin(2 * np.pi * x) + rng.normal(0, 0.2, N) M = 3 Phi = make_features(x, M) # 最大似然解:w = (Phi^T Phi)^-1 Phi^T t w_ml = np.linalg.pinv(Phi) @ t print("MLE weights:", w_ml) # 贝叶斯线性回归 alpha = 0.1 # 先验强度,越大权重越接近零 beta = 25.0 # 噪声精度,1/beta 是噪声方差 S_inv = alpha * np.eye(M+1) + beta * Phi.T @ Phi m_N = beta * np.linalg.solve(S_inv, Phi.T @ t) print("Bayes posterior mean:", m_N) # 在测试点上做预测,先只算均值 x_test = np.linspace(0, 1, 100) Phi_test = make_features(x_test, M) pred_mean = Phi_test @ m_N # 后验预测方差:1/beta + phi(x)^T S_N^-1 phi(x) S_N = np.linalg.inv(S_inv) ent = Phi_test @ S_N pred_var = 1.0/beta + np.sum(ent * Phi_test, axis=1) pred_std = np.sqrt(pred_var)

先说数据生成:我选了 N=10 个点,目标函数是 sin(2πx),噪声标准差 0.2。这是模仿 PRML 第一章的经典数据,这个噪声水平会带来明显的过拟合,方便你看到贝叶斯解和最大似然解的区别。

生成特征时用多项式基函数,M=3 代表最高次项是三次。注意这里没有做标准化,M 不太大的时候不会太危险。如果你换成 M=9,设计矩阵的条件数会很大,所以后面我统一只用 pinv 或 solve,尽量避免显式求逆。最大似然解用 np.linalg.pinv 而不是 inv,原因就在于设计矩阵可能接近奇异,伪逆更稳定。

贝叶斯部分的后验公式是 S_inv = αI + βΦ^T Φ,m_N = β·S_inv^{-1}·Φ^T t。这里用了 np.linalg.solve 而不是先求逆再乘,避免数值误差,速度也快。alpha 和 beta 是两个人工设定的超参。当 alpha 很小时,先验很弱,后验均值会接近最大似然;当 beta 很大时,说明观测噪声小,模型会不惜过拟合去穿过每个点。

预测方差那段有两处需要注意。一是这个方差由两部分组成:第一部分 1/β 是观测噪声,第二部分是参数不确定性。当你远离训练数据时,第二项会变大,这是贝叶斯和点估计的本质区别。二是求和式的写法 np.sum(ent * Phi_test, axis=1) 等价于对每个测试点计算 φ(x)^T S_N φ(x),但避免了显式构造全部二次型矩阵,内存更友好。

注意:如果 alpha 和 beta 的量级差太多,建议先把 beta 估计为残差方差的倒数,再回头调 alpha。这套代码跑完,把 alpha 从 0.0001 调到 10,观察后验均值如何被压缩向零。这个观察比任何公式都直观:alpha 越大,正则化越强,系数越小。

4. 复现 PRML 第一章那幅过拟合图:模型阶数、误差曲线和正则化的关系

PRML 第一章的过拟合图是很多机器学习初学者第一次看见“过拟合”长什么样。中文版里那几条正弦曲线在数据点中间穿来穿去,高次曲线在端点处翘上天。复现这张图的意义不只是怀旧,而是能用数据把三个结论钉死:训练误差一定随阶数下降、测试误差 U 形、高次项系数会爆炸。

4.1 画图实验:为什么固定随机种子才能复现书上的紫色曲线

先说结论:PRML 的原始插图不是随便跑出来的。它固定了一个随机种子,噪声标准差和样本点数也是一组特定取值。中文版书页上不会写这个参数,所以你直接换一种噪声,曲线形态会有细微差异,但“高次项端点翘起”的大趋势还在。复现的时候我固定用 default_rng(0),噪声标准差 0.3,N 取 10。

import numpy as np import matplotlib.pyplot as plt rng = np.random.default_rng(0) N = 10 x = np.linspace(0, 1, N) t = np.sin(2 * np.pi * x) + rng.normal(0, 0.3, N) def poly_fit(x, t, M): Phi = np.column_stack([x**m for m in range(M+1)]) # 伪逆能处理高次设计矩阵的近奇异问题 w = np.linalg.pinv(Phi) @ t return w M_list = [0, 1, 3, 9] xs = np.linspace(0, 1, 200) for M in M_list: w = poly_fit(x, t, M) Phis = np.column_stack([xs**m for m in range(M+1)]) pred = Phis @ w plt.plot(xs, pred, label=f"M={M}") if M == 9: print("M=9 的权重:", w) plt.scatter(x, t, marker='o') plt.legend() plt.show()

这段代码在画完四根拟合线后,M=9 的权向量会被打印出来。你会发现它的绝对值动辄上百,而 M=3 的权重都接近个位数。这就是系数爆炸的直接证据。为什么伪逆在这里比 inv 可靠?因为 x 的幂次相差巨大,设计矩阵列之间的尺度天差地别,直接求逆容易数值溢出,伪逆会把奇异值截断掉。

不过,光看曲线判断过拟合并不严谨。曲线在端点翘起确实暗示了过拟合,但更客观的标准是测试误差。PRML 第一章后面那张误差曲线才是核心证据。

4.2 误差曲线:训练误差单调下降,测试误差为什么是 U 形

把 M 从 0 遍历到 9,分别在同样生成的训练集和另一个测试集上算均方根误差(RMS)。这样你就把书里一张图变成了自己能读的数据表。

def rms(t_true, t_pred): # 均方根误差,误差低说明拟合好 return np.sqrt(np.mean((t_true - t_pred)**2)) # 独立生成测试集,固定另一个随机种子 rng_test = np.random.default_rng(100) x_test = np.linspace(0, 1, 100) t_test = np.sin(2 * np.pi * x_test) + rng_test.normal(0, 0.3, 100) print("M train_err test_err") for M in range(0, 10): w = poly_fit(x, t, M) Phi_train = np.column_stack([x**m for m in range(M+1)]) Phi_test = np.column_stack([x_test**m for m in range(M+1)]) pred_train = Phi_train @ w pred_test = Phi_test @ w et = rms(t, pred_train) ee = rms(t_test, pred_test) print(f"{M:<6} {et:<12.3f} {ee:.3f}")

运行这份代码,你会看到训练误差随着 M 增大一路下降,到 M=9 时几乎接近零。测试误差则是另一个故事:从 M=0 开始下降,到 M=3 前后最低,再往后反而上升,形成一条 U 形曲线。这条 U 形就是“过拟合”的数值定义:模型复杂度高到一定程度,它对训练数据记得越精确,对没见过的点预测越差。

这里有两个参数容易陷进去。一是测试集的采样范围也固定在 0 到 1,但测试点的个数和训练点不一样。二是测试集需要另一个随机种子,否则测试集与训练集噪声完全同源,误差曲线会失去意义。实际做实验时,最好把测试点密度、种子都当成超参记录下来,不然换一台机器、换一次运行,曲线的细节就会变动,容易误导自己。

正则化是拯救 M=9 的标准手段。PRML 的目标函数里加一项 λ/2||w||^2,解析解变成 (λI + Φ^T Φ)^{-1}Φ^T t。我用下面这个函数对比不同 λ 下的测试误差。

def ridge_fit(x, t, M, lam): Phi = np.column_stack([x**m for m in range(M+1)]) w = np.linalg.solve(lam * np.eye(M+1) + Phi.T @ Phi, Phi.T @ t) return w M = 9 Phi_train9 = np.column_stack([x**m for m in range(M+1)]) Phi_test9 = np.column_stack([x_test**m for m in range(M+1)]) for lam in [0, 1e-4, 1e-2, 1.0]: w = ridge_fit(x, t, M, lam) pred_test = Phi_test9 @ w print(f"lambda={lam:.1e}, test_err={rms(t_test, pred_test):.3f}")

λ 从 0 增到 1,高次项系数被压回个位数,测试误差也会回落。lambda 在贝叶斯视角下的对应就是 α/β:先验精度与噪声精度的比值。这就是为什么我在调参时先算残差方差估计 beta,再根据 beta 选 alpha,而不是直接瞎试 lambda。

这一章做完,PRML 第一章的前半部分就不再是黑匣子。之后再看“模型选择”和“证据近似”时,会知道书里那些严肃公式对应的就是你刚刚画过的 U 形曲线。

5. PRML 中文版阅读避坑:五条差点让人弃书的踩坑记录

读中文版 PRML 的体验,和读英文原版有很大差异。我见过不少同事刚翻几页就被翻译和排版劝退。下面这五条是我自己走过或者听某开发者、A同学反复抱怨过的坑,按“现象、原因、解决”写成记录。

5.1 坑一:中文版公式编号和英文版对不上

现象:某天在讨论群里看到有人引用公式(3.86),说这是贝叶斯线性回归的后验分布。我去中文版里找,结果那个位置是另一个公式,数字和内容全对不上。一开始我还以为自己买到了问题版本。

原因:中文版重排了章节和公式编号,同一公式在不同印刷批次里也可能不同。更麻烦的是,翻译术语的变化让搜英文和搜中文的结果看起来像两本书。

解决:不要用公式编号做索引,改用“第三章 3.2 节 后验分布”这种标题路径来定位。做笔记时同时写英文原版编号和中文版章节名,以后自查才找得到。如果你经常和团队讨论,直接用英文版编号加小节名,能省掉很多对不上号的尴尬。

5.2 坑二:后验更新不做归一化,数值越滚越大

现象:在模拟项目X里,我用贝叶斯公式在线更新权重:先验乘似然,得到后验,又把后验当新一轮先验再乘下一批观测。跑了二十轮,所有参数都变成 NaN。

原因:连续空间里的后验分母是积分,不是常数 1。只更新分子,相当于一直在乘概率密度值,密度值的幅度没有上界,连乘很快溢出。

解决:先看问题是否落在共轭模型里。线性高斯模型的后验仍是高斯,直接维护后验精度 S_inv 和均值 m_N 就足够,根本不需要显式计算分母。递推式是 S_inv_new = S_inv_old + β φ(x)φ(x)^T,m_new = S_inv_new^{-1}(S_inv_old m_old + β t φ(x))。写代码前先手推一遍高斯乘积更新式,确认均值精度公式能闭环,再动手实现。这个习惯至少帮我在两个项目里躲过了 NaN 事故。

5.3 坑三:复现经典过拟合图,曲线和书上长得不一样

现象:我参照常见复现代码跑多项式拟合,M=9 曲线确实在端点翘起,但幅度远没有书里夸张;换一个随机种子,测试误差曲线甚至不再是最低点在 M=3 的干净 U 形。

原因:书上插图固定了样本点、噪声标准差和随机种子。复现代码若用你自己的随机源,相当于换了一组不完全相同的数据,当然不会一模一样。小样本下随机波动对误差曲线的影响非常大。

解决:固定 np.random.default_rng(0),样本数 N=10,噪声标准差 0.3,测试集单独用另一个固定种子。在实验记录里明确写下这些参数,之后再跑就稳定了。如果你要拿这张图在团队里演示,一定要把种子写进脚本,否则每次翻页曲线都长得不一样,很容易被质疑结论不稳健。

5.4 坑四:中文版附录缺失,矩阵恒等式找不到出处

现象:推导最小二乘解时想找一个求逆恒等式,中文版附录翻来翻去没找到,后来才发现英文原版的附录里写得明明白白。

原因:中译本为了控制篇幅会裁剪部分附录,初学者对矩阵恒等式不熟悉,被砍掉就好比丢了拐杖。

解决:备一份英文原版附录的 PDF 对照,遇到推导跳步就用符号计算自己验一遍。常见恒等式比如 (A + U V)^{-1} = A^{-1} - A^{-1}U(I + V A^{-1} U)^{-1} V A^{-1},用 sympy 按第 2 章的方式验证一次,然后抄进自己的“手写附录”。这个办法比死记硬背可靠,因为你验证过的公式会在需要时自然浮出来。

5.5 坑五:只读不练,读完整本书什么也没带走

现象:A同学花了三个月把中文版通读一遍,笔记抄了好几本。结果做一个新数据集时还是先从调包开始;问他第一章过拟合讲了什么,能复述,但让他手写一个正则化回归代码却愣住了。

原因:PRML 是动手型教材,公式和插图都是为“做一遍”设计的。只靠眼睛读,迁移到代码的能力很弱,笔记本上抄的是纸面知识,不是模型直觉。

解决:每读完一章至少复现一张图或一个小实验:第一章复现过拟合,第二章画高斯分布形状随均值和方差的变化,第三章跑贝叶斯回归置信带。每个实验注释里写明对应书里的公式,比笔记本身更有用。等面试或项目里需要用方差做判断时,把 notebook 翻出来,直接复制粘贴,比临时翻书快得多。

6. 读完之后怎么用:把 PRML 的贝叶斯框架变成工程建模的检查清单

PRML 给一线工程师最值钱的观念,是“模型输出必须带不确定性”。点预测只能回答结果是什么,后验预测分布能同时回答结果是什么和这个结果有多可信。我在给某跨平台系统做日志异常检测时,把贝叶斯线性回归的预测方差当作一个简单的置信开关:方差小,输出预测值;方差大,说明这个输入落在训练数据覆盖范围的边缘,交给人工复核。就这一个改动,误报率明显下降。

落地只需要一个函数:

def bayes_predict(Phi, m_N, S_N, beta): # 返回预测均值和标准差 mean = Phi @ m_N var = 1.0 / beta + np.sum((Phi @ S_N) * Phi, axis=1) return mean, np.sqrt(var)

这里的每个变量都和第三章代码保持相同:m_N 是后验均值,S_N 是后验协方差,beta 是噪声精度。工程里只要把训练好的参数存成三个 NumPy 数组,新样本来了先做同样的基函数变换,就能在毫秒级得到均值和方差。这套东西比重新训练模型便宜得多。

有了这个习惯,再回头看 PRML 其它章节,很多内容都会自动变成你的工具箱:第二章的高斯分布是方差估计的底子,第四章的证据近似是超参选择的自动化形式,第八章图模型则是把多组置信开关组合在一起。不要试图第一遍就读完,我的教训是每次只带一个真问题去翻一章,把这一章的公式改成代码,再放进工程里试。这样读三遍,每一遍都会从同一本书里读出不同的东西。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询