本文基于 Christopher Bishop 的《Pattern Recognition and Machine Learning》(2006)第一章,结合数学推导与 Python 代码,系统讲解机器学习的核心基础概念。


目录

  1. 引言:什么是模式识别
  2. 多项式曲线拟合
  3. 概率论基础
  4. 频率派 vs 贝叶斯派
  5. 高斯分布与 MLE 推导
  6. 曲线拟合的概率视角
  7. 模型选择
  8. 维度灾难
  9. 决策论
  10. 信息论

1. 引言:什么是模式识别

模式识别(Pattern Recognition)的目标是:从原始数据中自动发现规律,并利用这些规律对新数据做出决策或预测

经典例子是手写数字识别(MNIST)。给定一张 28×28 像素的图像,我们希望机器能判断其表示的数字(0-9)。原始输入是 784 维的像素向量,而输出是 10 个类别之一。

输入空间:x ∈ ℝ^784(像素矩阵展平)
输出空间:y ∈ {0, 1, 2, ..., 9}

直接编写规则(if-else)来描述每个数字的形状是不现实的——数字的书写风格千变万化。机器学习的思路是:从训练数据中自动学习输入到输出的映射

这里引出机器学习的三个核心问题:

问题类型描述例子
监督学习(Supervised)有标注数据,学习 x→y 的映射分类、回归
无监督学习(Unsupervised)无标注数据,发现数据内在结构聚类、密度估计
强化学习(Reinforcement)通过与环境交互获得奖励信号游戏AI、机器人控制

2. 多项式曲线拟合

Bishop 用多项式曲线拟合作为贯穿全书的核心例子,直观呈现机器学习中的核心挑战。

2.1 问题设定与最小二乘法

问题设定:已知 NN 个观测点 {(xn,tn)}n=1N\{(x_n, t_n)\}_{n=1}^N,其中输入 xn[0,1]x_n \in [0,1],目标值 tn=sin(2πxn)+ϵt_n = \sin(2\pi x_n) + \epsilonϵ\epsilon 为高斯噪声。目标是学习一个函数 y(x,w)y(x, \mathbf{w}) 来预测新的 xx 对应的 tt

模型MM 阶多项式:

y(x,w)=j=0Mwjxj=w0+w1x+w2x2++wMxMy(x, \mathbf{w}) = \sum_{j=0}^{M} w_j x^j = w_0 + w_1 x + w_2 x^2 + \cdots + w_M x^M

这是关于参数 w\mathbf{w} 的线性模型(尽管对 xx 是非线性的)。线性模型具有良好的数学性质,可以求得解析解。

误差函数(平方误差)

E(w)=12n=1N[y(xn,w)tn]2E(\mathbf{w}) = \frac{1}{2} \sum_{n=1}^{N} \left[ y(x_n, \mathbf{w}) - t_n \right]^2

前面的 12\frac{1}{2} 是为了求导后消去系数,不影响最优解。几何意义:最小化每个训练点预测值与真实值之差的平方和(竖直方向误差)。

求解 w\mathbf{w}^*

Φ\Phi 为设计矩阵(Design Matrix),其中 Φnj=xnj\Phi_{nj} = x_n^j

Φ=(1x1x12x1M1x2x22x2M1xNxN2xNM)\Phi = \begin{pmatrix} 1 & x_1 & x_1^2 & \cdots & x_1^M \\ 1 & x_2 & x_2^2 & \cdots & x_2^M \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & x_N & x_N^2 & \cdots & x_N^M \end{pmatrix}

则误差函数可以写成矩阵形式:

E(w)=12Φwt2E(\mathbf{w}) = \frac{1}{2} \|\Phi\mathbf{w} - \mathbf{t}\|^2

w\mathbf{w} 求导并令其为零:

Ew=ΦT(Φwt)=0\frac{\partial E}{\partial \mathbf{w}} = \Phi^T(\Phi\mathbf{w} - \mathbf{t}) = 0 w=(ΦTΦ)1ΦTt\Rightarrow \mathbf{w}^* = (\Phi^T\Phi)^{-1}\Phi^T\mathbf{t}

这就是著名的正规方程(Normal Equation)(ΦTΦ)1ΦT(\Phi^T\Phi)^{-1}\Phi^T 称为 Φ\Phi伪逆(Moore-Penrose Pseudoinverse)

Python 实现

python
import numpy as np
import matplotlib.pyplot as plt
 
def polynomial_features(x, degree):
    """构建多项式设计矩阵"""
    return np.array([[xi**j for j in range(degree + 1)] for xi in x])
 
def fit_polynomial(x_train, t_train, degree):
    """用最小二乘法拟合多项式"""
    Phi = polynomial_features(x_train, degree)
    # 正规方程: w = (Phi^T Phi)^{-1} Phi^T t
    w = np.linalg.lstsq(Phi, t_train, rcond=None)[0]
    return w
 
def predict(x, w):
    degree = len(w) - 1
    Phi = polynomial_features(x, degree)
    return Phi @ w
 
# 生成数据
np.random.seed(42)
N = 10
x_train = np.linspace(0, 1, N)
t_train = np.sin(2 * np.pi * x_train) + np.random.normal(0, 0.3, N)
x_test  = np.linspace(0, 1, 200)
t_true  = np.sin(2 * np.pi * x_test)
 
# 绘制不同阶数的拟合结果
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
for ax, M in zip(axes.flat, [0, 1, 3, 9]):
    w = fit_polynomial(x_train, t_train, M)
    y_pred = predict(x_test, w)
    ax.scatter(x_train, t_train, color='blue', s=50, label='Training data')
    ax.plot(x_test, t_true, 'g-', label='True: sin(2πx)')
    ax.plot(x_test, y_pred, 'r-', label=f'M={M}')
    ax.set_ylim(-1.5, 1.5)
    ax.legend()
    ax.set_title(f'Polynomial Degree M={M}')
plt.tight_layout()
plt.savefig('polynomial_fitting.png', dpi=150)
plt.show()

2.2 模型复杂度与过拟合

Bishop 的实验(N=10N=10 个训练点)呈现了一个关键现象:

阶数 MM现象训练误差测试误差
M=0M=0(常数)欠拟合,无法捕捉数据变化
M=1M=1(线性)欠拟合,太简单
M=3M=3最优,良好泛化
M=9M=9过拟合,完美通过每个训练点,但测试误差极大≈0极大

过拟合的本质M=9M=9 的多项式有 10 个自由参数,恰好可以精确穿过 10 个训练点,但系数的量级极大(如 w9=125201w_9 = 125201),导致在训练点之间产生剧烈震荡。这是模型死记硬背了训练数据的噪声,而不是学习到了底层规律。

根均方误差(RMSE)

ERMS=2E(w)NE_{\text{RMS}} = \sqrt{\frac{2E(\mathbf{w}^*)}{N}}

用 RMSE 而非总误差,是为了在不同大小数据集之间公平比较。

python
def rms_error(y_pred, y_true):
    return np.sqrt(np.mean((y_pred - y_true)**2))
 
# 计算不同M的训练和测试误差
degrees = range(10)
train_errors, test_errors = [], []
x_test_pts = np.linspace(0, 1, 100)
t_test_pts = np.sin(2 * np.pi * x_test_pts) + np.random.normal(0, 0.3, 100)
 
for M in degrees:
    w = fit_polynomial(x_train, t_train, M)
    train_errors.append(rms_error(predict(x_train, w), t_train))
    test_errors.append(rms_error(predict(x_test_pts, w), t_test_pts))
 
plt.figure(figsize=(8, 5))
plt.plot(degrees, train_errors, 'b-o', label='Training')
plt.plot(degrees, test_errors, 'r-o', label='Test')
plt.xlabel('Polynomial Degree M')
plt.ylabel('RMS Error')
plt.legend()
plt.title('Train vs Test Error vs Model Complexity')
plt.savefig('bias_variance.png', dpi=150)
plt.show()

数据量与过拟合的关系:对于固定复杂度的模型,训练数据越多,过拟合越不严重。直觉上,数据越多,模型就越难"背下"每一个点。这引出一个重要观点:过拟合是一个关于相对于数据集大小而言模型复杂度过高的问题

2.3 正则化:抑制过拟合

正则化通过在误差函数中加入惩罚项来约束参数的大小:

E~(w)=12n=1N[y(xn,w)tn]2+λ2w2\tilde{E}(\mathbf{w}) = \frac{1}{2} \sum_{n=1}^{N} [y(x_n, \mathbf{w}) - t_n]^2 + \frac{\lambda}{2}\|\mathbf{w}\|^2

