模型选择准则:AIC、BIC

一句话概述

AIC(赤池信息准则)和 BIC(贝叶斯信息准则)是统计学中两个经典的模型选择准则,用于在模型拟合优度和复杂度之间取得平衡。AIC = −2·ln(L) + 2k,BIC = −2·ln(L) + k·ln(n),其中 L 是最大似然值,k 是模型参数数量,n 是样本量。AIC 和 BIC 都惩罚模型复杂度,但 BIC 的惩罚随样本量增加而加重,因此倾向于选择更简单的模型。在现代 ML 中,交叉验证已经很大程度上取代了 AIC/BIC,但理解它们有助于深入理解模型选择的核心思想。

💡 核心要点:① AIC 和 BIC 是信息论和贝叶斯框架下的模型选择准则 ② AIC 的目标是最小化预测误差的期望,BIC 的目标是选择真实模型的后验概率最大者 ③ BIC 对复杂度的惩罚随样本量增加而加重(k·ln(n) vs 2k),倾向于选择更简单的模型 ④ 在大数据时代,交叉验证是更常用和更灵活的模型选择方法,但 AIC/BIC 在统计建模中仍有重要地位

教学与演示

一、AIC(赤池信息准则)

是什么:AIC(Akaike Information Criterion)由日本统计学家赤池弘次于 1974 年提出。它的核心思想是:在候选模型中选择能最小化预测误差期望的模型。AIC 通过最大对数似然(衡量拟合优度)和参数数量(衡量复杂度)的权衡来实现这一目标。AIC 越小,模型越好。

大白话 AIC 就像「性价比评估」——模型拟合得越好(似然值大)得分越高,但每多用一个参数就要「扣分」。它帮你在「拟合得好」和「模型简单」之间找到最佳平衡。

为什么:AIC 的推导基于信息论中的 KL 散度(Kullback-Leibler Divergence)。赤池证明了:−2·ln(L) 是 KL 散度的有偏估计,偏差恰好约为 2k。因此 AIC = −2·ln(L) + 2k 是 KL 散度的无偏估计(在大样本下)。AIC 选择的是使预测分布最接近真实分布的模型,而非「真实模型」本身——赤池认为「真实模型」可能根本不存在或不在候选集中。

怎么做

import numpy as np

# ========== AIC 和 BIC 的计算与演示 ==========
np.random.seed(42)

def aic_bic_demo():
    """演示 AIC 和 BIC 的计算和应用"""
    n_samples = 200
    
    # 生成数据:真实模型 y = 2x + 1 + noise
    x = np.random.randn(n_samples)
    y = 2 * x + 1 + np.random.randn(n_samples) * 0.5
    
    print("=== AIC 与 BIC 模型选择 ===")
    print(f"真实模型: y = 2x + 1 + N(0, 0.5²)")
    print(f"样本数 n = {n_samples}")
    print()
    
    # 候选模型:不同阶数的多项式
    # 模型1: y = β₀(常数模型,k=1)
    # 模型2: y = β₀ + β₁x(线性,k=2)← 真实模型
    # 模型3: y = β₀ + β₁x + β₂x²(二次,k=3)
    # 模型4: y = β₀ + β₁x + β₂x² + β₃x³(三次,k=4)
    
    def compute_aic_bic(X_poly, y):
        """
        计算 AIC 和 BIC
        AIC = n·ln(RSS/n) + 2k (对线性回归的等价形式)
        BIC = n·ln(RSS/n) + k·ln(n)
        其中 RSS 是残差平方和,k 是参数数量(包括截距)
        """
        n = len(y)
        k = X_poly.shape[1]  # 参数数量
        
        # 最小二乘拟合
        w = np.linalg.lstsq(X_poly, y, rcond=None)[0]
        y_pred = X_poly @ w
        rss = np.sum((y - y_pred) ** 2)  # 残差平方和
        
        # AIC 和 BIC(使用 RSS 的等价形式)
        sigma2 = rss / n  # 误差方差的 MLE 估计
        log_lik = -n/2 * np.log(2 * np.pi * sigma2) - rss / (2 * sigma2)
        
        aic = -2 * log_lik + 2 * k
        bic = -2 * log_lik + k * np.log(n)
        
        # 也可以直接用: AIC = n*log(RSS/n) + 2*k (等价,差一个常数)
        # BIC = n*log(RSS/n) + k*log(n) (等价,差一个常数)
        
        return aic, bic, rss
    
    # 构建不同复杂度的模型矩阵
    X_poly_list = []
    names = []
    for degree in range(4):  # degree 0, 1, 2, 3
        if degree == 0:
            X_poly = np.column_stack([np.ones(n_samples)])  # 常数模型
            names.append("常数模型 (intercept only)")
        else:
            cols = [np.ones(n_samples)]
            for d in range(1, degree + 1):
                cols.append(x ** d)
            X_poly = np.column_stack(cols)
            names.append(f"{degree}次多项式")
        X_poly_list.append(X_poly)
    
    print(f"{'模型':<25} {'k':<5} {'RSS':<12} {'AIC':<12} {'BIC':<12} {'选择'}")
    print("-" * 75)
    
    results = []
    for i, (X_poly, name) in enumerate(zip(X_poly_list, names)):
        aic, bic, rss = compute_aic_bic(X_poly, y)
        k = X_poly.shape[1]
        results.append((name, k, aic, bic))
        print(f"{name:<25} {k:<5} {rss:<12.4f} {aic:<12.2f} {bic:<12.2f}")
    
    # 找出 AIC 和 BIC 最小的模型
    best_aic_idx = np.argmin([r[2] for r in results])
    best_bic_idx = np.argmin([r[3] for r in results])
    
    print(f"\nAIC 选择: {results[best_aic_idx][0]} (AIC={results[best_aic_idx][2]:.2f})")
    print(f"BIC 选择: {results[best_bic_idx][0]} (BIC={results[best_bic_idx][3]:.2f})")
    print(f"\n真实模型: 线性(1次多项式)")
    
    print(f"\n关键观察:")
    print(f"  1. AIC 和 BIC 都正确选择了线性模型(k=2)")
    print(f"  2. 常数模型(k=1)拟合差 → AIC/BIC 大")
    print(f"  3. 高次多项式(k=3,4)过拟合 → 惩罚项增加 → AIC/BIC 可能仍高于线性模型")

