最大似然估计(MLE)

最大似然估计(Maximum Likelihood Estimation, MLE)是统计学中最重要的参数估计方法之一。它通过最大化观测数据的似然函数来估计参数值,是许多机器学习算法的理论基础。1

1. 似然函数

1.1 定义

设数据 是独立同分布(i.i.d.)的观测,假设它们来自参数化分布 ,其中 是未知参数。

似然函数定义为给定参数 时,观测到数据 的概率:

对数似然函数

注意:使用对数似然的原因是避免数值下溢(连乘容易产生极小值)。

1.2 似然 vs 概率

概念定义变量
概率 是变量, 是固定的
似然 是变量, 是固定的

关键理解:似然不是概率!它衡量的是在不同参数值下,观察到当前数据的”可能性”。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
 
def likelihood_vs_probability():
    """可视化似然与概率的区别"""
    
    # 观测数据
    data = np.array([2.3, 2.5, 2.1, 2.7, 2.4])
    true_mu = 2.5
    true_sigma = 0.3
    
    # 参数空间
    mus = np.linspace(1.5, 3.5, 100)
    
    # 计算似然(固定数据,改变均值参数)
    likelihoods = []
    for mu in mus:
        # 似然 = p(data | mu, sigma)
        log_lik = sum(norm.logpdf(data, loc=mu, scale=true_sigma))
        likelihoods.append(np.exp(log_lik))
    
    plt.figure(figsize=(10, 4))
    
    plt.subplot(1, 2, 1)
    plt.plot(mus, likelihoods, 'b-')
    plt.axvline(true_mu, color='r', linestyle='--', label=f'True μ={true_mu}')
    plt.xlabel('Parameter μ')
    plt.ylabel('Likelihood')
    plt.title('Likelihood as Function of μ (data fixed)')
    plt.legend()
    
    plt.subplot(1, 2, 2)
    x = np.linspace(0, 5, 200)
    plt.plot(x, norm.pdf(x, true_mu, true_sigma), 'b-')
    plt.scatter(data, [0.01]*len(data), color='r', zorder=5)
    plt.xlabel('x')
    plt.ylabel('Probability Density')
    plt.title('Probability Density (parameter fixed)')
    
    plt.tight_layout()
    plt.show()

2. MLE的定义与求解

2.1 定义

最大似然估计定义为使似然函数最大化的参数值:

2.2 求解方法

解析解

对于简单的分布(如正态分布),可以通过求导获得解析解。

示例:正态分布的MLE

,数据为

对数似然:

求偏导并令为零:

求偏导:

数值优化

对于复杂模型,使用数值优化算法:

import numpy as np
from scipy.optimize import minimize
 
def mle_numerical(X, log_pdf, param_init):
    """
    数值MLE求解
    
    Args:
        X: 观测数据
        log_pdf: 对数概率密度函数 log p(x|theta)
        param_init: 参数初始值
    
    Returns:
        最优参数估计
    """
    def neg_log_likelihood(theta):
        return -sum(log_pdf(x, theta) for x in X)
    
    result = minimize(neg_log_likelihood, param_init, method='BFGS')
    
    return result.x, -result.fun  # 参数, 最大对数似然

3. MLE的性质

3.1 一致性

定理:在一定正则条件下,当样本量 时,MLE收敛到真实参数值:

直观理解:随着数据增多,MLE越来越准确地估计真实参数。

3.2 渐近正态性

定理:在大样本情况下,MLE服从渐近正态分布:

其中 Fisher信息矩阵

3.3 渐近有效性

MLE达到了Cramer-Rao下界,即它是渐近方差最小的无偏估计量。

3.4 不变性

如果 的MLE,那么对于任意函数 的MLE。


4. Fisher信息

4.1 定义

Fisher信息衡量了参数 在数据中的信息量:

直观理解:似然函数越陡峭(曲率越大),参数的信息越多。

4.2 与方差的关系

含义:Fisher信息越大,MLE的方差越小,估计越精确。

4.3 代码实现

import numpy as np
 
def compute_fisher_information(X, log_pdf_grad, theta):
    """
    计算Fisher信息矩阵
    
    Args:
        X: 观测数据
        log_pdf_grad: 对数似然函数的梯度
        theta: 参数值
    
    Returns:
        Fisher信息矩阵
    """
    n_samples = len(X)
    gradients = np.array([log_pdf_grad(x, theta) for x in X])
    
    # Fisher信息 = 梯度的协方差矩阵
    fisher_info = np.cov(gradients.T)
    
    return fisher_info
 
