2模式识别与机器学习

概率分布

数据的概率建模

高斯分布指数族共轭先验充分统计量

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第2章:概率分布(Probability Distributions)

一、导读

2.1 本章学习目标

第2章是全书的数学基础章节,系统介绍了模式识别中最常用的概率分布及其参数估计方法。如果说第1章建立了"概率论是模式识别的语言"这一宏观认知,那么第2章则教你如何使用这门语言。从二项分布到高斯分布,从最大似然估计到贝叶斯估计,本章为后续所有章节提供了必要的概率工具。

本章的核心学习目标包括:

  • 掌握二项分布和多项式分布:理解离散随机变量的建模方法,以及Beta分布和Dirichlet分布作为共轭先验的角色。
  • 深入理解高斯分布:掌握一元和多元高斯分布的性质,理解其在模式识别中的核心地位。
  • 掌握参数估计的两大范式:最大似然估计(MLE)和贝叶斯估计(Bayesian Estimation)的区别与联系。
  • 理解共轭先验的意义:为什么Beta分布是二项分布的共轭先验?高斯分布的共轭先验是什么?
  • 掌握非参数方法:核密度估计和K近邻方法如何在不假设分布形式的情况下估计概率密度。
  • 理解EM算法的动机:当数据包含隐变量时,如何估计概率分布的参数?

2.2 为什么本章如此重要

概率分布是构建概率模型的基石。在模式识别中,我们本质上是在做两件事:选择概率分布族(如高斯分布、多项式分布)和估计分布的参数(如均值、方差)。后续章节中的几乎所有模型——从线性模型到神经网络,从图模型到混合模型——都可以理解为对数据分布的建模。

特别值得注意的是本章引入的指数族分布(Exponential Family)的概念。二项分布、多项式分布、高斯分布、泊松分布、Gamma分布等都属于指数族。指数族提供了一个统一的框架,使得我们可以用相同的数学工具处理不同的分布。这个概念在后续章节的变分推断(第10章)和图模型(第8章)中起着关键作用。

2.3 核心问题引导

在阅读本章时,请带着以下问题思考:

最大似然估计为什么容易过拟合?贝叶斯方法如何解决这个问题?

什么是共轭先验?为什么共轭先验在贝叶斯推断中如此重要?

多元高斯分布的协方差矩阵为什么必须是正定的?它在几何上代表什么?

学生t分布相比高斯分布有什么优势?在什么场景下应该使用它?

核密度估计的带宽选择如何影响估计结果?如何自动选择最优带宽?

指数族分布有什么统一的性质?为什么这些性质对推断很重要?


二、核心概念详解

2.1 二项分布与多项式分布

2.1.1 二项分布

二项分布描述的是 $N$ 次独立伯努利试验中成功次数的概率分布。设每次试验成功的概率为 $\mu$,则 $m$ 次成功的概率为:

$$\text{Bin}(m|N, \mu) = \binom{N}{m} \mu^m (1-\mu)^{N-m}$$

其中 $\binom{N}{m} = \frac{N!}{m!(N-m)!}$ 是二项式系数。

二项分布的均值和方差分别为:

$$\mathbb{E}[m] = N\mu, \quad \text{var}[m] = N\mu(1-\mu)$$

2.1.2 Beta分布:二项分布的共轭先验

在贝叶斯框架中,我们需要为参数 $\mu$ 指定一个先验分布。为了使后验分布具有解析形式,我们选择二项分布的共轭先验——Beta分布:

$$\text{Beta}(\mu|a, b) = \frac{\Gamma(a+b)}{\Gamma(a)\Gamma(b)} \mu^{a-1} (1-\mu)^{b-1}$$

其中 $\Gamma(\cdot)$ 是Gamma函数。

Beta分布作为先验时,后验分布仍然是Beta分布:

$$p(\mu|m, N, a, b) \propto \mu^{m+a-1} (1-\mu)^{N-m+b-1} = \text{Beta}(\mu|m+a, N-m+b)$$

后验均值提供了一个优雅的"先验+数据"的加权平均:

$$\mathbb{E}[\mu] = \frac{m+a}{N+a+b} = \frac{a}{a+b} \cdot \frac{a+b}{N+a+b} + \frac{m}{N} \cdot \frac{N}{N+a+b}$$

当 $N \to \infty$ 时,后验均值趋向于最大似然估计 $\frac{m}{N}$。

python
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt

def beta_binomial_update(a, b, N, m):
    """Beta-Binomials共轭更新"""
    a_post = a + m
    b_post = b + N - m
    return a_post, b_post