aic_bic_demo()
\text{AIC 与 BIC 的定义}\(\begin{aligned} \text{AIC} &= -2 \ln(L) + 2k \\ \text{BIC} &= -2 \ln(L) + k \ln(n) \end{aligned}\)
大白话 AIC 和 BIC 都做同一件事:给模型打分。分越低越好。它们都奖励「拟合好」(似然值大)和惩罚「太复杂」(参数多)。区别在于 BIC 的「罚单」金额随数据量增加而涨——数据越多,它越「抠门」,越偏好简单的模型。

什么用:AIC/BIC 在传统统计建模中有广泛应用——时间序列模型阶数选择(ARIMA 的 p,d,q 选择)、回归模型变量选择、混合模型组件数选择等。在 AI 中,AIC/BIC 的思想启发了神经网络的结构选择(如通过验证集或正则化来实现类似的目标)。但实践中,交叉验证已经很大程度上替代了 AIC/BIC。

哪些坑:AIC/BIC 要求模型通过最大似然估计拟合,不能直接用于任意模型(如 SVM、决策树不基于似然)。AIC/BIC 给出的是「相对」比较——只能告诉你模型 A 比模型 B 好,不能告诉你模型 A 本身好不好。AIC 在大样本下可能选择过于复杂的模型(因为它的一致性不如 BIC),BIC 在小样本下可能选择过于简单的模型。

二、BIC(贝叶斯信息准则)

是什么:BIC(Bayesian Information Criterion)由 Gideon Schwarz 于 1978 年提出,也称为 SIC(Schwarz Information Criterion)。BIC 的推导基于贝叶斯框架——它近似于模型的后验概率的对数。BIC 与 AIC 的区别在于对复杂度的惩罚更重(k·ln(n) vs 2k),且 BIC 具有一致性——当 n→∞ 时,BIC 以概率 1 选择真实模型(如果真实模型在候选集中)。

大白话 BIC 是「贝叶斯版的 AIC」。它在乎的不只是预测准确,还关心「哪个模型更可能是真实的」。因为惩罚更重,BIC 更「谨慎」——有足够的证据(数据多)才敢选复杂模型。

为什么:BIC 的推导基于拉普拉斯近似(Laplace Approximation)——在大样本下,模型的后验概率的对数可以用 BIC 近似:ln P(M|data) ≈ −½·BIC。因此,选择 BIC 最小的模型等价于选择后验概率最大的模型。BIC 的一致性(Consistency)是一个重要理论性质——如果真实模型在候选集中且样本量足够大,BIC 会以概率 1 选出它。AIC 不具备这种一致性(它是「有效的」但不「一致的」)。

怎么做

import numpy as np

# ========== AIC 与 BIC 在不同样本量下的对比 ==========
np.random.seed(42)