def compute_fisher_analytical(n, mu_true, sigma_true):
    """
    正态分布的Fisher信息解析解
    
    对于 N(μ, σ²):
    - I(μ) = n / σ²
    - I(σ²) = n / (2σ⁴)
    """
    I_mu = n / sigma_true**2
    I_sigma2 = n / (2 * sigma_true**4)
    
    return I_mu, I_sigma2

5. 频率学派 vs 贝叶斯学派

参数估计存在两种主要范式:

5.1 核心区别

方面频率学派(Frequentist)贝叶斯学派(Bayesian)
参数性质固定但未知随机变量
先验知识不考虑通过先验分布引入
估计目标点估计 后验分布
不确定性通过渐近理论自然地融入后验分布

5.2 频率学派:MLE

频率学派认为参数是固定的,只关注点估计:

5.3 贝叶斯学派:后验估计

贝叶斯学派引入参数的先验分布 ,通过贝叶斯定理计算后验:

后验估计包括:

方法定义
MAP(最大后验)
后验均值
后验中位数

5.4 MLE与MAP的关系

当先验是均匀分布 时:

重要关系

MAP估计 = MLE估计 + 正则化项(来自先验)

import numpy as np
from scipy.optimize import minimize
 
def map_vs_mle(X, log_likelihood, log_prior, param_init):
    """
    比较MLE和MAP估计
    
    Args:
        X: 观测数据
        log_likelihood: 对数似然函数 log p(X|theta)
        log_prior: 对数先验函数 log p(theta)
        param_init: 参数初始值
    
    Returns:
        mle估计, map估计
    """
    # MLE
    def neg_ll(theta):
        return -sum(log_likelihood(x, theta) for x in X)
    
    mle_result = minimize(neg_ll, param_init, method='BFGS')
    theta_mle = mle_result.x
    
    # MAP
    def neg_map(theta):
        return -sum(log_likelihood(x, theta) for x in X) - log_prior(theta)
    
    map_result = minimize(neg_map, param_init, method='BFGS')
    theta_map = map_result.x
    
    return theta_mle, theta_map
 
# 示例:带L2正则化的线性回归
def linear_regression_mle_map(X, y, lambda_reg=0.1):
    """
    线性回归的MLE vs MAP
    
    MLE: min ||y - Xw||²
    MAP (L2): min ||y - Xw||² + λ||w||²
    """
    n_features = X.shape[1]
    
    # MLE
    w_mle = np.linalg.lstsq(X, y, rcond=None)[0]
    
    # MAP with Gaussian prior on w
    # 相当于Ridge回归
    XTX = X.T @ X
    XTy = X.T @ y
    
    # MAP: (X'X + λI)w = X'y
    w_map = np.linalg.solve(XTX + lambda_reg * np.eye(n_features), XTy)
    
    return w_mle, w_map

6. 偏差-方差权衡

6.1 MLE的偏差

MLE在大样本下无偏,但在小样本下可能有偏差。

示例:方差的MLE

这是有偏的,因为:

无偏估计是:

6.2 偏差-方差分解

对于均方误差:

估计量偏差方差MSE
MLE较小平衡
无偏估计0较大较大
MAP(强先验)大(向先验偏移)可能更小
import numpy as np
import matplotlib.pyplot as plt
 
def bias_variance_tradeoff():
    """演示偏差-方差权衡"""
    
    np.random.seed(42)
    n_samples = 50
    n_experiments = 1000
    true_theta = 0.5
    
    # 收集MLE和无偏估计的结果
    mle_estimates = []
    unbiased_estimates = []
    
    for _ in range(n_experiments):
        # 模拟数据
        X = np.random.uniform(0, 1, n_samples)
        y = true_theta * X + np.random.normal(0, 0.1, n_samples)
        
        # 简单估计器:y的均值
        mle_estimates.append(np.mean(y))
        
        # 贝叶斯MAP估计(简化版)
        # 假设先验 N(0, 1)
        posterior_mean = np.mean(y) / (1 + 1/n_samples)
        unbiased_estimates.append(2 * np.mean(y))  # 人为制造偏差
    
    mle_estimates = np.array(mle_estimates)
    
    # 计算统计量
    print(f"MLE: Mean={mle_estimates.mean():.4f}, Var={mle_estimates.var():.4f}")
    print(f"MSE MLE: {((mle_estimates - true_theta)**2).mean():.4f}")
    
    # 可视化
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))
    
    axes[0].hist(mle_estimates, bins=30, alpha=0.7, edgecolor='black')
    axes[0].axvline(true_theta, color='r', linestyle='--', label=f'True θ={true_theta}')
    axes[0].axvline(mle_estimates.mean(), color='g', linestyle='-', label=f'Estimated Mean')
    axes[0].set_title('Distribution of MLE Estimates')
    axes[0].legend()
    
    axes[1].scatter(range(n_experiments), mle_estimates, alpha=0.3, s=5)
    axes[1].axhline(true_theta, color='r', linestyle='--')
    axes[1].set_xlabel('Experiment')
    axes[1].set_ylabel('Estimate')
    axes[1].set_title('MLE Estimates Across Experiments')
    
    plt.tight_layout()
    plt.show()