# 可视化先验到后验的更新过程
a_prior, b_prior = 2, 2  # 先验
N = 10  # 试验次数

fig, axes = plt.subplots(1, 3, figsize=(15, 4))
mu = np.linspace(0.01, 0.99, 200)

# 不同观测数据下的后验
for idx, (m, title) in enumerate([(2, "m=2, N=10"), (5, "m=5, N=10"), (8, "m=8, N=10")]):
    a_post, b_post = beta_binomial_update(a_prior, b_prior, N, m)
    prior_pdf = stats.beta.pdf(mu, a_prior, b_prior)
    posterior_pdf = stats.beta.pdf(mu, a_post, b_post)
    
    axes[idx].plot(mu, prior_pdf, 'b--', label=f'Prior Beta({a_prior},{b_prior})', linewidth=2)
    axes[idx].plot(mu, posterior_pdf, 'r-', label=f'Posterior Beta({a_post},{b_post})', linewidth=2)
    axes[idx].set_title(title)
    axes[idx].set_xlabel('μ')
    axes[idx].set_ylabel('p(μ)')
    axes[idx].legend(fontsize=8)
    axes[idx].grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('beta_binomial_update.png', dpi=150)
plt.close()

print(f"先验均值: {a_prior/(a_prior+b_prior):.3f}")
for m in [2, 5, 8]:
    a_post, b_post = beta_binomial_update(a_prior, b_prior, N, m)
    print(f"m={m}, N={N}: 后验均值={a_post/(a_post+b_post):.3f}, MLE={m/N:.3f}")

2.1.3 多项式分布与Dirichlet分布

多项式分布是二项分布向多类别的推广。设 $K$ 个类别的概率分别为 $\boldsymbol{\mu} = (\mu_1, \ldots, \mu_K)$,满足 $\sum_k \mu_k = 1$,则观测到各类别计数为 $\mathbf{m} = (m_1, \ldots, m_K)$ 的概率为:

$$\text{Mult}(\mathbf{m}|N, \boldsymbol{\mu}) = \frac{N!}{m_1! \cdots m_K!} \prod_{k=1}^{K} \mu_k^{m_k}$$

多项式分布的共轭先验是Dirichlet分布:

$$\text{Dir}(\boldsymbol{\mu}|\boldsymbol{\alpha}) = \frac{\Gamma(\sum_k \alpha_k)}{\prod_k \Gamma(\alpha_k)} \prod_{k=1}^{K} \mu_k^{\alpha_k - 1}$$

后验分布为:

$$p(\boldsymbol{\mu}|\mathbf{m}, N, \boldsymbol{\alpha}) = \text{Dir}(\boldsymbol{\mu}|\mathbf{m} + \boldsymbol{\alpha})$$

python
def dirichlet_update(alpha, m):
    """Dirichlet-Multinomial共轭更新"""
    alpha_post = alpha + m
    return alpha_post

# 示例:3个类别
alpha_prior = np.array([1, 1, 1])  # 均匀先验
m = np.array([30, 50, 20])  # 观测计数
alpha_post = dirichlet_update(alpha_prior, m)

print(f"先验参数: {alpha_prior}")
print(f"观测计数: {m}")
print(f"后验参数: {alpha_post}")
print(f"后验均值: {alpha_post / alpha_post.sum()}")
print(f"MLE: {m / m.sum()}")

2.2 高斯分布

2.2.1 一元高斯分布

一元高斯分布的概率密度函数为:

$$\mathcal{N}(x|\mu, \sigma^2) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left\{-\frac{(x-\mu)^2}{2\sigma^2}\right\}$$

关键性质:

  • 均值:$\mathbb{E}[x] = \mu$
  • 方差:$\text{var}[x] = \sigma^2$
  • 熵:$H[x] = \frac{1}{2} \ln(2\pi e \sigma^2)$
  • 两个高斯分布的乘积仍然是高斯分布
  • 高斯分布的线性变换仍然是高斯分布

2.2.2 多元高斯分布

多元高斯分布的概率密度函数为:

$$\mathcal{N}(\mathbf{x}|\boldsymbol{\mu}, \boldsymbol{\Sigma}) = \frac{1}{(2\pi)^{D/2} |\boldsymbol{\Sigma}|^{1/2}} \exp\left\{-\frac{1}{2}(\mathbf{x}-\boldsymbol{\mu})^T \boldsymbol{\Sigma}^{-1} (\mathbf{x}-\boldsymbol{\mu})\right\}$$