def aic_vs_bic_comparison():
    """对比 AIC 和 BIC 在不同样本量下的表现"""
    print("=== AIC vs BIC:不同样本量下的表现 ===")
    
    # 真实模型:y = 2x + 1
    # 候选模型:常数(k=1)、线性(k=2)、二次(k=3)、三次(k=4)
    
    for n in [20, 100, 500, 2000]:
        print(f"\n样本量 n = {n}")
        print(f"{'模型':<15} {'k':<5} {'2k (AIC惩罚)':<15} {'k·ln(n) (BIC惩罚)':<18}")
        print("-" * 55)
        
        for k in [1, 2, 3, 4]:
            aic_penalty = 2 * k
            bic_penalty = k * np.log(n)
            names = ["常数", "线性(真实)", "二次", "三次"]
            marker = " ← 真实模型" if k == 2 else ""
            print(f"{names[k-1]:<15} {k:<5} {aic_penalty:<15.0f} {bic_penalty:<18.2f}{marker}")
        
        print(f"\n  AIC 惩罚比 (k+1)/k: 始终为 3/2 = 1.5 (常数比例)")
        print(f"  BIC 惩罚比 (k+1)/k: (k+1)/k (随 n 增大不变,但惩罚本身增大)")
    
    print(f"\n=== 关键结论 ===")
    print(f"1. AIC 的惩罚只与 k 有关(2k),与 n 无关")
    print(f"2. BIC 的惩罚随 n 对数增长(k·ln(n))")
    print(f"3. n=8 时:2k ≈ k·ln(8)=2.08k → AIC 和 BIC 惩罚相似")
    print(f"4. n=100时:2k < k·ln(100)=4.61k → BIC 惩罚远重于 AIC")
    print(f"5. 大数据下 BIC 更保守(偏好简单模型),AIC 更激进")
    print(f"6. BIC 有理论优势(一致性),AIC 有实用优势(预测导向)")

aic_vs_bic_comparison()
\text{AIC 和 BIC 惩罚项的比较}\(\text{AIC penalty} = 2k, \quad \text{BIC penalty} = k\ln(n) \quad \Rightarrow \quad \text{BIC 更重当 } n > e^2 \approx 7.4\)
大白话 AIC 像个「实用主义者」——只要多加的参数能提升预测效果就加;BIC 像个「保守主义者」——必须有足够的数据支撑才接受更复杂的模型。数据少的时候,BIC 比 AIC 更「抠门」。

什么用:BIC 在统计建模中广泛用于:线性回归变量选择(stepAIC/stepBIC)、混合模型(Gaussian Mixture Model)的组件数选择、隐马尔可夫模型的隐状态数选择、聚类分析中的簇数选择等。BIC 的一致性使其在「真实模型存在于候选集中」的假设下表现良好。

哪些坑:BIC 的「一致性」理论性质依赖于「真实模型在候选集中」的强假设——在现实中这个假设几乎不成立。BIC 在小样本下可能过度惩罚复杂度,选择过于简单的模型。BIC(和 AIC)只能比较「嵌套」或「同分布」的模型,不能比较不同数据变换后的模型。

三、AIC/BIC 与交叉验证的对比

是什么:AIC/BIC 和交叉验证都是模型选择方法,但哲学基础不同。AIC/BIC 基于信息论/贝叶斯理论,通过分析公式(似然 + 惩罚)直接计算;交叉验证基于经验评估,通过多次数据划分直接测量泛化性能。在大数据时代,交叉验证使用更广泛,因为它不依赖模型假设(如似然函数),更灵活通用。

大白话 AIC/BIC 是「理论推导」的方法——用公式算出哪个模型好。交叉验证是「实践检验」的方法——实际跑一遍看哪个模型好。理论推导快但有限制(需要似然函数),实践检验慢但更通用。

为什么:交叉验证的优势:① 不依赖似然函数(可用于任意模型),② 直接测量泛化性能(关注的目标),③ 通过调整 K 可以平衡偏差和方差。AIC/BIC 的优势:① 计算成本低(只需一次拟合,不需要 K 次),② 有理论保证(渐近性质),③ 在小样本下可能更稳定(交叉验证在样本少时方差大)。

怎么做

import numpy as np

