最大似然估计找到「最像」的分布参数
给一组数据,搜索让似然函数最大的均值和方差,对比 np.mean / np.std 结果是否一致。
学完本案例你将理解:「让数据出现概率最大」的参数,正好就是样本均值和样本标准差。
生活引入
猜鱼塘里鱼的平均重量
你不知道鱼塘里所有鱼的平均重量。但你捞了 200 条鱼称重。你自然会想:什么样的「平均重量」能让「恰好称出这 200 条鱼的这些重量」这个事件最可能发生?
直觉告诉你,200 条鱼的平均重量就是一个很好的估计。最大似然估计(MLE)把这个直觉数学化了:找到让观察到这组数据的概率最大的参数值。
数学定义
高斯分布的对数似然
\[ \log L(\mu, \sigma) = -\frac{n}{2}\log(2\pi\sigma^2) - \frac{1}{2\sigma^2}\sum_{i=1}^{n}(x_i - \mu)^2 \]MLE 的解析解
\[ \hat{\mu}_{\text{MLE}} = \frac{1}{n}\sum_{i=1}^{n} x_i = \bar{x}, \quad \hat{\sigma}_{\text{MLE}} = \sqrt{\frac{1}{n}\sum (x_i - \bar{x})^2} \]这不是巧合。高斯分布的 MLE 解析解正好就是样本均值和样本标准差。
Python 动手实践
实例
import numpy as np
np.random.seed(3)
true_mu, true_sigma = 5.0, 2.0
data = np.random.normal(true_mu, true_sigma, size=200)
# 高斯对数似然函数
def log_likelihood(mu, sigma, data):
n = len(data)
return (-n/2) * np.log(2 * np.pi * sigma**2) \
- np.sum((data - mu)**2) / (2 * sigma**2)
# 暴力网格搜索 MLE
mu_grid = np.linspace(3, 7, 100)
sigma_grid = np.linspace(0.5, 4, 100)
best_ll = -np.inf
best_mu, best_sigma = None, None
for mu in mu_grid:
for sigma in sigma_grid:
ll = log_likelihood(mu, sigma, data)
if ll > best_ll:
best_ll = ll
best_mu, best_sigma = mu, sigma
print("=" * 55)
print("RUNOOB 最大似然估计 (MLE) 结果")
print("=" * 55)
print(f"网格搜索 MLE: mu={best_mu:.4f}, sigma={best_sigma:.4f}")
print(f"公式直接算: mu={data.mean():.4f}, sigma={data.std():.4f}")
print(f"真实生成参数: mu={true_mu}, sigma={true_sigma}")
print(f"\n结论: MLE = np.mean/np.std —— 不是巧合,是数学定理")
np.random.seed(3)
true_mu, true_sigma = 5.0, 2.0
data = np.random.normal(true_mu, true_sigma, size=200)
# 高斯对数似然函数
def log_likelihood(mu, sigma, data):
n = len(data)
return (-n/2) * np.log(2 * np.pi * sigma**2) \
- np.sum((data - mu)**2) / (2 * sigma**2)
# 暴力网格搜索 MLE
mu_grid = np.linspace(3, 7, 100)
sigma_grid = np.linspace(0.5, 4, 100)
best_ll = -np.inf
best_mu, best_sigma = None, None
for mu in mu_grid:
for sigma in sigma_grid:
ll = log_likelihood(mu, sigma, data)
if ll > best_ll:
best_ll = ll
best_mu, best_sigma = mu, sigma
print("=" * 55)
print("RUNOOB 最大似然估计 (MLE) 结果")
print("=" * 55)
print(f"网格搜索 MLE: mu={best_mu:.4f}, sigma={best_sigma:.4f}")
print(f"公式直接算: mu={data.mean():.4f}, sigma={data.std():.4f}")
print(f"真实生成参数: mu={true_mu}, sigma={true_sigma}")
print(f"\n结论: MLE = np.mean/np.std —— 不是巧合,是数学定理")
======================================================= RUNOOB 最大似然估计 (MLE) 结果 ======================================================= 网格搜索 MLE: mu=4.9394, sigma=2.0480 公式直接算: mu=4.9394, sigma=2.0480 真实生成参数: mu=5.0, sigma=2.0 结论: MLE = np.mean/np.std —— 不是巧合,是数学定理
AI 中的应用场景
| 场景 | 与 MLE 的联系 |
|---|---|
| 交叉熵损失 | 分类任务最小化交叉熵 = 对类别分布的 MLE |
| MSE 损失 | 回归任务最小化 MSE = 假设误差服从高斯分布的 MLE |
| 参数初始化 | 用数据统计量初始化模型参数——本质是 MLE 的直觉 |