其中 $\boldsymbol{\mu}$ 是 $D$ 维均值向量,$\boldsymbol{\Sigma}$ 是 $D \times D$ 的协方差矩阵。

协方差矩阵 $\boldsymbol{\Sigma}$ 的几何意义:

  • 特征向量决定了高斯等密度椭圆的方向
  • 特征值的平方根决定了椭圆在各方向上的半轴长度
  • 行列式 $|\boldsymbol{\Sigma}|$ 决定了椭圆的体积
python
def multivariate_gaussian_sample(mu, Sigma, n_samples=1000):
    """从多元高斯分布中采样"""
    return np.random.multivariate_normal(mu, Sigma, n_samples)

def visualize_gaussian_contours():
    """可视化多元高斯分布的等密度轮廓"""
    # 不同协方差结构的2D高斯分布
    configs = [
        (np.array([0, 0]), np.array([[1, 0], [0, 1]]), "各向同性"),
        (np.array([0, 0]), np.array([[4, 0], [0, 1]]), "各向异性"),
        (np.array([0, 0]), np.array([[2, 1.5], [1.5, 2]]), "相关"),
    ]
    
    fig, axes = plt.subplots(1, 3, figsize=(15, 5))
    
    for ax, (mu, Sigma, title) in zip(axes, configs):
        samples = multivariate_gaussian_sample(mu, Sigma, 2000)
        ax.scatter(samples[:, 0], samples[:, 1], alpha=0.1, s=5)
        
        # 绘制等密度椭圆
        eigenvalues, eigenvectors = np.linalg.eigh(Sigma)
        angle = np.degrees(np.arctan2(eigenvectors[1, 0], eigenvectors[0, 0]))
        for n_std in [1, 2, 3]:
            width = 2 * n_std * np.sqrt(eigenvalues[0])
            height = 2 * n_std * np.sqrt(eigenvalues[1])
            ellipse = plt.Ellipse(mu, width, height, angle=angle, 
                                  fill=False, linewidth=2-n_std*0.5)
            ax.add_patch(ellipse)
        
        ax.set_title(title)
        ax.set_xlim(-6, 6)
        ax.set_ylim(-6, 6)
        ax.set_aspect('equal')
        ax.grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('gaussian_contours.png', dpi=150)
    plt.close()

visualize_gaussian_contours()

2.2.3 条件高斯与边缘高斯

多元高斯分布的一个优美性质是:条件分布和边缘分布仍然是高斯分布。

设 $\mathbf{x} = (\mathbf{x}_a, \mathbf{x}_b)$ 服从联合高斯分布 $\mathcal{N}(\boldsymbol{\mu}, \boldsymbol{\Sigma})$,则:

  • 边缘分布:$p(\mathbf{x}_a) = \mathcal{N}(\mathbf{x}_a|\boldsymbol{\mu}_a, \boldsymbol{\Sigma}_{aa})$
  • 条件分布:$p(\mathbf{x}_b|\mathbf{x}_a) = \mathcal{N}(\mathbf{x}_b|\boldsymbol{\mu}_{b|a}, \boldsymbol{\Sigma}_{b|a})$

其中:

  • $\boldsymbol{\mu}_{b|a} = \boldsymbol{\mu}_b + \boldsymbol{\Sigma}_{ba} \boldsymbol{\Sigma}_{aa}^{-1} (\mathbf{x}_a - \boldsymbol{\mu}_a)$
  • $\boldsymbol{\Sigma}_{b|a} = \boldsymbol{\Sigma}_{bb} - \boldsymbol{\Sigma}_{ba} \boldsymbol{\Sigma}_{aa}^{-1} \boldsymbol{\Sigma}_{ab}$

这些性质在图模型(第8章)和卡尔曼滤波中起着核心作用。

2.3 参数估计

2.3.1 最大似然估计

最大似然估计(Maximum Likelihood Estimation, MLE)是最常用的参数估计方法。其核心思想是:选择使观测数据出现概率最大的参数值。

对于独立同分布的数据 $\mathbf{X} = \{x_1, \ldots, x_N\}$,似然函数为:

$$p(\mathbf{X}|\boldsymbol{\theta}) = \prod_{n=1}^{N} p(x_n|\boldsymbol{\theta})$$

对数似然函数为:

$$\ln p(\mathbf{X}|\boldsymbol{\theta}) = \sum_{n=1}^{N} \ln p(x_n|\boldsymbol{\theta})$$

高斯分布的MLE:

$$\mu_{ML} = \frac{1}{N} \sum_{n=1}^{N} x_n$$

$$\sigma_{ML}^2 = \frac{1}{N} \sum_{n=1}^{N} (x_n - \mu_{ML})^2$$

注意:$\sigma_{ML}^2$ 是有偏估计,无偏估计为 $\frac{1}{N-1} \sum (x_n - \mu_{ML})^2$。当 $N$ 很大时,偏差可以忽略。

python
def mle_gaussian(x):
    """高斯分布的最大似然估计"""
    mu_ml = np.mean(x)
    sigma2_ml = np.mean((x - mu_ml) ** 2)
    sigma2_unbiased = np.sum((x - mu_ml) ** 2) / (len(x) - 1)
    return mu_ml, sigma2_ml, sigma2_unbiased

# 示例:从小样本估计高斯参数
np.random.seed(42)
true_mu, true_sigma = 3.0, 2.0
data = np.random.normal(true_mu, true_sigma, 20)

mu_ml, sigma2_ml, sigma2_unbiased = mle_gaussian(data)
print(f"真实参数: μ={true_mu}, σ²={true_sigma**2}")
print(f"MLE估计: μ={mu_ml:.3f}, σ²={sigma2_ml:.3f}")
print(f"无偏估计: σ²={sigma2_unbiased:.3f}")
print(f"偏差: {abs(sigma2_ml - true_sigma**2):.3f} (MLE) vs {abs(sigma2_unbiased - true_sigma**2):.3f} (无偏)")

2.3.2 最大似然估计的渐近性质

MLE 具有以下重要的渐近性质(当 $N \to \infty$):

  • 一致性:$\hat{\boldsymbol{\theta}}_{ML} \xrightarrow{P} \boldsymbol{\theta}^*$(收敛到真实参数)
  • 渐近正态性:$\hat{\boldsymbol{\theta}}_{ML} \sim \mathcal{N}(\boldsymbol{\theta}^, \mathbf{I}^{-1}(\boldsymbol{\theta}^))$
  • 有效性:达到Cramér-Rao下界

其中 $\mathbf{I}(\boldsymbol{\theta})$ 是Fisher信息矩阵:

$$\mathbf{I}(\boldsymbol{\theta}) = -\mathbb{E}\left[\frac{\partial^2}{\partial \boldsymbol{\theta} \partial \boldsymbol{\theta}^T} \ln p(x|\boldsymbol{\theta})\right]$$

2.3.3 贝叶斯估计

贝叶斯估计将参数视为随机变量,通过贝叶斯定理计算后验分布:

$$p(\boldsymbol{\theta}|\mathbf{X}) = \frac{p(\mathbf{X}|\boldsymbol{\theta}) p(\boldsymbol{\theta})}{p(\mathbf{X})}$$

与 MLE 不同,贝叶斯估计:

  • 引入了先验知识 $p(\boldsymbol{\theta})$
  • 输出参数的完整后验分布,而非单个点估计
  • 天然防止过拟合(先验起到正则化作用)

高斯分布(已知方差)的贝叶斯估计:

设先验为 $p(\mu) = \mathcal{N}(\mu|\mu_0, \sigma_0^2)$,则后验为:

$$p(\mu|\mathbf{X}) = \mathcal{N}(\mu|\mu_N, \sigma_N^2)$$

其中:

  • $\frac{1}{\sigma_N^2} = \frac{1}{\sigma_0^2} + \frac{N}{\sigma^2}$
  • $\mu_N = \sigma_N^2 \left(\frac{\mu_0}{\sigma_0^2} + \frac{N \mu_{ML}}{\sigma^2}\right)$

后验均值是先验均值和MLE的加权平均,权重分别正比于先验精度和数据精度。

python
def bayesian_gaussian_mean(x, sigma, mu_0, sigma_0):
    """已知方差的高斯均值贝叶斯估计"""
    N = len(x)
    mu_ml = np.mean(x)
    
    # 后验参数
    precision_post = 1/sigma_0**2 + N/sigma**2
    sigma_N = np.sqrt(1/precision_post)
    mu_N = sigma_N**2 * (mu_0/sigma_0**2 + N*mu_ml/sigma**2)
    
    return mu_N, sigma_N

# 示例:不同样本量下的贝叶斯估计
np.random.seed(42)
true_mu = 5.0
sigma = 2.0

mu_0 = 0.0  # 先验均值
sigma_0 = 3.0  # 先验标准差