# ========== AIC/BIC 与交叉验证的对比 ==========
def aic_vs_cv_comparison():
    """对比 AIC/BIC 和交叉验证"""
    print("=== AIC/BIC vs 交叉验证 ===")
    print()
    
    comparison = [
        ("理论基础", "信息论/贝叶斯理论", "经验评估"),
        ("计算成本", "低(一次拟合)", "高(K次拟合)"),
        ("模型假设", "需要似然函数", "几乎不需要"),
        ("适用模型", "基于似然的模型", "任意模型"),
        ("小样本", "稳定", "方差大"),
        ("大样本", "BIC一致,AIC非一致", "稳定且一致"),
        ("输出", "相对分数", "泛化性能估计"),
        ("主要用途", "统计建模模型选择", "机器学习模型选择"),
    ]
    
    print(f"{'对比维度':<12} {'AIC/BIC':<25} {'交叉验证':<25}")
    print("-" * 65)
    for dim, aic, cv in comparison:
        print(f"{dim:<12} {aic:<25} {cv:<25}")
    
    print(f"\n选择建议:")
    print(f"  - 线性回归/逻辑回归模型选择 → AIC/BIC(快,经典)")
    print(f"  - 复杂模型(树模型、神经网络)→ 交叉验证")
    print(f"  - 小样本(n < 30)→ AIC/BIC(更稳定)")
    print(f"  - 大样本 + 灵活模型 → 交叉验证(更可靠)")
    print(f"  - Kaggle 竞赛/工业部署 → 交叉验证(直接测量目标)")

aic_vs_cv_comparison()

# ===== 错误使用 AIC 的场景 =====
print(f"\n=== AIC/BIC 的常见误用 ===")
print(f"1. 对决策树/随机森林使用 AIC → 错误!树模型不基于似然")
print(f"2. 比较不同数据变换后的模型的 AIC → 错误!似然不可比")
print(f"3. AIC 最小 = 模型最好 → 不完全正确!AIC 只是相对比较")
print(f"4. 用训练集上计算的 AIC 来评估泛化 → 错误!AIC 近似泛化误差")
print(f"   但不是真正在验证集上测量")
大白话 在现代 ML 中,交叉验证是「标配」,AIC/BIC 是「传统工具」。如果你在做传统的统计建模(线性回归、时间序列),AIC/BIC 仍然好用;如果你在做深度学习或 Kaggle 竞赛,直接上交叉验证。

概念关系图谱

准则公式惩罚项一致性目标
AIC−2ln(L)+2k2k最小化预测误差
BIC−2ln(L)+k·ln(n)k·ln(n)选真实模型
AICcAIC+2k(k+1)/(n−k−1)更重小样本修正
CV经验评估隐式最小化泛化误差

重点答疑

Q1: AIC 和 BIC 在什么情况下会给出不同的模型选择?

当样本量 n 较大且候选模型之间的复杂度差异较大时。例如 n=1000 时,BIC 的惩罚约为 AIC 的 3.5 倍。如果复杂模型(k 更大)的拟合提升不够显著,AIC 可能选择复杂模型(因为它认为预测提升值得额外的参数),而 BIC 选择简单模型(因为它认为证据不足以支持更多参数)。

Q2: AIC 可以用来选择神经网络的层数吗?

传统上不能——因为 AIC 需要最大似然估计的似然值,而神经网络通常使用随机梯度下降而非 MLE。但对于使用 MSE 损失训练的回归网络,可以近似使用 n·ln(MSE) + 2k 来计算 AIC(k 是网络参数总数)。然而,神经网络的参数数量 k 通常极大(百万级),AIC 的 2k 惩罚项会主导公式,导致没有实用价值。实践中用验证集性能(交叉验证)来选择网络结构。

Q3: AICc 是什么?与 AIC 有什么区别?

AICc(Corrected AIC)是 AIC 的小样本修正版本:AICc = AIC + 2k(k+1)/(n−k−1)。当 n/k < 40 时,AICc 显著优于 AIC(AIC 在小样本下倾向于选择过于复杂的模型)。当 n→∞ 时,修正项趋近于 0,AICc → AIC。在统计分析软件中,通常推荐使用 AICc 而非 AIC。

章节单词汇总

英文音标术语/释义
AIC/ˌeɪ.aɪˈsiː/Akaike Information Criterion;赤池信息准则
BIC/ˌbiː.aɪˈsiː/Bayesian Information Criterion;贝叶斯信息准则
Likelihood/ˈlaɪklihʊd/似然;给定参数下观测数据的概率
KL Divergence/ˌkeɪˈel daɪˈvɜːrdʒəns/KL 散度;两个分布之间差异的度量
Consistency/kənˈsɪstənsi/一致性;n→∞时以概率1选择真实模型
Parsimony/ˈpɑːrsɪmoʊni/简约性;偏好简单模型的原则
Overfitting/ˌoʊvərˈfɪtɪŋ/过拟合;模型过于复杂
Model Selection/ˈmɑːdəl sɪˈlekʃən/模型选择;从候选模型中选最优

面试练习