其中 w2=wTw=jwj2\|\mathbf{w}\|^2 = \mathbf{w}^T\mathbf{w} = \sum_j w_j^2λ\lambda正则化系数,控制正则化的强度。

这种 L2 正则化在统计学中称为 Ridge Regression(岭回归),在神经网络中称为 Weight Decay(权重衰减)

求解带正则化的正规方程

E~w=ΦT(Φwt)+λw=0\frac{\partial \tilde{E}}{\partial \mathbf{w}} = \Phi^T(\Phi\mathbf{w} - \mathbf{t}) + \lambda\mathbf{w} = 0 (ΦTΦ+λI)w=ΦTt\Rightarrow (\Phi^T\Phi + \lambda I)\mathbf{w}^* = \Phi^T\mathbf{t} w=(ΦTΦ+λI)1ΦTt\Rightarrow \mathbf{w}^* = (\Phi^T\Phi + \lambda I)^{-1}\Phi^T\mathbf{t}

注意 λI\lambda I 的加入保证了矩阵可逆(即使 ΦTΦ\Phi^T\Phi 奇异)。

正则化系数 λ\lambda 的影响

python
def fit_polynomial_regularized(x_train, t_train, degree, lam):
    """带L2正则化的多项式拟合"""
    Phi = polynomial_features(x_train, degree)
    N, M_plus1 = Phi.shape
    # (Phi^T Phi + lambda * I) w = Phi^T t
    A = Phi.T @ Phi + lam * np.eye(M_plus1)
    b = Phi.T @ t_train
    w = np.linalg.solve(A, b)
    return w
 
# 固定M=9,比较不同lambda
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
lambdas = [np.exp(-18), np.exp(-3), np.exp(0)]
labels  = ['ln λ = -18 (适中)', 'ln λ = -3', 'ln λ = 0 (过强)']
 
for ax, lam, label in zip(axes, lambdas, labels):
    w = fit_polynomial_regularized(x_train, t_train, 9, lam)
    y_pred = predict(x_test, w)
    ax.scatter(x_train, t_train, color='blue', s=50)
    ax.plot(x_test, t_true, 'g-', label='True')
    ax.plot(x_test, np.clip(y_pred, -1.5, 1.5), 'r-', label='Fitted')
    ax.set_ylim(-1.5, 1.5)
    ax.set_title(label)
    ax.legend()
plt.suptitle('M=9 多项式正则化效果 (Regularization Effect)')
plt.tight_layout()
plt.show()

关键洞察:正则化其实是在引入先验知识(系数不应太大)。从贝叶斯视角看,λw2\lambda\|\mathbf{w}\|^2 对应于参数的高斯先验,这一点将在后面详细阐述。


3. 概率论基础

不确定性是模式识别的核心挑战,来源有二:

  1. 测量噪声:数据本身含有随机扰动
  2. 有限数据集:样本量有限,无法完全描述总体

概率论提供了一套一致性的框架来量化和操控不确定性。

3.1 概率的两大规则

Bishop 用一个直观的箱子水果例子引出概率的两条基本规则:

B{r,b}B \in \{r, b\} 为选择的箱子,F{a,o}F \in \{a, o\} 为选到的水果。

联合概率(Joint Probability)

p(X=xi,Y=yj)=nijNp(X=x_i, Y=y_j) = \frac{n_{ij}}{N}

边缘化(Sum Rule / Marginalization)

p(X)=Yp(X,Y)\boxed{p(X) = \sum_Y p(X, Y)}

物理含义:对不关心的变量 YY 求和,得到 XX 的边缘分布。

乘法规则(Product Rule)

p(X,Y)=p(YX)p(X)\boxed{p(X, Y) = p(Y|X) \cdot p(X)}

其中 p(YX)p(Y|X)条件概率,表示在已知 XX 的条件下 YY 的概率。

箱子例子的计算

p(F=a)=p(F=aB=r)p(B=r)+p(F=aB=b)p(B=b)p(F=a) = p(F=a|B=r)p(B=r) + p(F=a|B=b)p(B=b) =14410+34610=110+1840=1120= \frac{1}{4} \cdot \frac{4}{10} + \frac{3}{4} \cdot \frac{6}{10} = \frac{1}{10} + \frac{18}{40} = \frac{11}{20}

3.2 贝叶斯定理

从乘法规则出发,利用 p(X,Y)=p(Y,X)p(X,Y) = p(Y,X)

p(YX)p(X)=p(XY)p(Y)p(Y|X) \cdot p(X) = p(X|Y) \cdot p(Y)

整理得到贝叶斯定理(Bayes' Theorem)

p(YX)=p(XY)p(Y)p(X)\boxed{p(Y|X) = \frac{p(X|Y) \cdot p(Y)}{p(X)}}

其中:

箱子例子反向推断:已知拿到橙子,问来自红箱的概率?

p(B=rF=o)=p(F=oB=r)p(B=r)p(F=o)=34410920=23p(B=r|F=o) = \frac{p(F=o|B=r) \cdot p(B=r)}{p(F=o)} = \frac{\frac{3}{4} \cdot \frac{4}{10}}{\frac{9}{20}} = \frac{2}{3}

这是逆向推理的典型应用:虽然先验中红箱概率(4/10)小于蓝箱(6/10),但橙子更可能来自红箱(红箱 3/4 vs 蓝箱 1/4),所以后验概率反转为 2/3。

python
# 贝叶斯定理的Python验证
p_B_r = 0.4   # P(选红箱)
p_B_b = 0.6   # P(选蓝箱)
 
# 条件概率 P(水果|箱子)
p_orange_given_red  = 3/4
p_orange_given_blue = 1/4
 
# 边缘概率 P(橙子)  —— 全概率公式
p_orange = p_orange_given_red * p_B_r + p_orange_given_blue * p_B_b
print(f"P(橙子) = {p_orange:.4f}")   # 9/20 = 0.45
 
# 贝叶斯定理
p_red_given_orange = p_orange_given_red * p_B_r / p_orange
print(f"P(红箱|橙子) = {p_red_given_orange:.4f}")   # 2/3 ≈ 0.6667

独立性:若 p(X,Y)=p(X)p(Y)p(X, Y) = p(X)p(Y),则 XXYY 统计独立,此时 p(YX)=p(Y)p(Y|X) = p(Y),即知道 XX 不提供关于 YY 的任何信息。

3.3 连续概率密度

对于连续随机变量 xx,若 xx 落在区间 (x,x+δx)(x, x+\delta x) 的概率为 p(x)δxp(x)\delta xδx0\delta x \to 0),则 p(x)p(x) 称为概率密度函数(PDF, Probability Density Function)

概率密度的性质:

p(x)0,+p(x)dx=1p(x) \geq 0, \quad \int_{-\infty}^{+\infty} p(x)\,dx = 1 P(x(a,b))=abp(x)dxP(x \in (a, b)) = \int_a^b p(x)\,dx

注意:p(x)p(x) 本身不是概率,它可以大于 1(只要积分为 1)。

变量变换:若 x=g(y)x = g(y),则:

py(y)=px(x)dxdy=px(g(y))g(y)p_y(y) = p_x(x) \left|\frac{dx}{dy}\right| = p_x(g(y))|g'(y)|

这说明概率密度不是简单代入变换的,需要乘以雅可比行列式。这也意味着概率密度的最大值点(众数)在非线性变换下会改变位置。

累积分布函数(CDF)P(z)=zp(x)dxP(z) = \int_{-\infty}^z p(x)\,dx,满足 p(x)=dPdxp(x) = \frac{dP}{dx}

连续情形的加法规则和乘法规则

p(x)=p(x,y)dy(加法规则)p(x) = \int p(x, y)\,dy \quad \text{(加法规则)} p(x,y)=p(yx)p(x)(乘法规则)p(x, y) = p(y|x)\,p(x) \quad \text{(乘法规则)}

3.4 期望与协方差

期望(Expectation)

E[f]=f(x)p(x)dx(连续)\mathbb{E}[f] = \int f(x)\,p(x)\,dx \quad \text{(连续)} E[f]=xf(x)p(x)(离散)\mathbb{E}[f] = \sum_x f(x)\,p(x) \quad \text{(离散)}

用有限样本近似期望:

E[f]1Nn=1Nf(xn)\mathbb{E}[f] \approx \frac{1}{N}\sum_{n=1}^N f(x_n)

条件期望

Ex[fy]=f(x)p(xy)dx\mathbb{E}_x[f|y] = \int f(x)\,p(x|y)\,dx

方差(Variance)

Var[f]=E[(fE[f])2]=E[f2]E[f]2\text{Var}[f] = \mathbb{E}\left[(f - \mathbb{E}[f])^2\right] = \mathbb{E}[f^2] - \mathbb{E}[f]^2