for N in [5, 20, 100, 1000]:
    x = np.random.normal(true_mu, sigma, N)
    mu_N, sigma_N = bayesian_gaussian_mean(x, sigma, mu_0, sigma_0)
    print(f"N={N:4d}: 后验均值={mu_N:.3f}, 后验标准差={sigma_N:.4f}, MLE={np.mean(x):.3f}")

2.4 指数族分布

2.4.1 定义

指数族分布是一类具有统一形式的概率分布:

$$p(\mathbf{x}|\boldsymbol{\eta}) = h(\mathbf{x}) g(\boldsymbol{\eta}) \exp\{\boldsymbol{\eta}^T \mathbf{u}(\mathbf{x})\}$$

其中:

  • $\boldsymbol{\eta}$ 是自然参数(Natural Parameter)
  • $\mathbf{u}(\mathbf{x})$ 是充分统计量(Sufficient Statistic)
  • $g(\boldsymbol{\eta})$ 是归一化系数的倒数
  • $h(\mathbf{x})$ 是与参数无关的因子

属于指数族的分布包括:高斯分布、二项分布、多项式分布、泊松分布、Gamma分布、Beta分布等。

2.4.2 指数族的统一性质

指数族分布具有以下统一的性质:

充分统计量的期望:$\mathbb{E}[\mathbf{u}(\mathbf{x})] = -\frac{\partial \ln g(\boldsymbol{\eta})}{\partial \boldsymbol{\eta}}$

充分统计量的方差:$\text{var}[\mathbf{u}(\mathbf{x})] = -\frac{\partial^2 \ln g(\boldsymbol{\eta})}{\partial \boldsymbol{\eta} \partial \boldsymbol{\eta}^T}$

最大似然估计:$\mathbf{u}(\mathbf{x})$ 的样本均值等于其期望值

共轭先验:指数族分布的共轭先验也有统一的形式

python
def exponential_family_properties():
    """演示指数族分布的统一性质"""
    
    # 高斯分布(已知方差sigma^2=1)作为指数族
    # p(x|mu) = (2*pi)^{-1/2} exp{-1/2 * (x-mu)^2}
    #         = (2*pi)^{-1/2} exp{-mu^2/2} * exp{mu*x - x^2/2}
    # 自然参数: eta = mu
    # 充分统计量: u(x) = x
    # g(eta) = exp{-eta^2/2}
    # h(x) = (2*pi)^{-1/2} * exp{-x^2/2}
    
    # 验证: E[u(x)] = -d ln g(eta) / d eta = eta = mu
    mu = 3.0
    print(f"高斯分布(μ={mu}, σ²=1):")
    print(f"  自然参数 η = μ = {mu}")
    print(f"  充分统计量 u(x) = x")
    print(f"  E[u(x)] = η = {mu}")
    
    # 二项分布作为指数族
    # Bin(m|N, mu) = C(N,m) * mu^m * (1-mu)^{N-m}
    #              = C(N,m) * (1-mu)^N * exp{m * ln(mu/(1-mu))}
    # 自然参数: eta = ln(mu/(1-mu)) (logit)
    # 充分统计量: u(m) = m
    
    N_trials = 10
    mu_binom = 0.3
    eta_binom = np.log(mu_binom / (1 - mu_binom))
    print(f"\n二项分布(N={N_trials}, μ={mu_binom}):")
    print(f"  自然参数 η = logit(μ) = {eta_binom:.4f}")
    print(f"  充分统计量 u(m) = m")
    print(f"  E[u(m)] = N*μ = {N_trials * mu_binom}")
    
exponential_family_properties()

2.5 非参数方法

2.5.1 核密度估计

核密度估计(Kernel Density Estimation, KDE)不假设数据服从特定的分布形式,而是用数据本身来估计概率密度:

$$p(x) = \frac{1}{N} \sum_{n=1}^{N} K(x - x_n | h)$$

其中 $K(\cdot|h)$ 是核函数,$h$ 是带宽参数。最常用的是高斯核:

$$K(x|h) = \frac{1}{\sqrt{2\pi}h} \exp\left\{-\frac{x^2}{2h^2}\right\}$$

带宽 $h$ 的选择至关重要:

  • $h$ 太小:密度估计过于"尖锐",噪声大(高方差)
  • $h$ 太大:密度估计过于"平滑",丢失细节(高偏差)
python
def kernel_density_estimate(x_data, x_grid, bandwidth):
    """高斯核密度估计"""
    N = len(x_data)
    density = np.zeros_like(x_grid)
    for xi in x_data:
        density += stats.norm.pdf(x_grid, loc=xi, scale=bandwidth)
    density /= N
    return density