Q1 [单选] AIC 的全称是什么?

  • A. Artificial Intelligence Criterion
  • B. Akaike Information Criterion(赤池信息准则)
  • C. Average Information Criterion
  • D. Automatic Information Criterion
解答:AIC 由日本统计学家赤池弘次(Hirotsugu Akaike)于 1974 年提出,全称 Akaike Information Criterion。

Q2 [单选] 当样本量 n→∞ 时,AIC 会选择什么样的模型?

  • A. 总是选择真实模型
  • B. 倾向于选择比真实模型更复杂的模型(非一致性)
  • C. 总是选择最简单的模型
  • D. 与 BIC 总是给出相同结果
解答:AIC 不具备一致性——即使 n→∞,AIC 也有正概率选择过于复杂的模型。这是因为其惩罚项 2k 不随 n 增长。BIC 具有一致性(n→∞ 时以概率 1 选择真实模型)。

Q3 [多选] 以下关于 AIC 和 BIC 的说法,哪些是正确的?

  • A. AIC 的惩罚项是 2k,BIC 的惩罚项是 k·ln(n)
  • B. AIC 的目标是最小化预测误差,BIC 的目标是选择真实模型
  • C. AIC 和 BIC 都可以用于任意机器学习模型
  • D. 当 n > 8 时,BIC 对复杂度的惩罚比 AIC 更重
解答:AIC 和 BIC 需要模型有似然函数,不能用于任意模型(如 SVM、决策树)。其他三项正确。

Q4 [单选] BIC 中的「B」代表什么?

  • A. Binary
  • B. Bayesian(贝叶斯)
  • C. Best
  • D. Basic
解答:BIC 全称 Bayesian Information Criterion,由 Gideon Schwarz 于 1978 年在贝叶斯框架下提出,因此以「B」开头。

Q5 [单选] 对于线性回归模型,AIC 的简化计算公式是什么?

  • A. AIC = n·ln(RSS/n) + 2k
  • B. AIC = RSS + 2k
  • C. AIC = R² + 2k
  • D. AIC = n·ln(RSS) + k
解答:对于线性回归(正态误差假设),AIC 可以简化为 n·ln(RSS/n) + 2k(去掉常数项)。RSS 是残差平方和,k 是参数数量(包括截距)。

Q6 [多选] AIC/BIC 相比交叉验证的优势有哪些?

  • A. 计算成本低(只需一次拟合)
  • B. 小样本下更稳定
  • C. 可用于任意模型
  • D. 直接给出泛化误差的绝对估计
解答:AIC/BIC 计算成本低(不需要 K 次拟合),在小样本下比交叉验证更稳定(交叉验证在样本少时方差大)。但它们不能用于任意模型(需要似然函数),也只给出相对比较而非绝对估计。

Q7 [单选] AICc 是什么?

  • A. AIC 的大样本版本
  • B. AIC 的小样本修正版本
  • C. AIC 的分类版本
  • D. AIC 的贝叶斯版本
解答:AICc(Corrected AIC)是 AIC 的小样本修正:AICc = AIC + 2k(k+1)/(n−k−1)。当 n/k < 40 时推荐使用 AICc。

Q8 [单选] 两个模型 A 和 B,A 的 AIC = 100,B 的 AIC = 95,哪个模型更好?

  • A. 模型 A 更好
  • B. 模型 B 更好
  • C. 两者相同
  • D. 无法判断
解答:AIC 越小越好(类似于「损失」)。模型 B 的 AIC 更小,说明它在拟合优度和复杂度的权衡中表现更好。

Q9 [多选] 以下哪些模型可以合理使用 AIC/BIC 进行选择?

  • A. 线性回归(不同特征子集)
  • B. 逻辑回归(不同特征子集)
  • C. 随机森林(不同树的数量)
  • D. ARIMA 时间序列模型(不同阶数)
解答:线性回归、逻辑回归和 ARIMA 都基于似然估计,可以使用 AIC/BIC。随机森林不基于似然,不能直接使用 AIC/BIC。

Q10 [单选] BIC 为什么具有一致性(当 n→∞ 时以概率 1 选择真实模型)?

  • A. 因为 BIC 的公式更复杂
  • B. 因为 BIC 的惩罚项 k·ln(n) 随 n 增长,大样本下对复杂模型的惩罚足够重以排除虚假的复杂模型
  • C. 因为 BIC 使用了贝叶斯先验
  • D. 因为 BIC 计算更精确
解答:BIC 的惩罚项 k·ln(n) 随样本量对数增长。当 n→∞ 时,任何多余的参数都会被足够重的惩罚排除,只有真实模型(或与真实模型等价的最简模型)会在极限下被选中。AIC 的惩罚 2k 不随 n 增长,不具备此性质。