7. 常用分布的MLE

7.1 伯努利分布

,观测到 次成功, 次失败。

7.2 泊松分布

,数据为

7.3 指数分布

7.4 均匀分布

这个估计是有偏的!无偏估计为:

def mle_common_distributions(data):
    """常见分布的MLE估计"""
    
    results = {}
    
    # 伯努利
    k = sum(data)  # 成功次数
    n = len(data)  # 总次数
    results['bernoulli'] = {'p': k / n}
    
    # 泊松
    results['poisson'] = {'lambda': np.mean(data)}
    
    # 指数分布
    results['exponential'] = {'lambda': len(data) / sum(data)}
    
    # 均匀分布
    results['uniform'] = {'theta': max(data), 'theta_unbiased': (len(data) + 1) / len(data) * max(data)}
    
    # 正态分布
    results['normal'] = {
        'mu': np.mean(data),
        'sigma2_mle': np.var(data),  # 有偏
        'sigma2_unbiased': np.var(data, ddof=1)  # 无偏
    }
    
    return results

8. MLE的高级主题

8.1 约束优化

当参数有约束时(如概率必须在[0,1]之间):

from scipy.optimize import minimize
 
def mle_constrained(X, log_pdf, param_init, bounds):
    """
    带约束的MLE
    
    Args:
        bounds: 参数边界 [(min, max), ...]
    """
    def neg_log_likelihood(theta):
        return -sum(log_pdf(x, theta) for x in X)
    
    result = minimize(
        neg_log_likelihood, 
        param_init, 
        method='L-BFGS-B',
        bounds=bounds
    )
    
    return result.x
 
# 示例:概率参数 p ∈ [0, 1]
# bounds = [(0, 1)]

8.2 期望最大化(EM)与MLE

当数据含隐变量时,直接MLE不可行,需要EM算法。

详见 EM算法

8.3 经验风险最小化视角

在机器学习中,MLE等价于经验风险最小化

这与交叉熵损失完全一致!


9. 代码实现

import numpy as np
from scipy.optimize import minimize
from scipy.stats import norm, bernoulli, poisson, expon
 
class MLEEstimator:
    """通用的MLE估计器"""
    
    def __init__(self, distribution='normal'):
        self.distribution = distribution
        self.params_ = None
    
    def fit(self, data):
        """根据分布类型拟合MLE"""
        
        if self.distribution == 'normal':
            self.params_ = self._fit_normal(data)
        elif self.distribution == 'bernoulli':
            self.params_ = self._fit_bernoulli(data)
        elif self.distribution == 'poisson':
            self.params_ = self._fit_poisson(data)
        elif self.distribution == 'exponential':
            self.params_ = self._fit_exponential(data)
        
        return self
    
    def _fit_normal(self, data):
        """正态分布MLE"""
        mu_hat = np.mean(data)
        sigma2_hat = np.var(data)  # MLE(有偏)
        sigma2_unbiased = np.var(data, ddof=1)
        return {'mu': mu_hat, 'sigma2': sigma2_hat, 'sigma2_unbiased': sigma2_unbiased}
    
    def _fit_bernoulli(self, data):
        """伯努利分布MLE"""
        p_hat = np.mean(data)
        return {'p': p_hat}
    
    def _fit_poisson(self, data):
        """泊松分布MLE"""
        lambda_hat = np.mean(data)
        return {'lambda': lambda_hat}
    
    def _fit_exponential(self, data):
        """指数分布MLE"""
        lambda_hat = len(data) / sum(data)
        return {'lambda': lambda_hat}
    
    def predict(self, x):
        """预测概率密度/质量"""
        if self.distribution == 'normal':
            return norm.pdf(x, self.params_['mu'], np.sqrt(self.params_['sigma2']))
        elif self.distribution == 'bernoulli':
            return self.params_['p'] ** x * (1 - self.params_['p']) ** (1 - x)
        elif self.distribution == 'poisson':
            return poisson.pmf(x, self.params_['lambda'])
        elif self.distribution == 'exponential':
            return expon.pdf(x, scale=1/self.params_['lambda'])
    
    def log_likelihood(self, data):
        """计算对数似然"""
        return sum(np.log(self.predict(x) + 1e-10) for x in data)

10. 参考文献


相关阅读

Footnotes

  1. Casella, G., & Berger, R. L. (2002). Statistical Inference. Duxbury.