# 示例:不同带宽的效果
np.random.seed(42)
# 混合分布:两个高斯的混合
data = np.concatenate([
    np.random.normal(-2, 0.5, 100),
    np.random.normal(2, 0.8, 150)
])

x_grid = np.linspace(-5, 5, 200)

fig, axes = plt.subplots(1, 3, figsize=(15, 4))
for ax, bw in zip(axes, [0.1, 0.5, 2.0]):
    density = kernel_density_estimate(data, x_grid, bw)
    ax.hist(data, bins=30, density=True, alpha=0.3, color='gray')
    ax.plot(x_grid, density, 'b-', linewidth=2)
    ax.set_title(f'bandwidth={bw}')
    ax.set_ylim(0, 0.5)
    ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig('kde_bandwidth.png', dpi=150)
plt.close()

2.5.2 K近邻密度估计

K近邻方法通过考虑数据点周围的局部密度来进行密度估计:

$$p(\mathbf{x}) = \frac{K}{N V}$$

其中 $K$ 是落入区域 $\mathcal{V}$ 的点数,$V$ 是区域 $\mathcal{V}$ 的体积。

K近邻分类器将新样本分配到其 $K$ 个最近邻中多数所属的类别。

python
def knn_density_estimate(x_data, x_query, K):
    """K近邻密度估计"""
    from scipy.spatial import KDTree
    tree = KDTree(x_data.reshape(-1, 1))
    distances, _ = tree.query(x_query, k=K)
    # 区域体积 = 2 * max_distance (1D情况)
    V = 2 * distances[:, -1]
    density = K / (len(x_data) * V)
    return density

# 示例
np.random.seed(42)
data = np.random.normal(0, 1, 200)
x_query = np.linspace(-3, 3, 50)
density = knn_density_estimate(data, x_query, K=10)

print(f"KNN密度估计在 x=0 处的值: {density[len(density)//2]:.4f}")
print(f"理论高斯密度在 x=0 处的值: {stats.norm.pdf(0):.4f}")

2.6 学生t分布

2.6.1 定义与性质

学生t分布是对异常值更鲁棒的分布,其概率密度函数为:

$$\text{St}(x|\mu, \lambda, \nu) = \frac{\Gamma(\nu/2 + 1/2)}{\Gamma(\nu/2)} \left(\frac{\lambda}{\pi\nu}\right)^{1/2} \left[1 + \frac{\lambda(x-\mu)^2}{\nu}\right]^{-\nu/2 - 1/2}$$

其中 $\mu$ 是位置参数,$\lambda$ 是精度参数,$\nu$ 是自由度。

当 $\nu \to \infty$ 时,t分布趋向于高斯分布;当 $\nu$ 较小时,t分布有更厚的尾部,对异常值更鲁棒。

python
def compare_gaussian_and_t():
    """比较高斯分布和t分布对异常值的鲁棒性"""
    x = np.linspace(-5, 5, 200)
    
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))
    
    # 左图:不同自由度的t分布
    for nu in [1, 3, 10, 30]:
        y = stats.t.pdf(x, df=nu)
        axes[0].plot(x, y, label=f'ν={nu}')
    axes[0].plot(x, stats.norm.pdf(x), 'k--', label='Gaussian')
    axes[0].set_title('t分布 vs 高斯分布')
    axes[0].legend()
    axes[0].grid(True, alpha=0.3)
    
    # 右图:拟合数据(含异常值)
    np.random.seed(42)
    data_clean = np.random.normal(0, 1, 100)
    data_with_outliers = np.concatenate([data_clean, [5, -5, 6, -6]])
    
    # 用高斯和t分布分别拟合
    mu_g, sigma_g = stats.norm.fit(data_with_outliers)
    mu_t, sigma_t, nu_t = stats.t.fit(data_with_outliers)
    
    axes[1].hist(data_with_outliers, bins=20, density=True, alpha=0.5, label='Data')
    axes[1].plot(x, stats.norm.pdf(x, mu_g, sigma_g), 'b-', label=f'Gaussian(μ={mu_g:.2f})', linewidth=2)
    axes[1].plot(x, stats.t.pdf(x, df=nu_t, loc=mu_t, scale=sigma_t), 'r-', label=f't(ν={nu_t:.1f}, μ={mu_t:.2f})', linewidth=2)
    axes[1].set_title('对含异常值数据的拟合')
    axes[1].legend()
    axes[1].grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('t_vs_gaussian.png', dpi=150)
    plt.close()