协方差(Covariance):衡量两个变量的线性相关程度:

Cov[x,y]=Ex,y[(xE[x])(yE[y])]=E[xy]E[x]E[y]\text{Cov}[x, y] = \mathbb{E}_{x,y}\left[(x - \mathbb{E}[x])(y - \mathbb{E}[y])\right] = \mathbb{E}[xy] - \mathbb{E}[x]\mathbb{E}[y]

对于两个独立随机变量,Cov[x,y]=0\text{Cov}[x,y] = 0(但反之不成立)。

协方差矩阵:对于随机向量 xRd\mathbf{x} \in \mathbb{R}^d

Cov[x]=E[(xE[x])(xE[x])T]=E[xxT]E[x]E[x]T\text{Cov}[\mathbf{x}] = \mathbb{E}\left[(\mathbf{x} - \mathbb{E}[\mathbf{x}])(\mathbf{x} - \mathbb{E}[\mathbf{x}])^T\right] = \mathbb{E}[\mathbf{x}\mathbf{x}^T] - \mathbb{E}[\mathbf{x}]\mathbb{E}[\mathbf{x}]^T

这是一个 d×dd \times d 对称正半定矩阵。


4. 频率派 vs 贝叶斯派

机器学习中最重要的哲学分歧之一,直接导致两类不同的算法体系。

符号约定

频率派(Frequentist)

核心观点:参数 θ\theta未知的固定常数,数据 XX 是随机的。

方法:最大似然估计(MLE, Maximum Likelihood Estimation)

θMLE=argmaxθlogp(Xθ)=argmaxθi=1Nlogp(xiθ)\theta_{\text{MLE}} = \arg\max_\theta \log p(X|\theta) = \arg\max_\theta \sum_{i=1}^N \log p(x_i|\theta)

之所以取对数:① 数值稳定性(乘积变求和,避免下溢);② 数学上等价(对数是严格单调增函数)。

核心工具:最优化(Optimization)

MLE 导出的算法:线性回归(最小二乘)、逻辑回归、SVM、神经网络(标准形式)等。

贝叶斯派(Bayesian)

核心观点:参数 θ\theta随机变量,服从先验分布 θp(θ)\theta \sim p(\theta)

贝叶斯定理应用

p(θX)=p(Xθ)p(θ)p(X)p(Xθ)p(θ)p(\theta|X) = \frac{p(X|\theta) \cdot p(\theta)}{p(X)} \propto p(X|\theta) \cdot p(\theta)

最大后验估计(MAP, Maximum A Posteriori)

θMAP=argmaxθp(θX)=argmaxθ[logp(Xθ)+logp(θ)]\theta_{\text{MAP}} = \arg\max_\theta p(\theta|X) = \arg\max_\theta \left[\log p(X|\theta) + \log p(\theta)\right]

MAP = MLE + 先验的约束(取对数后变加法)。

贝叶斯预测(Bayesian Prediction)

p(x~X)=p(x~θ)p(θX)dθp(\tilde{x}|X) = \int p(\tilde{x}|\theta)\, p(\theta|X)\, d\theta

这是对所有可能的 θ\theta 进行加权平均(权重为后验概率),而不是只用一个点估计。

核心工具:积分(Integration)

由于分母 p(X)=p(Xθ)p(θ)dθp(X) = \int p(X|\theta)p(\theta)d\theta 通常难以解析计算,需要近似方法:

对比总结

特性频率派贝叶斯派
参数 θ\theta固定常数随机变量
核心操作最优化积分
数据的角色随机变量固定观测
不确定性表达置信区间后验分布
典型算法SVM, 标准神经网络贝叶斯网络, GP, LDA
先验的使用核心要素

5. 高斯分布与 MLE 推导

高斯(正态)分布是机器学习中最重要的分布,其地位源于中心极限定理

5.1 一维高斯分布的 MLE

一维高斯分布

p(xμ,σ2)=12πσexp((xμ)22σ2)p(x|\mu, \sigma^2) = \frac{1}{\sqrt{2\pi}\sigma} \exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)

参数:均值 μ\mu(分布中心),方差 σ2\sigma^2(分布宽度)。

对数似然函数(对 NN 个 i.i.d. 样本):

logp(Xμ,σ2)=i=1Nlogp(xiμ,σ2)\log p(X|\mu, \sigma^2) = \sum_{i=1}^N \log p(x_i|\mu, \sigma^2) =i=1N[log(2πσ)(xiμ)22σ2]= \sum_{i=1}^N \left[-\log(\sqrt{2\pi}\sigma) - \frac{(x_i-\mu)^2}{2\sigma^2}\right] =N2log(2π)Nlogσ12σ2i=1N(xiμ)2= -\frac{N}{2}\log(2\pi) - N\log\sigma - \frac{1}{2\sigma^2}\sum_{i=1}^N (x_i-\mu)^2

μ\mu 求偏导

μlogp(Xμ,σ2)=1σ2i=1N(xiμ)=0\frac{\partial}{\partial \mu}\log p(X|\mu, \sigma^2) = \frac{1}{\sigma^2}\sum_{i=1}^N (x_i - \mu) = 0 μMLE=1Ni=1Nxi\Rightarrow \boxed{\mu_{\text{MLE}} = \frac{1}{N}\sum_{i=1}^N x_i}

这就是样本均值,完全符合直觉。

σ2\sigma^2 求偏导(设 β=1/σ2\beta = 1/\sigma^2):

σi=1N[logσ(xiμ)22σ2]=i=1N[1σ+(xiμ)2σ3]=0\frac{\partial}{\partial \sigma}\sum_{i=1}^N\left[-\log\sigma - \frac{(x_i-\mu)^2}{2\sigma^2}\right] = \sum_{i=1}^N\left[-\frac{1}{\sigma} + \frac{(x_i-\mu)^2}{\sigma^3}\right] = 0 σMLE2=1Ni=1N(xiμMLE)2\Rightarrow \boxed{\sigma^2_{\text{MLE}} = \frac{1}{N}\sum_{i=1}^N (x_i - \mu_{\text{MLE}})^2}

这是样本方差

5.2 MLE 的偏差问题

μMLE\mu_{\text{MLE}}μ\mu无偏估计

E[μMLE]=E[1Ni=1Nxi]=1Ni=1NE[xi]=μ\mathbb{E}[\mu_{\text{MLE}}] = \mathbb{E}\left[\frac{1}{N}\sum_{i=1}^N x_i\right] = \frac{1}{N}\sum_{i=1}^N \mathbb{E}[x_i] = \mu

σMLE2\sigma^2_{\text{MLE}}σ2\sigma^2有偏估计,推导如下:

E[σMLE2]=E[1Ni=1N(xiμMLE)2]\mathbb{E}\left[\sigma^2_{\text{MLE}}\right] = \mathbb{E}\left[\frac{1}{N}\sum_{i=1}^N (x_i - \mu_{\text{MLE}})^2\right]

关键步骤:(xiμMLE)=(xiμ)(μMLEμ)(x_i - \mu_{\text{MLE}}) = (x_i - \mu) - (\mu_{\text{MLE}} - \mu),展开平方后:

E[σMLE2]=σ2Var[μMLE]=σ2σ2N=N1Nσ2\mathbb{E}\left[\sigma^2_{\text{MLE}}\right] = \sigma^2 - \text{Var}[\mu_{\text{MLE}}] = \sigma^2 - \frac{\sigma^2}{N} = \frac{N-1}{N}\sigma^2

MLE 系统性低估了方差!原因是:我们用 μMLE\mu_{\text{MLE}} 代替真实均值 μ\mu,而样本均值天然地比真实均值更"靠近"样本点,导致计算出的方差偏小。

无偏修正(贝塞尔校正)

σ^2=1N1i=1N(xiμMLE)2\hat{\sigma}^2 = \frac{1}{N-1}\sum_{i=1}^N (x_i - \mu_{\text{MLE}})^2

分母用 N1N-1 而非 NN,这也是 numpy.var(ddof=1)pandas.std() 的默认行为。

python
import numpy as np
 
# 模拟MLE偏差
true_mu, true_sigma2 = 0.0, 1.0
np.random.seed(0)
 
n_datasets = 10000
N = 5  # 小数据集时偏差更明显
mle_means, mle_vars, corrected_vars = [], [], []
 
for _ in range(n_datasets):
    data = np.random.normal(true_mu, np.sqrt(true_sigma2), N)
    mu_mle = np.mean(data)
    var_mle = np.var(data)          # 除以N(有偏)
    var_corr = np.var(data, ddof=1) # 除以N-1(无偏)
    mle_means.append(mu_mle)
    mle_vars.append(var_mle)
    corrected_vars.append(var_corr)
 