compare_gaussian_and_t()

三、实战案例

3.1 完整的参数估计比较实验

python
def parameter_estimation_comparison():
    """比较MLE、MAP和贝叶斯估计"""
    np.random.seed(42)
    
    # 真实参数
    true_mu = 3.0
    true_sigma = 2.0
    
    # 不同样本量
    sample_sizes = [5, 10, 30, 100, 500]
    n_experiments = 50
    
    results = {n: {'MLE': [], 'MAP': [], 'Bayes': []} for n in sample_sizes}
    
    for n in sample_sizes:
        for _ in range(n_experiments):
            data = np.random.normal(true_mu, true_sigma, n)
            
            # MLE
            mu_mle = np.mean(data)
            
            # MAP (with prior N(0, 5^2))
            sigma_0 = 5.0
            mu_0 = 0.0
            precision_data = n / true_sigma**2
            precision_prior = 1 / sigma_0**2
            mu_map = (precision_data * np.mean(data) + precision_prior * mu_0) / (precision_data + precision_prior)
            
            # 贝叶斯后验均值
            mu_bayes = mu_map  # 对于高斯模型,MAP和后验均值相同
            
            results[n]['MLE'].append(mu_mle)
            results[n]['MAP'].append(mu_map)
            results[n]['Bayes'].append(mu_bayes)
    
    print(f"{'N':>5} {'MLE偏差':>10} {'MLE方差':>10} {'MAP偏差':>10} {'MAP方差':>10}")
    print("-" * 55)
    for n in sample_sizes:
        mle_bias = np.mean(results[n]['MLE']) - true_mu
        mle_var = np.var(results[n]['MLE'])
        map_bias = np.mean(results[n]['MAP']) - true_mu
        map_var = np.var(results[n]['MAP'])
        print(f"{n:5d} {mle_bias:10.4f} {mle_var:10.4f} {map_bias:10.4f} {map_var:10.4f}")

parameter_estimation_comparison()

3.2 高斯混合模型的密度估计