print(f"真实均值: {true_mu:.4f}")
print(f"MLE均值期望: {np.mean(mle_means):.4f}  (无偏)")
print(f"真实方差: {true_sigma2:.4f}")
print(f"MLE方差期望: {np.mean(mle_vars):.4f}  (有偏, 约为 (N-1)/N * σ²)")
print(f"校正方差期望: {np.mean(corrected_vars):.4f}  (无偏)")
print(f"理论有偏值: {(N-1)/N * true_sigma2:.4f}")

这个偏差现象的深层含义:MLE 作为频率派的核心方法,在有限样本下会系统性地低估不确定性(方差)。这是过拟合问题的一个缩影——模型对训练数据的拟合"太好了"。贝叶斯方法通过引入先验,能够自动避免这种过估计。

5.3 多维高斯分布

多维高斯分布xRp\mathbf{x} \in \mathbb{R}^p):

p(xμ,Σ)=1(2π)p/2Σ1/2exp(12(xμ)TΣ1(xμ))p(\mathbf{x}|\boldsymbol{\mu}, \boldsymbol{\Sigma}) = \frac{1}{(2\pi)^{p/2}|\boldsymbol{\Sigma}|^{1/2}} \exp\left(-\frac{1}{2}(\mathbf{x}-\boldsymbol{\mu})^T\boldsymbol{\Sigma}^{-1}(\mathbf{x}-\boldsymbol{\mu})\right)

指数中的二次型 Δ2=(xμ)TΣ1(xμ)\Delta^2 = (\mathbf{x}-\boldsymbol{\mu})^T\boldsymbol{\Sigma}^{-1}(\mathbf{x}-\boldsymbol{\mu}) 称为马氏距离(Mahalanobis Distance)

特征值分解Σ=UΛUT\boldsymbol{\Sigma} = U\Lambda U^T,则:

Δ2=i=1pyi2λi\Delta^2 = \sum_{i=1}^p \frac{y_i^2}{\lambda_i}

其中 yi=uiT(xμ)y_i = \mathbf{u}_i^T(\mathbf{x} - \boldsymbol{\mu})xμ\mathbf{x}-\boldsymbol{\mu} 在特征向量方向的投影。等 Δ\Delta 值的曲面是以特征向量为主轴、特征值平方根为半轴的椭球面

多维高斯的两个实际问题

  1. 参数量问题:协方差矩阵 Σ\boldsymbol{\Sigma}p(p+1)/2p(p+1)/2 个自由参数,当 pp 很大时不可处理

    • 解决方案:对角矩阵(特征独立假设)、各向同性(Σ=σ2I\boldsymbol{\Sigma} = \sigma^2 I
    • 相关算法:Factor Analysis, 概率PCA
  2. 单峰限制:单个高斯无法建模多峰数据

    • 解决方案:高斯混合模型(GMM)
python
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normal
 
# 二维高斯分布可视化
mu = np.array([0.0, 0.0])
Sigma = np.array([[2.0, 1.5], [1.5, 2.0]])  # 正相关
 
x, y = np.meshgrid(np.linspace(-4, 4, 100), np.linspace(-4, 4, 100))
pos = np.dstack((x, y))
z = multivariate_normal(mu, Sigma).pdf(pos)
 
fig, ax = plt.subplots(figsize=(7, 6))
cp = ax.contourf(x, y, z, levels=20, cmap='Blues')
plt.colorbar(cp, label='Density')
 
# 画主轴(特征向量方向)
eigenvalues, eigenvectors = np.linalg.eigh(Sigma)
for val, vec in zip(eigenvalues, eigenvectors.T):
    scale = 2 * np.sqrt(val)
    ax.annotate('', xy=mu + scale * vec, xytext=mu - scale * vec,
                arrowprops=dict(arrowstyle='<->', color='red', lw=2))
 
ax.set_title('2D Gaussian: Contours & Principal Axes')
ax.set_aspect('equal')
plt.tight_layout()
plt.savefig('2d_gaussian.png', dpi=150)
plt.show()

6. 曲线拟合的概率视角

6.1 最大似然与最小二乘的等价性

噪声模型假设:目标值由真实函数加上高斯噪声生成:

t=y(x,w)+ϵ,ϵN(0,β1)t = y(x, \mathbf{w}) + \epsilon, \quad \epsilon \sim \mathcal{N}(0, \beta^{-1})

其中 β=1/σ2\beta = 1/\sigma^2 称为精度(precision)。

因此,给定 xx 和参数 w\mathbf{w}tt 的条件概率为:

p(tx,w,β)=N(ty(x,w),β1)p(t|x, \mathbf{w}, \beta) = \mathcal{N}(t\, |\, y(x,\mathbf{w}),\, \beta^{-1})

对数似然(对 NN 个 i.i.d. 观测):

logp(tX,w,β)=n=1NlogN(tny(xn,w),β1)\log p(\mathbf{t}|X, \mathbf{w}, \beta) = \sum_{n=1}^N \log \mathcal{N}(t_n|y(x_n,\mathbf{w}), \beta^{-1}) =N2log(2π)+N2logββ2n=1N[y(xn,w)tn]2= -\frac{N}{2}\log(2\pi) + \frac{N}{2}\log\beta - \frac{\beta}{2}\sum_{n=1}^N [y(x_n,\mathbf{w}) - t_n]^2

最大化似然 ⟺ 最小化平方误差

w\mathbf{w} 最大化对数似然,等价于最小化:

n=1N[y(xn,w)tn]2=2E(w)\sum_{n=1}^N [y(x_n,\mathbf{w}) - t_n]^2 = 2E(\mathbf{w})

这揭示了最小二乘法的概率含义:最小二乘是在高斯噪声假设下的最大似然估计

噪声精度的 MLE:对 β\beta 求导:

1βMLE=1Nn=1N[y(xn,wMLE)tn]2\frac{1}{\beta_{\text{MLE}}} = \frac{1}{N}\sum_{n=1}^N [y(x_n, \mathbf{w}_{\text{MLE}}) - t_n]^2

即预测方差等于训练集的平均残差平方和。

预测分布(对新数据点 xx^* 的预测):

p(tx,wMLE,βMLE)=N(ty(x,wMLE),βMLE1)p(t^*|x^*, \mathbf{w}_{\text{MLE}}, \beta_{\text{MLE}}) = \mathcal{N}(t^*|y(x^*, \mathbf{w}_{\text{MLE}}), \beta_{\text{MLE}}^{-1})
python
import numpy as np
from scipy.optimize import minimize
 
def log_likelihood_poly(w_beta, x, t, M):
    """多项式回归对数似然"""
    w = w_beta[:M+1]
    log_beta = w_beta[M+1]
    beta = np.exp(log_beta)
    y = np.polyval(w[::-1], x)  # 注意系数顺序
    N = len(t)
    ll = (N/2) * np.log(beta) - (beta/2) * np.sum((y - t)**2) - (N/2) * np.log(2*np.pi)
    return -ll  # 负对数似然(最小化)
 
# 用梯度下降等价地最小化平方误差
Phi = polynomial_features(x_train, 3)
w_mle = np.linalg.lstsq(Phi, t_train, rcond=None)[0]
residuals = t_train - Phi @ w_mle
beta_mle = 1.0 / np.mean(residuals**2)
 
print(f"MLE参数 w: {w_mle}")
print(f"MLE噪声精度 β: {beta_mle:.4f}")
print(f"MLE噪声标准差 σ: {1/np.sqrt(beta_mle):.4f}")
 
# 预测区间
x_pred = np.linspace(0, 1, 200)
Phi_pred = polynomial_features(x_pred, 3)
y_pred = Phi_pred @ w_mle
std_pred = 1 / np.sqrt(beta_mle)
 
plt.figure(figsize=(8, 5))
plt.scatter(x_train, t_train, color='blue', s=50, label='训练数据')
plt.plot(x_pred, np.sin(2*np.pi*x_pred), 'g-', label='真实函数')
plt.plot(x_pred, y_pred, 'r-', label='MLE预测')
plt.fill_between(x_pred, y_pred - std_pred, y_pred + std_pred,
                 alpha=0.3, color='red', label='±1σ 预测区间')
plt.legend()
plt.title('最大似然估计:多项式回归(概率视角)')
plt.tight_layout()
plt.show()

6.2 贝叶斯曲线拟合

频率派的局限:MLE 给出的是点估计,没有对参数不确定性的量化。在数据量少时,这会导致置信度过高。

贝叶斯方法:对参数 w\mathbf{w} 引入高斯先验:

p(wα)=N(w0,α1I)p(\mathbf{w}|\alpha) = \mathcal{N}(\mathbf{w}|\mathbf{0}, \alpha^{-1}I)

这相当于假设每个参数都独立地接近零,α\alpha 控制先验强度。

后验分布(利用高斯共轭性,后验仍是高斯):

p(wt,X,α,β)p(tX,w,β)p(wα)p(\mathbf{w}|\mathbf{t}, X, \alpha, \beta) \propto p(\mathbf{t}|X, \mathbf{w}, \beta) \cdot p(\mathbf{w}|\alpha) =N(wmN,SN)= \mathcal{N}(\mathbf{w}|\mathbf{m}_N, S_N)

其中:

SN1=αI+βΦTΦS_N^{-1} = \alpha I + \beta \Phi^T\Phi mN=βSNΦTt\mathbf{m}_N = \beta S_N \Phi^T\mathbf{t}

关键洞察:MAP 估计(后验最大值)为:

wMAP=argmaxwlogp(wt)=mN\mathbf{w}_{\text{MAP}} = \arg\max_\mathbf{w} \log p(\mathbf{w}|\mathbf{t}) = \mathbf{m}_N

这等价于 αβ=λ\frac{\alpha}{\beta} = \lambda 时的正则化最小二乘!正则化系数 λ\lambda 的贝叶斯解释就是先验精度与噪声精度的比值。

贝叶斯预测分布:对所有可能的参数积分,得到预测分布

p(tx,X,t,α,β)=p(tx,w,β)p(wX,t,α,β)dwp(t^*|x^*, X, \mathbf{t}, \alpha, \beta) = \int p(t^*|x^*, \mathbf{w}, \beta)\, p(\mathbf{w}|X, \mathbf{t}, \alpha, \beta)\, d\mathbf{w} =N(tmNTϕ(x),1β噪声不确定性+ϕ(x)TSNϕ(x)参数不确定性)= \mathcal{N}\left(t^*\,\bigg|\, \mathbf{m}_N^T\phi(x^*),\, \underbrace{\frac{1}{\beta}}_{\text{噪声不确定性}} + \underbrace{\phi(x^*)^T S_N \phi(x^*)}_{\text{参数不确定性}}\right)

两个不确定性来源

  1. 数据噪声1/β1/\beta,固定不变
  2. 参数不确定性ϕ(x)TSNϕ(x)\phi(x^*)^T S_N \phi(x^*),在训练数据少的区域(外推区)更大
python
import numpy as np
import matplotlib.pyplot as plt
 
def bayesian_polynomial_regression(x_train, t_train, x_pred, degree, alpha, beta):
    """
    贝叶斯多项式回归
    alpha: 先验精度
    beta:  噪声精度
    返回后验均值和方差
    """
    Phi_train = polynomial_features(x_train, degree)
    Phi_pred  = polynomial_features(x_pred, degree)
    M1 = degree + 1
 
    # 后验精度矩阵
    S_N_inv = alpha * np.eye(M1) + beta * Phi_train.T @ Phi_train
    S_N = np.linalg.inv(S_N_inv)
 
    # 后验均值
    m_N = beta * S_N @ Phi_train.T @ t_train
 
    # 预测均值和方差
    y_pred_mean = Phi_pred @ m_N
    y_pred_var  = 1/beta + np.array([phi @ S_N @ phi for phi in Phi_pred])
 
    return m_N, S_N, y_pred_mean, y_pred_var
 
alpha, beta_val = 5e-3, 11.1   # 超参数
m_N, S_N, y_mean, y_var = bayesian_polynomial_regression(
    x_train, t_train, x_test, 9, alpha, beta_val
)
y_std = np.sqrt(y_var)
 
plt.figure(figsize=(8, 5))
plt.scatter(x_train, t_train, color='blue', s=50, zorder=5, label='训练数据')
plt.plot(x_test, np.sin(2*np.pi*x_test), 'g-', lw=2, label='真实函数')
plt.plot(x_test, y_mean, 'r-', lw=2, label='贝叶斯预测均值')
plt.fill_between(x_test, y_mean - y_std, y_mean + y_std,
                 alpha=0.3, color='red', label='±1σ 贝叶斯不确定性')
plt.ylim(-1.5, 1.5)
plt.legend()
plt.title('贝叶斯曲线拟合(M=9,高斯先验)')
plt.tight_layout()
plt.show()
 
print("贝叶斯预测 vs MLE预测的关键区别:")
print("- 贝叶斯预测给出完整的预测分布,而非点估计")
print("- 在数据稀少区域(如端点),预测不确定性自动增大")
print("- 不需要单独的验证集来选择模型复杂度(原则上)")

7. 模型选择

核心问题:如何选择合适的模型复杂度(如多项式阶数 MM,或正则化参数 λ\lambda)?

方法一:验证集(Validation Set)

将数据分成训练集和验证集,在训练集上拟合模型,在验证集上评估性能,选择验证误差最小的模型。

问题:当数据量有限时,这种方法"浪费"了宝贵的训练数据。

方法二:kk 折交叉验证(kk-fold Cross-Validation)

将数据分成 kk 份,轮流用其中 k1k-1 份训练,1 份验证,最终取平均验证误差:

数据集 D 分成 k 份: D₁, D₂, ..., Dₖ

for i = 1 to k:
    训练集 = D \ Dᵢ
    验证集 = Dᵢ
    error_i = evaluate(train on 训练集, test on 验证集)

CV_error = mean(error_1, ..., error_k)

特例:k=Nk=N留一法,LOO-CV),偏差最小但计算代价最大。

python
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import Ridge
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
 
# k折交叉验证选择最优模型阶数
x_data = x_train.reshape(-1, 1)
cv_errors = []
 
for degree in range(1, 10):
    model = Pipeline([
        ('poly', PolynomialFeatures(degree=degree)),
        ('ridge', Ridge(alpha=1e-4))
    ])
    scores = cross_val_score(model, x_data, t_train,
                             cv=5, scoring='neg_mean_squared_error')
    cv_errors.append(-scores.mean())
 
best_degree = np.argmin(cv_errors) + 1
print(f"5折交叉验证最优阶数: M = {best_degree}")
 
plt.figure(figsize=(7, 4))
plt.plot(range(1, 10), cv_errors, 'b-o')
plt.xlabel('多项式阶数 M')
plt.ylabel('5折CV MSE')
plt.title('交叉验证选择模型复杂度')
plt.axvline(best_degree, color='r', linestyle='--', label=f'最优M={best_degree}')
plt.legend()
plt.tight_layout()
plt.show()

方法三:信息准则

其中 kk 是参数数量,L^\hat{L} 是最大似然。BIC 对复杂模型的惩罚更重(包含 lnN\ln N),更倾向于选择简单模型。

方法四:贝叶斯模型选择

通过计算边际似然(模型证据)

p(XMi)=p(Xw,Mi)p(wMi)dwp(X|\mathcal{M}_i) = \int p(X|\mathbf{w}, \mathcal{M}_i)\,p(\mathbf{w}|\mathcal{M}_i)\,d\mathbf{w}

证据自动对模型复杂度进行惩罚(奥卡姆剃刀原则):复杂模型必须用先验概率来支付参数的"代价"。


8. 维度灾难

维度灾难(Curse of Dimensionality) 是高维机器学习面临的核心挑战,由 Richard Bellman 提出。

8.1 球体体积集中在壳上

现象:在高维空间中,超球体的体积几乎全部集中在薄壳上(接近表面)。

DD 维单位球体中,半径 [1ϵ,1][1-\epsilon, 1] 的壳占总体积的比例为:

VD(1)VD(1ϵ)VD(1)=1(1ϵ)D\frac{V_D(1) - V_D(1-\epsilon)}{V_D(1)} = 1 - (1-\epsilon)^D
python
import numpy as np
import matplotlib.pyplot as plt
 
epsilon = 0.01  # 薄壳厚度
dims = range(1, 1001)
shell_fraction = [1 - (1 - epsilon)**D for D in dims]
 
plt.figure(figsize=(8, 4))
plt.plot(dims, shell_fraction, 'b-')
plt.xlabel('维度 D')
plt.ylabel('薄壳体积占比')
plt.title(f'ε={epsilon} 薄壳体积占超球体总体积的比例')
plt.axhline(0.99, color='r', linestyle='--', label='99%')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
 
# 数值结果
for D in [1, 2, 5, 10, 100]:
    fraction = 1 - (1 - epsilon)**D
    print(f"D={D:4d}: 壳体积占比 = {fraction:.6f}")