python
def gaussian_mixture_density_estimation():
    """使用高斯混合模型进行密度估计"""
    from sklearn.mixture import GaussianMixture
    
    np.random.seed(42)
    
    # 生成混合分布数据
    N = 500
    data = np.concatenate([
        np.random.normal(-3, 1, N // 3),
        np.random.normal(1, 0.5, N // 3),
        np.random.normal(4, 1.5, N // 3)
    ]).reshape(-1, 1)
    
    # 不同组件数的GMM
    fig, axes = plt.subplots(1, 3, figsize=(15, 4))
    x_grid = np.linspace(-8, 8, 200).reshape(-1, 1)
    
    for ax, n_components in zip(axes, [1, 3, 5]):
        gmm = GaussianMixture(n_components=n_components, random_state=42)
        gmm.fit(data)
        
        density = np.exp(gmm.score_samples(x_grid))
        
        ax.hist(data, bins=30, density=True, alpha=0.3, color='gray', label='Data')
        ax.plot(x_grid, density, 'b-', linewidth=2, label=f'GMM(K={n_components})')
        ax.set_title(f'K={n_components}, BIC={gmm.bic(data):.0f}')
        ax.legend()
        ax.grid(True, alpha=0.3)
    
    plt.tight_layout()
    plt.savefig('gmm_density.png', dpi=150)
    plt.close()
    
    # 使用BIC选择最优组件数
    bic_scores = []
    for K in range(1, 8):
        gmm = GaussianMixture(n_components=K, random_state=42)
        gmm.fit(data)
        bic_scores.append(gmm.bic(data))
        print(f"K={K}: BIC={gmm.bic(data):.1f}, AIC={gmm.aic(data):.1f}")
    
    best_K = np.argmin(bic_scores) + 1
    print(f"\nBIC选择的最优K: {best_K}")

gaussian_mixture_density_estimation()

3.3 贝叶斯预测与不确定性量化

python
def bayesian_prediction_with_uncertainty():
    """贝叶斯预测:展示预测不确定性的量化"""
    np.random.seed(42)
    
    # 训练数据
    N = 15
    x_train = np.sort(np.random.uniform(-3, 3, N))
    y_train = np.sin(x_train) + np.random.normal(0, 0.2, N)
    
    # 贝叶斯线性回归(使用多项式基函数)
    M = 3  # 多项式阶数
    alpha = 1.0  # 先验精度
    beta = 5.0  # 噪声精度
    
    Phi_train = np.column_stack([x_train ** j for j in range(M + 1)])
    
    # 后验参数
    S_N_inv = alpha * np.eye(M + 1) + beta * Phi_train.T @ Phi_train
    S_N = np.linalg.inv(S_N_inv)
    m_N = beta * S_N @ Phi_train.T @ y_train
    
    # 测试点
    x_test = np.linspace(-4, 4, 200)
    Phi_test = np.column_stack([x_test ** j for j in range(M + 1)])
    
    # 预测分布
    pred_mean = Phi_test @ m_N
    pred_var = np.array([1/beta + Phi_test[i] @ S_N @ Phi_test[i] for i in range(len(x_test))])
    pred_std = np.sqrt(pred_var)
    
    # 可视化
    fig, ax = plt.subplots(figsize=(10, 6))
    
    ax.scatter(x_train, y_train, c='red', s=50, zorder=5, label='Training data')
    ax.plot(x_test, pred_mean, 'b-', linewidth=2, label='Predictive mean')
    ax.fill_between(x_test, pred_mean - 2*pred_std, pred_mean + 2*pred_std, 
                    alpha=0.2, color='blue', label='95% predictive interval')
    ax.plot(x_test, np.sin(x_test), 'g--', linewidth=2, label='True function')
    
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title('Bayesian Polynomial Regression with Predictive Uncertainty')
    ax.legend()
    ax.grid(True, alpha=0.3)
    ax.set_xlim(-4, 4)
    
    plt.tight_layout()
    plt.savefig('bayesian_prediction.png', dpi=150)
    plt.close()
    
    # 分析不确定性
    print("预测不确定性分析:")
    for x_val in [-3, -1, 0, 1, 3]:
        idx = np.argmin(np.abs(x_test - x_val))
        print(f"  x={x_val:5.1f}: 预测均值={pred_mean[idx]:.3f}, "
              f"标准差={pred_std[idx]:.3f}, "
              f"模型不确定性={np.sqrt(pred_var[idx] - 1/beta):.3f}")

bayesian_prediction_with_uncertainty()

四、本章小结

第2章系统介绍了模式识别中最常用的概率分布和参数估计方法:

离散分布:二项分布和多项式分布分别建模二值和多值离散数据。Beta分布和Dirichlet分布分别是它们的共轭先验,使得贝叶斯更新具有解析形式。

高斯分布:作为最重要的连续分布,高斯分布在模式识别中无处不在。多元高斯分布的条件分布和边缘分布仍然是高斯分布,这一性质在图模型中至关重要。

参数估计:最大似然估计简单但容易过拟合(特别是小样本情况)。贝叶斯估计通过引入先验分布,提供了更鲁棒的参数估计和完整的不确定性量化。

指数族分布:提供了一个统一的框架,涵盖了大多数常用的概率分布。指数族的性质使得我们可以用相同的数学工具处理不同的分布。

非参数方法:核密度估计和K近邻方法不假设特定的分布形式,提供了灵活的密度估计能力,但需要仔细选择带宽参数。

学生t分布:相比高斯分布,t分布具有更厚的尾部,对异常值更鲁棒,是处理含噪声数据的有效工具。

这些概率分布和估计方法构成了后续章节的数学基础。第3章的线性回归可以理解为对条件高斯分布的建模,第8章的图模型利用条件高斯的性质进行高效推断,第9章的高斯混合模型直接使用了本章的概率分布。


五、思考与练习

思考题

为什么最大似然估计在小样本情况下容易过拟合?请从偏差-方差分解的角度分析。

共轭先验的优点是什么?是否存在缺点?在什么情况下你可能不想使用共轭先验?

多元高斯分布的协方差矩阵有 $O(D^2)$ 个自由参数。当维度 $D$ 很大时,这会带来什么问题?有哪些解决方案?

核密度估计的带宽选择和正则化系数有什么相似之处?

指数族分布在变分推断中扮演什么角色?为什么它如此重要?

编程练习

Beta-Bernoulli模型:实现一个完整的贝叶斯伯努利模型,使用Beta先验。在不同样本量下比较MLE和贝叶斯估计的结果,验证"大数据量下两者趋同"的结论。

多元高斯MLE:从多元高斯分布中生成数据,实现最大似然估计,并可视化估计的等密度椭圆与真实椭圆的差异。研究样本量对估计精度的影响。

核密度估计的带宽选择:实现交叉验证方法自动选择最优带宽,并与Silverman法则的结果进行比较。


2/10概率分布
0%