8.2 高维空间中数据点稀疏

核心问题:要在 DD 维空间中达到足够密度的训练样本,所需样本量以指数方式增长。

例如:在每个维度上将 [0,1]D[0,1]^D 分成 5 份,需要 5D5^D 个格子:

8.3 高维 Gaussian 的几何性质

DD 维标准高斯中采样,样本到原点的距离分布峰值在 rDr \approx \sqrt{D} 处:

p(r)rD1exp(r2/2)p(r) \propto r^{D-1}\exp(-r^2/2)
python
import numpy as np
import matplotlib.pyplot as plt
 
def sample_gaussian_radius(D, n_samples=10000):
    samples = np.random.randn(n_samples, D)
    return np.linalg.norm(samples, axis=1)
 
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
 
for D in [1, 2, 5, 20, 100]:
    radii = sample_gaussian_radius(D)
    axes[0].hist(radii, bins=50, density=True, alpha=0.5, label=f'D={D}')
    axes[1].hist(radii / np.sqrt(D), bins=50, density=True, alpha=0.5, label=f'D={D}')
 
axes[0].set_title('高维高斯样本到原点距离分布')
axes[0].set_xlabel('距离 r')
axes[0].legend()
 
axes[1].set_title('归一化距离 r/√D 分布')
axes[1].set_xlabel('r / √D')
axes[1].legend()
 
plt.tight_layout()
plt.show()

8.4 维度灾难的影响与应对

影响

应对策略

  1. 特征选择(Feature Selection):只保留最相关的特征
  2. 降维(Dimensionality Reduction):PCA, t-SNE, UMAP
  3. 正则化(Regularization):约束模型的有效复杂度
  4. 利用数据的低维流形结构:真实数据往往存在于高维空间的低维流形上

重要认识:维度灾难并没有使机器学习无效!这是因为真实数据不是在高维空间中均匀分布的,而是集中在较低维的流形上,这使得机器学习仍然可行。


9. 决策论

概率论告诉我们如何描述和更新不确定性;决策论(Decision Theory) 告诉我们在不确定性下如何做出最优决策。

场景:已知输入 x\mathbf{x} 和后验分布 p(Ckx)p(\mathcal{C}_k|\mathbf{x}),应该将 x\mathbf{x} 分到哪个类?

9.1 最小误分类率

决策区域(Decision Region):将输入空间划分为 KK 个区域 Rk\mathcal{R}_k,落入 Rk\mathcal{R}_k 的点被分为 Ck\mathcal{C}_k 类。

误分类概率

P(mistake)=k=1KxRkp(x,Ck)dxP(\text{mistake}) = \sum_{k=1}^K \int_{\mathbf{x} \notin \mathcal{R}_k} p(\mathbf{x}, \mathcal{C}_k)\,d\mathbf{x}

两类问题的最优规则(最小化误分类率):

C1 当p(C1x)>p(C2x)\text{选} \mathcal{C}_1 \text{ 当} p(\mathcal{C}_1|\mathbf{x}) > p(\mathcal{C}_2|\mathbf{x})

总是选择后验概率最大的类——这就是最大后验(MAP)分类规则

伪代码:MAP分类器
输入: x, 模型 p(x|C_k), 先验 p(C_k)
输出: 预测类别

1. 对每个类 k:
   计算 p(C_k|x) ∝ p(x|C_k) * p(C_k)
2. 返回 argmax_k p(C_k|x)

几何意义:决策边界 R1/R2\mathcal{R}_1 / \mathcal{R}_2 是满足 p(C1x)=p(C2x)p(\mathcal{C}_1|\mathbf{x}) = p(\mathcal{C}_2|\mathbf{x}) 的超曲面,即后验概率相等的点集。

9.2 最小期望损失

在许多实际应用中,不同类型的错误代价不同。例如:

损失矩阵(Loss Matrix)LkjL_{kj} 表示真实类别为 Ck\mathcal{C}_k 但被分到 Cj\mathcal{C}_j 时的损失(Lkk=0L_{kk}=0)。

期望损失(Expected Loss)

E[L]=kjRjLkjp(x,Ck)dx\mathbb{E}[L] = \sum_k \sum_j \int_{\mathcal{R}_j} L_{kj} p(\mathbf{x}, \mathcal{C}_k)\,d\mathbf{x}

最优决策规则:将 x\mathbf{x} 分到使期望损失最小的类:

j=argminjkLkjp(Ckx)j^* = \arg\min_j \sum_k L_{kj} p(\mathcal{C}_k|\mathbf{x})
python
import numpy as np
 
def min_expected_loss_decision(posterior, loss_matrix):
    """
    posterior: shape (K,) — 各类的后验概率
    loss_matrix: shape (K, K) — L[k,j] = 真实为k分到j的损失
    返回最优决策类别索引
    """
    # 期望损失 [j] = sum_k L[k,j] * p(C_k|x)
    expected_losses = loss_matrix.T @ posterior
    return np.argmin(expected_losses)
 
# 二分类例子:医疗诊断
# 类0: 正常, 类1: 癌症
posterior = np.array([0.7, 0.3])  # P(正常|x)=0.7, P(癌症|x)=0.3
 
# 对称损失(0-1损失)
L_symmetric = np.array([[0, 1],
                         [1, 0]])
 
# 非对称损失(漏诊代价极高)
L_asymmetric = np.array([[0,  1],    # 正常→误诊为癌: 代价1
                          [10, 0]])   # 癌症→漏诊: 代价10
 
dec_sym = min_expected_loss_decision(posterior, L_symmetric)
dec_asy = min_expected_loss_decision(posterior, L_asymmetric)
 
print(f"后验概率: P(正常|x)={posterior[0]}, P(癌症|x)={posterior[1]}")
print(f"对称损失下决策: 类{dec_sym} ({'正常' if dec_sym==0 else '癌症'})")
print(f"非对称损失下决策: 类{dec_asy} ({'正常' if dec_asy==0 else '癌症'})")
print("=> 即使癌症后验只有0.3,考虑漏诊代价后仍应诊断为癌症!")

9.3 拒绝选项

最高后验概率不超过阈值 θ\theta 时,拒绝做出决策(交给专家判断):

决策={argmaxkp(Ckx)maxkp(Ckx)>θ拒绝否则\text{决策} = \begin{cases} \arg\max_k p(\mathcal{C}_k|\mathbf{x}) & \text{若} \max_k p(\mathcal{C}_k|\mathbf{x}) > \theta \\ \text{拒绝} & \text{否则} \end{cases}

直觉:当模型对某个输入不确定时(所有类的后验都接近),强行做出决策可能是不可靠的。

应用场景

阈值 θ\theta 的选择θ\theta 越高,拒绝的样本越多(覆盖率下降),但对接受的样本准确率越高(精度提升)。ROC 曲线下的面积(AUC)是衡量这种权衡的常用指标。

python
def predict_with_rejection(posteriors, threshold):
    """
    posteriors: shape (N, K)
    threshold: 拒绝阈值
    返回决策(-1表示拒绝)
    """
    max_posteriors = np.max(posteriors, axis=1)
    decisions = np.argmax(posteriors, axis=1)
    decisions[max_posteriors < threshold] = -1  # -1 = 拒绝
    return decisions
 
# 示例
np.random.seed(42)
N = 1000
posteriors = np.random.dirichlet([1, 1, 1], N)  # 3类随机后验
 
for theta in [0.4, 0.6, 0.8, 0.95]:
    decisions = predict_with_rejection(posteriors, theta)
    rejection_rate = np.mean(decisions == -1)
    print(f"θ={theta:.2f}: 拒绝率={rejection_rate:.2%}")

9.4 推断与决策的分离

Bishop 提出三种解决判别问题的方法,从完整到简化:

方法一:生成模型(Generative Models)

  1. 学习类条件密度 p(xCk)p(\mathbf{x}|\mathcal{C}_k) 和先验 p(Ck)p(\mathcal{C}_k)
  2. 用贝叶斯定理计算后验 p(Ckx)p(\mathcal{C}_k|\mathbf{x})
  3. 用决策论做最终决策

优点:可以生成新数据;可以检测异常值(低密度区域)
缺点:需要大量数据准确估计 p(xCk)p(\mathbf{x}|\mathcal{C}_k);分类不需要的密度信息被浪费
代表:朴素贝叶斯、高斯判别分析(GDA)、GMM 分类

方法二:判别模型(Discriminative Models)

直接建模后验 p(Ckx)p(\mathcal{C}_k|\mathbf{x}),然后决策。

优点:更直接,不需要建模 p(xCk)p(\mathbf{x}|\mathcal{C}_k);参数量少;通常泛化性能更好
代表:逻辑回归、条件随机场(CRF)

方法三:判别函数(Discriminant Functions)

直接学习输入到类别的映射 f(x)=Ckf(\mathbf{x}) = \mathcal{C}_k,完全绕过概率。

优点:最简单直接
缺点:没有不确定性信息;无法拒绝选项;无法使用损失矩阵
代表:SVM、感知机、决策树(以 hard 预测为输出时)

选择建议

需求推荐方法
只需要分类结果判别函数
需要概率输出(用于决策/校准)判别模型
需要生成新样本/异常检测生成模型

9.5 回归的损失函数

回归问题的期望损失

E[L]=L(t,y(x))p(x,t)dxdt\mathbb{E}[L] = \int\int L(t, y(\mathbf{x}))\,p(\mathbf{x}, t)\,d\mathbf{x}\,dt

对于给定 x\mathbf{x},最优预测 y(x)y(\mathbf{x}) 是使条件期望损失最小的值。

平方损失(L2 Loss)L(t,y)=(yt)2L(t, y) = (y-t)^2

最优预测:

y(x)=E[tx]=tp(tx)dty(\mathbf{x}) = \mathbb{E}[t|\mathbf{x}] = \int t\,p(t|\mathbf{x})\,dt

条件均值。推导(对 yy 求导令其为零):

y(yt)2p(tx)dt=2(yt)p(tx)dt=0\frac{\partial}{\partial y}\int (y-t)^2 p(t|\mathbf{x})\,dt = 2\int (y-t)p(t|\mathbf{x})\,dt = 0 y=tp(tx)dt=E[tx]\Rightarrow y = \int t\,p(t|\mathbf{x})\,dt = \mathbb{E}[t|\mathbf{x}]

期望平方误差的分解(Bias-Variance Decomposition):

E[(y(x)t)2x]=(y(x)E[tx])2偏差2+Var[tx]不可约噪声\mathbb{E}[(y(\mathbf{x}) - t)^2|\mathbf{x}] = \underbrace{(y(\mathbf{x}) - \mathbb{E}[t|\mathbf{x}])^2}_{\text{偏差}^2} + \underbrace{\text{Var}[t|\mathbf{x}]}_{\text{不可约噪声}}

绝对值损失(L1 Loss)L(t,y)=ytL(t, y) = |y-t|

最优预测是条件中位数(Median)。

Minkowski 损失L(t,y)=ytqL(t, y) = |y-t|^q

python
import numpy as np
import matplotlib.pyplot as plt
 
# 偏度非对称分布:均值、中位数、众数的比较
np.random.seed(42)
# 模拟一个右偏分布
data = np.concatenate([np.random.normal(2, 0.5, 800),
                        np.random.normal(5, 1.0, 200)])
 
mean_val   = np.mean(data)
median_val = np.median(data)
 
plt.figure(figsize=(8, 4))
plt.hist(data, bins=50, density=True, alpha=0.7, color='steelblue')
plt.axvline(mean_val,   color='red',    lw=2, linestyle='--', label=f'均值 (L2最优)={mean_val:.2f}')
plt.axvline(median_val, color='green',  lw=2, linestyle='--', label=f'中位数 (L1最优)={median_val:.2f}')
plt.legend()
plt.title('不同损失函数下的最优预测值')
plt.tight_layout()
plt.show()
 
# L2 vs L1 损失的鲁棒性比较
y_pred_vals = np.linspace(-2, 8, 500)
t_examples  = np.array([1.0, 2.0, 2.5, 3.0, 10.0])  # 最后一个是异常值
 
l2_losses = [np.sum((y - t_examples)**2) for y in y_pred_vals]
l1_losses = [np.sum(np.abs(y - t_examples)) for y in y_pred_vals]
 
plt.figure(figsize=(8, 4))
plt.plot(y_pred_vals, l2_losses, 'r-', label='L2总损失(最优=均值)')
plt.plot(y_pred_vals, l1_losses, 'b-', label='L1总损失(最优=中位数)')
plt.axvline(np.mean(t_examples),   color='r', linestyle='--', alpha=0.5)
plt.axvline(np.median(t_examples), color='b', linestyle='--', alpha=0.5)
plt.xlabel('预测值 y')
plt.ylabel('总损失')
plt.title('L2 vs L1 损失对异常值的敏感性')
plt.legend()
plt.tight_layout()
plt.show()

10. 信息论

信息论为机器学习提供了量化不确定性、衡量信息量、比较概率分布的数学工具。

10.1 熵

信息量的定义:观察到事件 xx 所获得的信息量应该满足:

  1. 概率越小的事件,信息量越大
  2. 独立事件的信息量可以相加:h(x,y)=h(x)+h(y)h(x, y) = h(x) + h(y)

满足以上条件的唯一函数形式(至多差一个正常数)是:

h(x)=logp(x)h(x) = -\log p(x)

负号保证信息量非负(因为 logp(x)0\log p(x) \leq 0)。

香农熵(Entropy):随机变量 XX 的平均信息量:

H[X]=xp(x)logp(x)\boxed{H[X] = -\sum_x p(x)\log p(x)}

约定 0log0=00\log 0 = 0(极限意义)。对于连续变量:

H[X]=p(x)logp(x)dx(微分熵,differential entropy)H[X] = -\int p(x)\log p(x)\,dx \quad \text{(微分熵,differential entropy)}

熵的性质

二元熵p(x=1)=μp(x=1) = \mup(x=0)=1μp(x=0) = 1-\mu

H=μlogμ(1μ)log(1μ)H = -\mu\log\mu - (1-\mu)\log(1-\mu)
python
import numpy as np
import matplotlib.pyplot as plt
 
def binary_entropy(mu):
    eps = 1e-15  # 防止log(0)
    mu = np.clip(mu, eps, 1 - eps)
    return -mu * np.log2(mu) - (1 - mu) * np.log2(1 - mu)
 
def discrete_entropy(probs):
    """计算离散分布的香农熵(以2为底,单位:bits)"""
    probs = np.array(probs)
    probs = probs[probs > 0]  # 排除0概率
    return -np.sum(probs * np.log2(probs))
 
# 二元熵曲线
mu_vals = np.linspace(0, 1, 1000)
H_vals  = binary_entropy(mu_vals)
 
plt.figure(figsize=(8, 4))
plt.plot(mu_vals, H_vals, 'b-', lw=2)
plt.xlabel('概率 μ = P(x=1)')
plt.ylabel('熵 H (bits)')
plt.title('二元熵函数:H(μ) = -μlog₂μ - (1-μ)log₂(1-μ)')
plt.axvline(0.5, color='r', linestyle='--', label='μ=0.5: 最大熵=1 bit')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
 
# 几个分布的熵
examples = {
    "公平硬币 (均匀)": [0.5, 0.5],
    "偏硬币 (0.9/0.1)": [0.9, 0.1],
    "确定事件": [1.0, 0.0],
    "均匀4面骰": [0.25]*4,
    "均匀6面骰": [1/6]*6,
}
print("各分布的熵:")
for name, probs in examples.items():
    H = discrete_entropy([p for p in probs if p > 0])
    print(f"  {name}: H = {H:.4f} bits")

最大熵分布

联合熵与条件熵

H[X,Y]=p(x,y)logp(x,y)dxdyH[X, Y] = -\iint p(x,y)\log p(x,y)\,dx\,dy H[YX]=p(x,y)logp(yx)dxdy=H[X,Y]H[X]H[Y|X] = -\iint p(x,y)\log p(y|x)\,dx\,dy = H[X,Y] - H[X]

链式法则H[X,Y]=H[X]+H[YX]H[X, Y] = H[X] + H[Y|X]

互信息(Mutual Information)

I[X;Y]=H[X]H[XY]=H[Y]H[YX]=H[X]+H[Y]H[X,Y]I[X; Y] = H[X] - H[X|Y] = H[Y] - H[Y|X] = H[X] + H[Y] - H[X,Y]

互信息衡量"了解 YY 之后,XX 的不确定性减少了多少",可以作为变量之间相关性的度量(不限于线性相关)。

10.2 KL 散度与互信息

KL 散度(相对熵, Kullback-Leibler Divergence):衡量分布 q(x)q(x) 与真实分布 p(x)p(x) 的差异:

KL(pq)=p(x)logq(x)dx(p(x)logp(x)dx)\text{KL}(p\|q) = -\int p(x)\log q(x)\,dx - \left(-\int p(x)\log p(x)\,dx\right) =p(x)logp(x)q(x)dx= \int p(x)\log\frac{p(x)}{q(x)}\,dx

KL 散度的性质

吉布斯不等式的证明(利用 lnxx1\ln x \leq x - 1):

KL(pq)=p(x)logq(x)p(x)dxp(x)(q(x)p(x)1)dx=q(x)dx1=0-\text{KL}(p\|q) = \int p(x)\log\frac{q(x)}{p(x)}\,dx \leq \int p(x)\left(\frac{q(x)}{p(x)} - 1\right)\,dx = \int q(x)\,dx - 1 = 0

因此 KL(pq)0\text{KL}(p\|q) \geq 0

KL 散度与最大似然的联系

假设真实分布为 p(x)p(\mathbf{x}),我们用参数化模型 q(xθ)q(\mathbf{x}|\boldsymbol{\theta}) 来近似:

KL(pq)=p(x)logq(xθ)dx+const\text{KL}(p\|q) = -\int p(\mathbf{x})\log q(\mathbf{x}|\boldsymbol{\theta})\,d\mathbf{x} + \text{const}

最小化 KL(pq)\text{KL}(p\|q) 等价于最大化期望对数似然

argminθKL(pq)=argmaxθEp[logq(xθ)]\arg\min_\theta \text{KL}(p\|q) = \arg\max_\theta \mathbb{E}_{p}[\log q(\mathbf{x}|\boldsymbol{\theta})]

用样本近似期望:1Nn=1Nlogq(xnθ)\approx \frac{1}{N}\sum_{n=1}^N \log q(x_n|\theta),这正是 MLE!

MLE最小化训练数据经验分布与模型分布之间的KL散度\text{MLE} \equiv \text{最小化训练数据经验分布与模型分布之间的KL散度}

互信息与KL散度的关系

I[X;Y]=KL(p(X,Y)p(X)p(Y))I[X; Y] = \text{KL}\left(p(X,Y) \| p(X)p(Y)\right)

互信息是联合分布与独立假设分布之间的 KL 散度,衡量 XXYY 偏离独立性的程度。

python
import numpy as np
from scipy.special import rel_entr  # KL散度的逐元素版本
 
def kl_divergence(p, q):
    """
    计算 KL(p||q)
    p, q: 离散概率分布 (numpy arrays)
    """
    eps = 1e-15
    p = np.clip(p, eps, 1)
    q = np.clip(q, eps, 1)
    return np.sum(rel_entr(p, q))  # sum(p * log(p/q))
 
# 示例:高斯分布的KL散度
def kl_gaussian(mu1, sigma1, mu2, sigma2):
    """计算 KL(N(mu1,sigma1^2) || N(mu2,sigma2^2)) 的解析解"""
    return (np.log(sigma2/sigma1) +
            (sigma1**2 + (mu1 - mu2)**2) / (2 * sigma2**2) - 0.5)
 
# 固定N(0,1),改变另一个分布
mu2_vals = np.linspace(-3, 3, 100)
kl_vals_1 = [kl_gaussian(0, 1, mu2, 1) for mu2 in mu2_vals]   # 只改变均值
kl_vals_2 = [kl_gaussian(0, 1, 0, sigma2) for sigma2 in np.linspace(0.1, 4, 100)]
 
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
 
axes[0].plot(mu2_vals, kl_vals_1, 'b-', lw=2)
axes[0].set_xlabel('μ₂ (σ₂=1固定)')
axes[0].set_ylabel('KL(N(0,1) || N(μ₂,1))')
axes[0].set_title('KL散度 vs 均值偏移')
axes[0].axvline(0, color='r', linestyle='--', label='KL=0 (相同分布)')
axes[0].legend()
 
sigma2_vals = np.linspace(0.1, 4, 100)
kl_vals_2 = [kl_gaussian(0, 1, 0, s2) for s2 in sigma2_vals]
axes[1].plot(sigma2_vals, kl_vals_2, 'g-', lw=2)
axes[1].set_xlabel('σ₂ (μ₂=0固定)')
axes[1].set_ylabel('KL(N(0,1) || N(0,σ₂))')
axes[1].set_title('KL散度 vs 方差变化')
axes[1].axvline(1, color='r', linestyle='--', label='KL=0 (σ₂=1)')
axes[1].legend()
 
plt.tight_layout()
plt.savefig('kl_divergence.png', dpi=150)
plt.show()
 
# 非对称性演示
print("\nKL散度的非对称性:")
p = np.array([0.7, 0.2, 0.1])
q = np.array([0.4, 0.4, 0.2])
print(f"  KL(p||q) = {kl_divergence(p, q):.4f}")
print(f"  KL(q||p) = {kl_divergence(q, p):.4f}")
print(f"  KL(p||q) ≠ KL(q||p), KL散度是非对称的")

交叉熵(Cross-Entropy)

H(p,q)=p(x)logq(x)dx=H[p]+KL(pq)H(p, q) = -\int p(x)\log q(x)\,dx = H[p] + \text{KL}(p\|q)

在机器学习中,当真实分布 pp 固定时,最小化交叉熵等价于最小化 KL 散度,也等价于 MLE。这也是分类问题中常用 Cross-Entropy Loss 的理论依据。

python
import numpy as np
 
def cross_entropy_loss(y_true_onehot, y_pred_probs):
    """
    分类交叉熵损失
    y_true_onehot: shape (N, K) 真实标签(one-hot)
    y_pred_probs: shape (N, K) 预测概率(softmax输出)
    """
    eps = 1e-15
    y_pred_probs = np.clip(y_pred_probs, eps, 1)
    return -np.mean(np.sum(y_true_onehot * np.log(y_pred_probs), axis=1))
 
# 示例:3分类,5个样本
np.random.seed(42)
y_true = np.array([[1,0,0], [0,1,0], [0,0,1], [1,0,0], [0,1,0]])
y_pred_good = np.array([[0.9, 0.05, 0.05],
                         [0.05, 0.9, 0.05],
                         [0.05, 0.05, 0.9],
                         [0.8, 0.1, 0.1],
                         [0.1, 0.8, 0.1]])
y_pred_bad  = np.array([[0.4, 0.3, 0.3],
                         [0.3, 0.4, 0.3],
                         [0.3, 0.3, 0.4],
                         [0.5, 0.3, 0.2],
                         [0.2, 0.5, 0.3]])
 
print(f"好预测的交叉熵: {cross_entropy_loss(y_true, y_pred_good):.4f}")
print(f"差预测的交叉熵: {cross_entropy_loss(y_true, y_pred_bad):.4f}")

总结:第一章知识体系

text
PRML 第一章知识图谱

├── 核心示例: 多项式曲线拟合
│   ├── 最小二乘法(正规方程)
│   ├── 过拟合与欠拟合
│   └── 正则化(Ridge/L2)

├── 概率论基础
│   ├── 加法规则(边际化)
│   ├── 乘法规则
│   ├── 贝叶斯定理
│   └── 连续密度 / 期望 / 协方差

├── 两大学派
│   ├── 频率派 → MLE → 最优化问题
│   └── 贝叶斯派 → MAP / 后验预测 → 积分问题

├── 高斯分布
│   ├── MLE(均值无偏,方差有偏)
│   └── 贝塞尔校正

├── 概率视角的曲线拟合
│   ├── 高斯噪声模型 → MLE ≡ 最小二乘
│   └── 高斯先验 → MAP ≡ 正则化最小二乘

├── 模型选择
│   ├── 交叉验证
│   └── 信息准则 (AIC/BIC)

├── 维度灾难
│   ├── 体积集中在表面
│   └── 指数增长的样本需求

├── 决策论
│   ├── 最小误分类率 → MAP规则
│   ├── 最小期望损失 → 损失矩阵
│   ├── 拒绝选项
│   ├── 推断与决策的分离(三种方法)
│   └── 回归损失:L2→均值, L1→中位数

└── 信息论
    ├── 熵 H[X]
    ├── 联合熵 / 条件熵
    ├── KL散度(非对称,≥0)
    ├── 互信息 I[X;Y] = KL(p(x,y)||p(x)p(y))
    └── 交叉熵 ≡ MLE 目标函数

贯穿全章的核心思想

  1. 不确定性无处不在:数据有噪声,模型有参数不确定性,预测有误差
  2. 概率论是处理不确定性的语言:加法规则+乘法规则推导出贝叶斯定理
  3. MLE 与最小二乘是等价的(高斯噪声假设下),正则化对应高斯先验
  4. 过拟合 = 有限数据下的最大似然:贝叶斯方法通过积分避免过拟合
  5. 决策需要损失函数:概率是推断的工具,损失函数决定最终行动

参考资料