量化交易中文教材

第 13b 章 模型选择与 Logistic 回归

本章对应 Wasserman 原书第 13 章后半(13.6–13.9 节)。第 13a 章回答了"给定一组协变量,怎么估计和检验";本章回答一个更难、也更贴近量化研究日常的问题:手上有几十个候选因子,该用哪几个? 原书用不到六页给出了一个非常干净的框架——先定义"预测风险",证明训练误差系统性地低估它,再给出 \(C_p\)、AIC、交叉验证、BIC 四种修正办法,最后讲如何在 \(2^k\) 个模型中搜索。这套框架是理解回测过拟合的数学基础。本章后半部分讲 logistic 回归,它是二元结果(涨跌、违约、成交与否)的标准参数模型。

第 05 册计量经济学也会讲回归中的变量选择,但那里关心的是遗漏变量偏差与因果识别;本章关心的是预测,两者目标不同,选择变量的标准也不同,这一点在 13b.7 节会专门说明。

学习目标

  1. 理解偏差–方差权衡与欠拟合/过拟合,能写出预测风险与训练误差的定义。
  2. 会证明"训练误差是预测风险的向下有偏估计",偏差等于 \(-2\sum\text{Cov}(\hat Y_i,Y_i)\),在线性回归中等于 \(-2|S|\sigma^2\)。
  3. 掌握 Mallows \(C_p\)、AIC、留一与 \(k\) 折交叉验证、BIC 的公式与来历,会用帽子矩阵捷径计算留一交叉验证。
  4. 理解 AIC/交叉验证(追求预测最优)与 BIC(追求选中真模型)目标的差别,知道 AIC 不具备选择相合性。
  5. 会做前向/后向逐步回归,了解 Zheng–Loh 方法;知道这些方法选出的变量不代表因果。
  6. 会写出 logistic 回归的似然,理解迭代重加权最小二乘(IRLS)算法,会用 Fisher 信息求标准误,会把系数解释为对数优势比。

读前导读

这一章在解决什么问题

前半章回答一个你在做策略研究时天天面对的问题:回测里表现好的模型,实盘为什么会变差?差多少?怎么提前估计? 答案是一个可以精确计算的偏差:用同一份数据既拟合又评估,样本内误差一定偏乐观,乐观的幅度与模型自由度成正比。\(C_p\)、AIC、BIC 是给样本内误差"加罚分"把偏差补回来;交叉验证是干脆留出一部分数据不参与拟合。CFA 二级讲过调整 \(R^2\),它也是在"拟合好坏"上扣掉变量个数的惩罚,本章的几种准则是同一思路的更严格版本。

后半章讲 logistic 回归,处理"是或否"的结果:涨或跌、违约或不违约、成交或不成交。CFA 里你见过它被用于信用评分和违约预测。它和线性回归的区别是:线性回归直接预测数值,logistic 回归预测的是概率,而且要把预测值限制在 0 到 1 之间。代价是没有闭式解,要用迭代算法求,这就是 IRLS。

需要先想起来的数学

1. 矩阵的迹 \(\text{tr}\)。 方阵对角线元素之和,例如 \(\text{tr}\begin{pmatrix}1&2\\3&4\end{pmatrix}=5\)。关键性质:\(\text{tr}(AB)=\text{tr}(BA)\)(只要两边的乘法都有定义),以及迹是线性的。定理 13.15 之后的 \(\text{tr}(U_S)=|S|\) 就是用这两条算出来的。参见 第 00 册第 06 章 线性代数速成。

2. 协方差的双线性。 \(\text{Cov}(aX+bY,Z)=a\text{Cov}(X,Z)+b\text{Cov}(Y,Z)\);\(\mathbb V(A-B)=\mathbb VA+\mathbb VB-2\text{Cov}(A,B)\)。后者与 CFA 里两资产组合方差公式同形。参见 第 00 册第 07 章 概率中的分析工具。

3. 对数与指数互逆。 \(\log\) 默认是自然对数。\(\log(p/(1-p))\) 与 \(p=e^\eta/(1+e^\eta)\) 互为反函数:\(p=0.5\) 对应 \(\eta=0\);\(p=0.73\) 对应 \(\eta\approx1\);\(p=0.88\) 对应 \(\eta\approx2\)。参见 第 00 册第 04 章 级数与收敛。

4. 梯度、Hessian 与 Newton 法。 梯度 \(\nabla\ell\) 是一阶偏导排成的向量,Hessian \(\nabla^2\ell\) 是二阶偏导排成的矩阵(多元版的"二阶导")。一维 Newton 法求最大值:\(\beta\leftarrow\beta-\ell'(\beta)/\ell''(\beta)\),即用二次函数近似 \(\ell\)、直接跳到近似的顶点。用久期和凸性近似债券价格后求收益率,就是同一个想法。函数"凹"指 Hessian 处处负定(多元版的 \(\ell''<0\)),此时只有一个最高点。参见 第 00 册第 05 章 多元微积分与优化。

5. \(\chi^2_1\) 分布。 一个标准正态变量的平方。\(P(\chi^2_1<2)=P(|Z|<\sqrt2)\approx0.843\)。

怎么读这一章

核心必读:13b.2(定理 13.15 是全章的地基)、13b.3–13b.5、13b.7(AIC 与 BIC 的目标差别)、13b.9 的模型与系数解释、实战三(时间序列 CV 泄漏,对量化最实用)。13b.4 中 AIC 的 KL 推导、13b.6 的 Laplace 近似、13b.5 的 Sherman–Morrison 推导第一次可只看结论。IRLS 的"为什么这样做是对的"一段建议在读完导读第 4 项后再读。


13b.1 为什么要做模型选择

在第 13a 章的犯罪数据例子里,10 个协变量中有一半不显著。是否应该把它们剔除?原书给出两个理由支持更小的模型:一是预测可能更准,二是更简约(parsimonious),更容易解释和维护。

第一个理由背后是偏差–方差权衡(bias-variance tradeoff)。往模型里加变量,通常会降低预测的偏差(模型更能贴近真实的回归函数),但会增加方差(要估计的参数更多,每个都带着估计误差):

  • 协变量太少,偏差大,称为欠拟合(underfitting);
  • 协变量太多,方差大,称为过拟合(overfitting)。

好的模型在两者之间取得平衡。模型选择因此包含两个子问题:(i) 给每个候选模型打一个分,衡量它的好坏;(ii) 在所有候选模型中搜索得分最高的那个。

记号。 设共有 \(k\) 个协变量,\(S\subset\{1,\dots,k\}\) 是一个子集,\(X_S\) 是只含这些协变量的设计矩阵,\(\hat\beta_S\) 是对应的最小二乘估计,\(\hat r_S\) 是估计的回归函数,\(\hat Y_i(S)=\hat r_S(X_i)\) 是拟合值。\(|S|\) 表示模型中的项数。


13b.2 预测风险与训练误差的偏差

怎样给模型打分?最自然的目标是它对未来数据的预测能力。

预测风险(prediction risk)定义为

\[R(S)=\sum_{i=1}^n\mathbb E\big(\hat Y_i(S)-Y_i^*\big)^2,\tag{13.24}\]
其中 \(Y_i^*\) 是在同一协变量 \(X_i\) 处的一个新的、独立的观测。\(R(S)\) 就是"样本外误差"。

我们无法直接计算 \(R(S)\),因为不知道真实分布。最直接的估计是训练误差(training error):

\[\hat R_{\text{tr}}(S)=\sum_{i=1}^n\big(\hat Y_i(S)-Y_i\big)^2,\]
也就是残差平方和 RSS。问题在于它是一个糟糕的估计。

定理 13.15。 训练误差是预测风险的向下有偏估计:\(\mathbb E\hat R_{\text{tr}}(S)<R(S)\)。准确地说,

\[\text{bias}\big(\hat R_{\text{tr}}(S)\big)=\mathbb E\hat R_{\text{tr}}(S)-R(S)=-2\sum_{i=1}^n\text{Cov}(\hat Y_i,Y_i).\tag{13.25}\]

证明。 固定 \(X_i\),记 \(\mu_i=\mathbb E Y_i=\mathbb EY_i^*\),\(\mathbb VY_i=\mathbb VY_i^*=\sigma^2\)。展开两个平方误差:

\[\mathbb E(\hat Y_i-Y_i)^2=\mathbb V(\hat Y_i)+\sigma^2-2\,\text{Cov}(\hat Y_i,Y_i)+(\mathbb E\hat Y_i-\mu_i)^2,\]
\[\mathbb E(\hat Y_i-Y_i^*)^2=\mathbb V(\hat Y_i)+\sigma^2+(\mathbb E\hat Y_i-\mu_i)^2.\]
第二式没有协方差项,因为 \(Y_i^*\) 与训练数据独立,因而与 \(\hat Y_i\) 独立。两式相减并对 \(i\) 求和即得 (13.25)。\(\square\)

推导拆解:

  1. 任何随机变量 \(D\) 都有 \(\mathbb ED^2=\mathbb VD+(\mathbb ED)^2\)(第 12 章的"方差 + 偏差²")。取 \(D=\hat Y_i-Y_i\)。
  2. 均值:\(\mathbb ED=\mathbb E\hat Y_i-\mu_i\),平方后就是第一式最后一项。
  3. 方差:\(\mathbb V(\hat Y_i-Y_i)=\mathbb V\hat Y_i+\mathbb VY_i-2\text{Cov}(\hat Y_i,Y_i)\),与两资产组合方差 \(\sigma_A^2+\sigma_B^2-2\sigma_{AB}\)(权重 \(+1,-1\))同形。
  4. 把 \(Y_i\) 换成 \(Y_i^*\):均值不变,\(\mathbb VY_i^*\) 仍为 \(\sigma^2\),但 \(\text{Cov}(\hat Y_i,Y_i^*)=0\)。
  5. 两式只差 \(-2\text{Cov}(\hat Y_i,Y_i)\)。

金融直觉:这就像用同一年的数据挑选基金经理并评估他们。挑出来的经理"今年业绩好"部分源于运气,而运气正是用来挑选他们的那份数据里的噪声。明年运气重新抽签,业绩自然回落。\(\text{Cov}(\hat Y_i,Y_i)\) 衡量的就是"拟合值在多大程度上抓住了这份数据里的噪声",抓得越多,明年回落越多。

这个证明的直觉非常重要:训练误差把同一份数据用了两次——一次用来估计参数,一次用来评估拟合。拟合值 \(\hat Y_i\) 是"照着 \(Y_i\) 做出来的",二者正相关,所以训练误差看起来比真实情况好。模型越灵活,\(\hat Y_i\) 越能追随 \(Y_i\),协方差越大,乐观偏差越严重。

线性回归中的偏差有闭式。 拟合值 \(\hat Y=U_SY\),\(U_S=X_S(X_S^TX_S)^{-1}X_S^T\) 是帽子矩阵。于是

\[\sum_i\text{Cov}(\hat Y_i,Y_i)=\text{tr}\big(\text{Cov}(U_SY,Y)\big)=\text{tr}(U_S\,\sigma^2I)=\sigma^2\,\text{tr}(U_S)=|S|\sigma^2,\]
最后一步用到投影矩阵的迹等于其秩(列数):\(\text{tr}(U_S)=\text{tr}\big((X_S^TX_S)^{-1}X_S^TX_S\big)=|S|\)。> 推导拆解:

  1. \(\hat Y=U_SY\),所以 \(\hat Y_i=\sum_jU_{ij}Y_j\)。由协方差的线性,\(\text{Cov}(\hat Y_i,Y_i)=\sum_jU_{ij}\text{Cov}(Y_j,Y_i)\)。不同观测的 \(Y\) 互不相关,只剩 \(j=i\) 一项:\(U_{ii}\sigma^2\)。
  2. 对 \(i\) 求和:\(\sigma^2\sum_iU_{ii}=\sigma^2\text{tr}(U_S)\)。原文用矩阵语言写的是同一件事。
  3. 迹的轮换:取 \(A=X_S\),\(B=(X_S^TX_S)^{-1}X_S^T\),则 \(\text{tr}(AB)=\text{tr}(BA)=\text{tr}\big((X_S^TX_S)^{-1}X_S^TX_S\big)=\text{tr}(I_{|S|})=|S|\)。注意 \(AB\) 是 \(n\times n\),\(BA\) 是 \(|S|\times|S|\),大小不同但迹相同。 小例子:\(n=250\) 个日收益,\(\sigma=1\%\),模型 5 个参数。训练 RSS 平均比样本外少 \(2\times5\times(0.01)^2=0.001\),平摊到每个观测是 \(4\times10^{-6}\),相当于每日误差方差被低估 4%。参数加到 50 个,低估 40%。

所以每多估计一个参数,训练误差就平均乐观 \(2\sigma^2\)。这个量通常称为模型的"有效自由度",它的推广(\(\sum\text{Cov}(\hat Y_i,Y_i)/\sigma^2\))对岭回归、样条、树模型同样适用。

把这一结论翻译成量化语言:回测的样本内表现是样本外表现的乐观估计,乐观程度随你尝试的自由度增加而增加。调过的参数、试过的因子组合、改过的止损规则都是自由度。


13b.3 Mallows \(C_p\)

既然知道偏差是 \(-2|S|\sigma^2\),最直接的办法就是把它加回去。

Mallows \(C_p\) 统计量:

\[\hat R(S)=\hat R_{\text{tr}}(S)+2|S|\hat\sigma^2,\tag{13.26}\]
其中 \(\hat\sigma^2\) 取自全模型(包含所有 \(k\) 个协变量)的估计。之所以用全模型,是因为全模型偏差最小,对 \(\sigma^2\) 的估计最可靠;若用子模型自己的 \(\hat\sigma^2\),欠拟合模型会高估 \(\sigma^2\)。

\(C_p\) 的结构是"拟合不足 + 复杂度惩罚"(lack of fit + complexity penalty):第一项随变量增加而下降,第二项随变量增加而上升,最优模型在两者之和最小处。后面所有准则都是这个结构,区别只在惩罚多重。


13b.4 AIC

Akaike 信息准则(Akaike Information Criterion, AIC)选择使下式最大的 \(S\):

\[\text{AIC}(S)=\ell_S-|S|,\tag{13.27}\]
其中 \(\ell_S\) 是模型 \(S\) 在最大似然估计处的对数似然。这同样是"拟合优度减复杂度"。

关于符号:不同教材和软件把 AIC 乘以 \(2\) 或 \(-2\),例如 R 使用 \(-2\ell_S+2|S|\) 并取最小值。这些版本选出的模型完全相同,读文献时只需留意是取最大还是最小。

与 \(C_p\) 的关系。 在正态误差线性回归中,若 \(\sigma\) 已知(或固定为全模型估计值),\(\ell_S=\text{const}-\text{RSS}_S/(2\sigma^2)\),于是

\[\text{AIC}(S)=\text{const}-\frac{1}{2\sigma^2}\big(\text{RSS}_S+2|S|\sigma^2\big),\]
最大化 AIC 等价于最小化 \(C_p\)(原书习题 8)。

AIC 从哪里来(原书 13.9 节附录)。 AIC 的理论基础是 Kullback–Leibler 距离(第 09 章)。设真实分布为 \(f\),模型 \(M_j\) 的最大似然拟合为 \(\hat f_j\)。用 KL 距离

\[D(f,g)=\sum_xf(x)\log\frac{f(x)}{g(x)}\]
作为损失,风险为 \(\mathbb E\,D(f,\hat f_j)\)。把 \(D\) 拆开:\(D(f,\hat f_j)=c-A(f,\hat f_j)\),其中 \(c=\sum f\log f\) 与模型无关,\(A(f,\hat f_j)=\sum_xf(x)\log\hat f_j(x)\)。所以最小化 KL 风险等价于最大化 \(a(f,\hat f_j)=\mathbb E\,A(f,\hat f_j)\)——即"拟合出的模型对新数据的期望对数似然"。

白话解释:KL 距离 \(D(f,g)\) 衡量"真实分布是 \(f\)、你却以为是 \(g\)"时的平均代价,\(f=g\) 时为 0,否则为正。它可以这样理解:\(\log(f(x)/g(x))\) 是在结果 \(x\) 上"真实概率比你以为的高多少倍"取对数,再按真实概率加权平均。在模型比较里 \(f\) 不变,所以只需比较 \(A=\sum f\log\hat f_j\),即"用拟合出的模型给新数据打分,平均对数似然有多高"。这和投资里用对数效用评估一个概率预测者是同一种打分方式:给真实发生的结果分配的概率越高,得分越高。

用样本内的对数似然 \(\ell_j/n\) 去估计它,会犯与训练误差同样的错误:参数是照着这份数据拟合的,样本内对数似然偏高,偏高量约为 \(|M_j|/n\)(模型参数个数除以 \(n\))。

定理 13.18。 \(\text{AIC}(M_j)\) 是 \(a(f,\hat f_j)\) 的近似无偏估计(差一个与模型无关的尺度)。

因此 AIC 可以理解为"对数似然版的 \(C_p\)":它估计的是样本外的预测能力,度量预测好坏的尺子是 KL 距离。AIC 的好处是适用于任何用最大似然拟合的模型——logistic 回归、GARCH、ARMA 定阶都可以直接用。


13b.5 交叉验证

\(C_p\) 和 AIC 都依赖于偏差的解析公式。交叉验证(cross-validation, CV)不依赖任何公式:既然问题出在"同一份数据用两次",那就把数据分开用。

留一交叉验证(leave-one-out cross-validation):

\[\hat R_{CV}(S)=\sum_{i=1}^n\big(Y_i-\hat Y_{(i)}\big)^2,\tag{13.28}\]
其中 \(\hat Y_{(i)}\) 是去掉第 \(i\) 个观测后拟合的模型对 \(Y_i\) 的预测。由于 \(Y_i\) 没有参与拟合,\(\hat Y_{(i)}\) 与 \(Y_i\) 独立,乐观偏差消失。

直接计算需要拟合 \(n\) 次,但线性回归有一个漂亮的捷径:

\[\hat R_{CV}(S)=\sum_{i=1}^n\left(\frac{Y_i-\hat Y_i(S)}{1-U_{ii}(S)}\right)^2,\tag{13.29}\]
其中 \(U_{ii}(S)\) 是帽子矩阵
\[U(S)=X_S(X_S^TX_S)^{-1}X_S^T\tag{13.30}\]
的第 \(i\) 个对角元,称为第 \(i\) 个观测的杠杆值(leverage)。于是拟合一次就能得到留一误差。

捷径的推导思路。 删去第 \(i\) 行后,\(X^TX\) 变为 \(X^TX-x_ix_i^T\),用 Sherman–Morrison 公式求其逆,可以证明删一后的残差 \(Y_i-\hat Y_{(i)}\) 等于普通残差 \(Y_i-\hat Y_i\) 除以 \(1-U_{ii}\)。直观上,杠杆值 \(U_{ii}\) 度量第 \(i\) 个点对自身拟合值的"拉动力"(\(\hat Y_i=\sum_jU_{ij}Y_j\) 中 \(Y_i\) 自己的权重)。高杠杆点(协变量取极端值的观测)把拟合线拉向自己,残差被压小,除以 \(1-U_{ii}\) 正好把这部分补回来。这一点在金融数据里很实用:极端行情日往往是高杠杆点,样本内残差很小,但样本外不可靠。

白话解释(杠杆值的范围与数值例子):\(U_{ii}\) 在 0 和 1 之间,所有 \(U_{ii}\) 之和等于参数个数 \(|S|\),所以平均杠杆值是 \(|S|/n\)。简单回归中 \(U_{ii}=\frac1n+\frac{(X_i-\bar X)^2}{\sum_j(X_j-\bar X)^2}\),离中心越远杠杆越高。例:\(n=250\),某暴跌日市场收益偏离均值 5 个标准差,\(U_{ii}\approx\frac1{250}+\frac{25}{250}=0.104\)。它的样本内残差若为 1%,留一残差就是 \(1\%/(1-0.104)\approx1.12\%\)。普通日子 \(U_{ii}\approx0.004\),几乎不用修正。

\(k\) 折交叉验证(\(k\)-fold CV):把数据随机分成 \(k\) 组(常取 \(k=10\)),每次留出一组作为测试集,用其余各组拟合模型,计算留出组上的 \(\sum(Y_i-\hat Y_i)^2\);把 \(k\) 次结果平均。它比留一 CV 计算量小,且适用于没有捷径公式的复杂模型。

原书指出:在线性回归中,\(C_p\) 与交叉验证的结果往往几乎相同,可以直接用 \(C_p\);交叉验证在后面更复杂的问题(非参数回归、分类)中更有用。在量化中,交叉验证还有一个原书没有涉及但必须强调的陷阱:时间序列数据不能随机打乱分组,见 13b.10 节实战。


13b.6 BIC

贝叶斯信息准则(Bayesian Information Criterion, BIC)选择使下式最大的模型:

\[\text{BIC}(S)=\ell_S-\frac{|S|}{2}\log n.\tag{13.31}\]

它的形式与 AIC 相同,只是每个参数的惩罚从 \(1\) 变为 \(\frac12\log n\)。当 \(n\ge8\) 时 \(\frac12\log n>1\),所以 BIC 惩罚更重,倾向于选择更小的模型;而且样本越大,惩罚越重。

贝叶斯解释。 设有模型集合 \(\{S_1,\dots,S_m\}\),给每个模型相同的先验概率 \(\mathbb P(S_j)=1/m\),并在每个模型内部给参数一个光滑的先验。可以证明后验概率近似为

\[\mathbb P(S_j\mid\text{data})\approx\frac{e^{\text{BIC}(S_j)}}{\sum_re^{\text{BIC}(S_r)}}.\]
推导的核心是对边际似然 \(\int\mathcal L(\theta)\pi(\theta)d\theta\) 做 Laplace 近似:似然在 MLE 附近形如宽度 \(\propto1/\sqrt n\) 的尖峰,每个参数维度贡献一个 \(n^{-1/2}\) 的因子,取对数即 \(-\frac{|S|}2\log n\)。> 推导拆解(\(\frac{|S|}{2}\log n\) 的来历):

  1. 边际似然 \(\int\mathcal L(\theta)\pi(\theta)d\theta\) 是"似然按先验加权的平均值"(第 11 章 11.8 节的贝叶斯因子分母)。
  2. \(n\) 大时,似然只在 MLE 附近一个宽度约 \(c/\sqrt n\) 的小区域内不可忽略(第 11 章定理 11.5),先验在这么小的区域内近似常数 \(\pi(\hat\theta)\)。
  3. 于是积分 ≈ 峰值高度 × 峰的"体积" ≈ \(\mathcal L(\hat\theta)\cdot\pi(\hat\theta)\cdot(c/\sqrt n)^{|S|}\)。每个参数维度贡献一个宽度因子 \(n^{-1/2}\)。
  4. 取对数:\(\ell_S-\frac{|S|}2\log n+O(1)\),\(O(1)\) 是不随 \(n\) 增长的项,大样本下可以忽略。 直观含义:多一个参数,先验就要把概率摊薄到多一个维度上,而数据只支持其中很窄的一条,"浪费"的先验质量随 \(n\) 增大而增加。这就是贝叶斯版本的"奥卡姆剃刀"。

所以选 BIC 最大的模型,近似于选后验概率最大的模型。上式还给出了一种"模型平均"的权重。BIC 还有基于最小描述长度(minimum description length)的信息论解释。


13b.7 AIC 与 BIC:两个不同的目标

AIC/\(C_p\)/交叉验证和 BIC 并不是"同一件事的不同近似",它们追求不同的目标。

  • AIC、\(C_p\)、交叉验证追求预测最优:选出的模型使样本外预测误差(或 KL 风险)尽量小。
  • BIC 追求选中"真模型":如果真模型在候选集中,随着 \(n\to\infty\),BIC 以趋于 1 的概率选中它,这称为选择相合性(selection consistency)。

原书习题 9 用一个最简单的例子把这一差别讲得很透。比较 \(M_0:N(0,1)\) 与 \(M_1:N(\theta,1)\)。AIC 在 \(\ell_1-1>\ell_0\) 时选 \(M_1\),而 \(2(\ell_1-\ell_0)=n\bar X^2\)。当真值 \(\theta=0\) 时,\(n\bar X^2\sim\chi^2_1\),故

\[\lim_{n\to\infty}\mathbb P(\text{AIC 选 }M_0)=\mathbb P(\chi^2_1<2)\approx0.843.\]
也就是说,即使样本无穷大,AIC 仍有约 16% 的概率选择多余的参数——AIC 不具备选择相合性。但同一道题的 (b) 部分说明:无论 \(\theta\) 是否为零,AIC 选出的密度与真密度的 KL 距离都依概率趋于零。多选一个参数并不伤害预测,因为那个多余参数的估计值本身会趋于零。BIC 则不同:其选择 \(M_1\) 的门槛是 \(n\bar X^2>\log n\to\infty\),所以在 \(\theta=0\) 时选错的概率趋于零。

推导拆解:

  1. \(N(\theta,1)\) 的对数似然(去掉常数)是 \(-\frac12\sum(X_i-\theta)^2\)。\(M_0\) 中 \(\theta=0\),\(\ell_0=-\frac12\sum X_i^2\);\(M_1\) 中 MLE 是 \(\bar X\),\(\ell_1=-\frac12\sum(X_i-\bar X)^2\)。
  2. 用 \(\sum X_i^2=\sum(X_i-\bar X)^2+n\bar X^2\),得 \(\ell_1-\ell_0=\frac12n\bar X^2\)。
  3. \(\theta=0\) 时 \(\sqrt n\bar X\sim N(0,1)\),所以 \(n\bar X^2\sim\chi^2_1\),分布不随 \(n\) 变。AIC 选 \(M_1\) 的条件 \(\ell_1-\ell_0>1\) 即 \(n\bar X^2>2\),概率恒为 \(P(\chi^2_1>2)\approx0.157\),不会随样本增大而消失。
  4. BIC 的条件是 \(\ell_1-\ell_0>\frac12\log n\),即 \(n\bar X^2>\log n\)。门槛随 \(n\) 上升,\(\chi^2_1\) 超过它的概率趋于 0。 用 t 值的语言:AIC 相当于 \(|t|>1.41\) 就加入变量,门槛固定;BIC 相当于 \(|t|>\sqrt{\log n}\),\(n=250\) 时约 2.35,\(n=10000\) 时约 3.03。

对量化研究的含义:

  • 如果目标是预测(构建收益预测模型、风险模型),AIC 或交叉验证是合理的默认选择,多纳入几个弱因子问题不大。
  • 如果目标是判断某个因子是否真的存在(学术意义上的"发现"),应该用更严格的惩罚(BIC 一类),或者第 10b 章的多重检验校正。在成百上千个候选因子里按 AIC 挑选,选中的"弱因子"中会有很大比例是假的。

Zheng–Loh 方法。 原书还介绍了 Zheng 与 Loh(1995)的方法,它的目标同样是找出真模型(非零 \(\beta_j\) 构成的最小子集):

  1. 拟合全模型,计算每个系数的 Wald 统计量 \(W_j=\hat\beta_j/\widehat{\text{se}}(\hat\beta_j)\);
  2. 按绝对值从大到小排序:\(|W_{(1)}|\ge|W_{(2)}|\ge\dots\ge|W_{(k)}|\);
  3. 令 \(\hat j\) 为使 \(\text{RSS}(j)+j\,\hat\sigma^2\log n\) 最小的 \(j\),其中 \(\text{RSS}(j)\) 是只包含 \(|W|\) 最大的前 \(j\) 个变量的模型的残差平方和;
  4. 最终模型取 \(|W|\) 最大的 \(\hat j\) 个变量。

它只需检查 \(k\) 个嵌套模型而不是 \(2^k\) 个,惩罚 \(j\hat\sigma^2\log n\) 相当于 BIC 量级。Zheng 与 Loh 证明在适当条件下它选中真模型的概率随 \(n\) 增大趋于 1。它的弱点是排序完全依赖全模型的 Wald 统计量;变量高度相关时,排序本身就不稳定。


13b.8 模型搜索:逐步回归

\(k\) 个协变量有 \(2^k\) 个子模型。\(k\) 较小时(例如 \(k\le20\))可以全部枚举;\(k\) 大时不可行,只能搜索一部分:

  • 前向逐步回归(forward stepwise regression):从空模型开始,每一步加入使得分改进最多的变量,直到任何变量都不能再改进得分;
  • 后向逐步回归(backward stepwise regression):从全模型开始,每一步删去一个变量(删除后得分最好的那个),直到删除任何变量都会使得分变差。

二者都是贪心搜索,不保证找到全局最优模型。随机搜索也很常用,但原书指出,没有理由认为它比确定性搜索更好。

例 13.16(犯罪数据,后向逐步 + AIC)。 原书在 R 中进行(R 的 AIC 定义取最小值,等价于最小化 \(C_p\))。全模型 AIC 为 310.37。逐个删除单个变量后的 AIC(升序)为:

删除的变量 Pop Labor South Wealth Males U1 Educ U2 Age Expend
删除后 AIC 308 309 309 309 310 310 312 314 315 324

删除 Pop 使 AIC 降到 308,于是先删 Pop。第二轮在剩余变量中重复:South 308、Labor 308、Wealth 308、Males 309、U1 309、Education 310、U2 313、Age 313、Expend 329,删除 South。如此继续,直到删除任何变量都不再降低 AIC。最终模型为

\[\text{Crime}=1.2\,\text{Age}+0.75\,\text{Education}+0.87\,\text{Expenditure}+0.34\,\text{Males}-0.86\,U_1+2.31\,U_2.\]

原书紧接着提醒:这仍然没有回答哪些变量是犯罪的原因。逐步回归找的是好的预测组合。被删除的变量可能是重要的原因(其作用已被相关变量吸收),被保留的变量可能只是原因的"代理"。这一点在 13b.9 节的 CORIS 例子里还会再次出现。

在量化中,逐步回归还有一个额外风险:在大量候选因子上做贪心选择,再用同一份数据报告所选模型的 t 值,这些 t 值严重高估了显著性——选择过程本身已经"偷看"了数据。正确做法是在选择之后用独立的样本外数据评估,或把选择过程整体放进交叉验证内部。


13b.9 Logistic 回归

模型

当响应变量是二元的,\(Y_i\in\{0,1\}\),线性回归不再合适:线性函数的取值不受限制,而概率必须在 \([0,1]\) 中。Logistic 回归(logistic regression)用 logistic 函数把线性组合压进 \((0,1)\):

\[p_i\equiv p_i(\beta)\equiv\mathbb P(Y_i=1\mid X=x_i)=\frac{e^{\beta_0+\sum_{j=1}^k\beta_jx_{ij}}}{1+e^{\beta_0+\sum_{j=1}^k\beta_jx_{ij}}}.\tag{13.32}\]
等价地,
\[\text{logit}(p_i)=\beta_0+\sum_{j=1}^k\beta_jx_{ij},\qquad\text{logit}(p)=\log\frac{p}{1-p}.\tag{13.33–13.34}\]
logistic 函数 \(e^x/(1+e^x)\) 是一条 S 形曲线,从 0 升到 1,在 \(x=0\) 处等于 \(1/2\)(原书图 13.3)。

系数的解释。 \(\log\frac{p}{1-p}\) 是对数优势(log odds)。\(\beta_j\) 表示其他变量不变时,\(x_j\) 增加一个单位,对数优势增加 \(\beta_j\);也就是优势乘以 \(e^{\beta_j}\)。所以 \(e^{\beta_j}\) 是一个优势比(odds ratio),与第 15 章 \(2\times2\) 列联表的优势比是同一个概念。当二元协变量是唯一的协变量时,logistic 回归的 \(e^{\hat\beta_1}\) 恰好等于列联表的 \(\hat\psi\)。

金融直觉:优势(odds)就是博彩和信用分析里的"赔率"口径。违约概率 \(p=20\%\),优势是 \(0.2/0.8=0.25\),即"1 比 4"。若 \(\beta_j=0.5\),杠杆率每升一个单位,优势乘以 \(e^{0.5}\approx1.65\),变成 0.41,对应违约概率 \(0.41/1.41\approx29\%\)。注意系数作用在优势上是"乘法"、作用在概率上不是固定增量:基础违约率 1% 时,同样乘以 1.65 只让违约率升到约 1.6%。这就是为什么信用评分卡用对数优势打分(每多少分让优势翻倍),而不直接用概率相加。

似然与 IRLS 算法

给定协变量,\(Y_i\sim\text{Bernoulli}(p_i)\),条件似然为

\[\mathcal L(\beta)=\prod_{i=1}^np_i(\beta)^{Y_i}\big(1-p_i(\beta)\big)^{1-Y_i}.\tag{13.35}\]
对数似然 \(\ell(\beta)=\sum_i[Y_i\eta_i-\log(1+e^{\eta_i})]\),\(\eta_i=x_i^T\beta\)。它关于 \(\beta\) 是凹的,所以最大似然估计(若存在)唯一,但没有闭式解,需要数值求解。

迭代重加权最小二乘(iteratively reweighted least squares, IRLS)算法:取初值 \(\hat\beta^0\)(例如全零),由 (13.32) 算出 \(p_i^0\),令 \(s=0\),重复以下步骤直到收敛:

  1. 计算工作响应:\(Z_i=\text{logit}(p_i^s)+\dfrac{Y_i-p_i^s}{p_i^s(1-p_i^s)}\),\(i=1,\dots,n\);
  2. 令 \(W\) 为对角矩阵,第 \((i,i)\) 元为 \(p_i^s(1-p_i^s)\);
  3. 令 \(\hat\beta^{s+1}=(X^TWX)^{-1}X^TWZ\),即用 \(Z\) 对 \(X\) 做加权最小二乘;
  4. \(s\leftarrow s+1\),回到第 1 步。

(原书第 3 步文字写作"regress \(Z\) on \(Y\)",应为 \(Z\) 对 \(X\) 的加权回归,公式本身无误。)

为什么这样做是对的。 对数似然的梯度和 Hessian 为

\[\nabla\ell=X^T(Y-p),\qquad\nabla^2\ell=-X^TWX.\]
Newton–Raphson 迭代(第 09 章、第 04 册)为
\[\beta^{s+1}=\beta^s+(X^TWX)^{-1}X^T(Y-p)=(X^TWX)^{-1}X^TW\big[X\beta^s+W^{-1}(Y-p)\big],\]
方括号里正是工作响应 \(Z\)。所以 IRLS 就是 Newton 法;对 logistic 回归(典则链接),它也与 Fisher scoring 相同。Newton 法在凹函数上收敛很快,通常几步就够。

推导拆解:

  1. 单个观测的对数似然 \(Y_i\eta_i-\log(1+e^{\eta_i})\) 对 \(\eta_i\) 求导:\(Y_i-\frac{e^{\eta_i}}{1+e^{\eta_i}}=Y_i-p_i\)。再用链式法则 \(\partial\eta_i/\partial\beta=x_i\),得 \(\nabla\ell=\sum_ix_i(Y_i-p_i)=X^T(Y-p)\)。形式上和线性回归的正规方程 \(X^T(Y-X\beta)\) 一模一样:残差与协变量正交。
  2. 再求一次导:\(\partial p_i/\partial\eta_i=p_i(1-p_i)\)(logistic 函数的导数),所以 \(\nabla^2\ell=-\sum_ip_i(1-p_i)x_ix_i^T=-X^TWX\)。
  3. Newton 步 \(\beta-(\nabla^2\ell)^{-1}\nabla\ell\) 就是原文第一个等号。第二个等号是把 \(\beta^s\) 写成 \((X^TWX)^{-1}X^TWX\beta^s\) 后合并。 白话:每一轮,先在当前估计处把非线性的 logistic 模型"线性化",得到一个近似的线性回归问题(因变量是工作响应 \(Z\)),再用加权最小二乘解它。权重 \(p_i(1-p_i)\) 在 \(p_i=0.5\) 时最大:概率在 50% 附近的观测最"有信息量",几乎肯定的观测(\(p_i\) 接近 0 或 1)权重很小。

标准误与模型选择。 收敛时,\(X^TWX\) 就是 Fisher 信息矩阵 \(I\) 的估计,\(J=I^{-1}\) 的第 \((j,j)\) 元开方即为 \(\widehat{\text{se}}(\hat\beta_j)\),由此可做 Wald 检验和置信区间。模型选择通常用 AIC 得分 \(\ell_S-|S|\)。

一个实用提醒:若某个线性组合能把 0 和 1 完全分开(完全分离),对数似然会随 \(\|\beta\|\to\infty\) 单调上升,MLE 不存在,IRLS 会发散。小样本、稀有事件或特征过多时容易遇到,这时需要正则化(岭/lasso 惩罚)。

例 13.17:CORIS 冠心病数据

南非三个农村地区 462 名 15–64 岁男性,\(Y\) 表示是否患冠心病,9 个协变量:收缩压(sbp)、累计烟草消费量(tobacco,千克)、低密度脂蛋白(ldl)、肥胖指数(adiposity)、家族史(famhist)、A 型行为(typea)、肥胖(obesity)、饮酒(alcohol)、年龄(age)。logistic 回归结果:

变量 \(\hat\beta_j\) \(\widehat{\text{se}}\) \(W_j\) p 值
截距 −6.145 1.300 −4.738 0.000
sbp 0.007 0.006 1.138 0.255
tobacco 0.079 0.027 2.991 0.003
ldl 0.174 0.059 2.925 0.003
adiposity 0.019 0.029 0.637 0.524
famhist 0.925 0.227 4.078 0.000
typea 0.040 0.012 3.233 0.001
obesity −0.063 0.044 −1.427 0.153
alcohol 0.000 0.004 0.027 0.979
age 0.045 0.012 3.754 0.000

例如有家族史者患病优势是无家族史者的 \(e^{0.925}\approx2.5\) 倍(其他变量不变)。

原书的评论很犀利:如果你对"收缩压不显著""肥胖系数为负"感到意外,说明你把关联和因果混为一谈了。收缩压不显著并不意味着血压不是心脏病的重要原因,只意味着在已经知道其他变量的条件下,它不是一个重要的预测因子。在因子研究中,"控制了其他因子后某因子不显著"也只能这样解读。


13b.10 量化实战

实战一:在 10 个候选因子中选模型

场景。 10 个标准化候选因子,只有 3 个真正有预测力(系数 0.40、0.25、0.15,相对于噪声标准差 1 都属于弱信号),其中因子 3 是与真因子 0 相关系数 0.7 的"伪因子"。对每个样本,枚举全部 \(2^{10}=1024\) 个子模型,分别用训练误差、\(C_p\)、AIC、BIC、留一 CV(帽子矩阵捷径)选模型,并用精确公式计算所选模型的真实样本外均方误差。重复 300 次,样本量分别为 200 与 2000。

import numpy as np
from itertools import combinations

rng = np.random.default_rng(2024)
k, sigma = 10, 1.0
beta_true = np.zeros(k); beta_true[[0, 1, 2]] = [0.40, 0.25, 0.15]   # 10 个候选因子,只有 3 个真因子
Sigma_F = np.eye(k); Sigma_F[0, 3] = Sigma_F[3, 0] = 0.7              # 因子 3 是与因子 0 相关的"伪因子"
L = np.linalg.cholesky(Sigma_F)
SUBSETS = [list(S) for m in range(k + 1) for S in combinations(range(k), m)]

def make(n):
    F = rng.normal(size=(n, k)) @ L.T
    return F, F @ beta_true + sigma * rng.normal(size=n)

def fit(Xs, y):
    G = np.linalg.inv(Xs.T @ Xs)
    b = G @ Xs.T @ y
    h = np.einsum("ij,jk,ik->i", Xs, G, Xs)                  # 帽子矩阵对角元 U_ii
    return b, y - Xs @ b, h

def true_risk(S, b):
    """新观测的期望平方预测误差(精确值):sigma^2 + 截距^2 + d' Sigma_F d"""
    d = -beta_true.copy(); d[S] += b[1:]
    return sigma**2 + b[0]**2 + d @ Sigma_F @ d

def run_once(n):
    F, y = make(n)
    one = np.ones((n, 1))
    _, e_full, _ = fit(np.hstack([one, F]), y)
    s2_full = e_full @ e_full / (n - k - 1)                  # Cp 用全模型的 sigma^2
    res = {}
    for S in SUBSETS:
        Xs = np.hstack([one, F[:, S]]); b, e, h = fit(Xs, y)
        p, rss = Xs.shape[1], e @ e
        ll = -n / 2 * (np.log(2 * np.pi * rss / n) + 1)      # 正态对数似然(MLE 处)
        res[tuple(S)] = dict(train=rss / n, Cp=rss + 2 * p * s2_full,
                             AIC=-(ll - (p + 1)), BIC=-(ll - (p + 1) / 2 * np.log(n)),
                             LOO=np.sum((e / (1 - h)) ** 2), risk=true_risk(S, b))
    return res

for n in (200, 2000):
    out = {c: dict(size=[], hit=[], risk=[]) for c in ("train", "Cp", "AIC", "BIC", "LOO")}
    gap = []
    for rep in range(300):
        res = run_once(n)
        gap.append(n * (res[(0, 1, 2)]["risk"] - res[(0, 1, 2)]["train"]))
        for c in out:
            S = min(res, key=lambda s: res[s][c])
            out[c]["size"].append(len(S)); out[c]["hit"].append(S == (0, 1, 2))
            out[c]["risk"].append(res[S]["risk"])
    print(f"--- n={n}, 300 次重复 ---  真模型 n×(样本外MSE-样本内MSE) 平均 {np.mean(gap):.1f}"
          f"(固定设计理论值 2|S|σ²=8)")
    for c, d in out.items():
        print(f"{c:<6s} 平均选入变量数 {np.mean(d['size']):5.2f}  选中真模型比例 {np.mean(d['hit']):.2f}"
              f"  样本外MSE {np.mean(d['risk']):.4f}")

(代码中 AIC、BIC 取了相反数以便统一"取最小";参数个数把 \(\sigma\) 也算进去,对所有模型加同一个常数,不影响选择。)

关键输出:

--- n=200, 300 次重复 ---  真模型 n×(样本外MSE-样本内MSE) 平均 7.8(固定设计理论值 2|S|σ²=8)
train  平均选入变量数 10.00  选中真模型比例 0.00  样本外MSE 1.0608
Cp     平均选入变量数  3.94  选中真模型比例 0.20  样本外MSE 1.0488
AIC    平均选入变量数  4.02  选中真模型比例 0.19  样本外MSE 1.0488
BIC    平均选入变量数  2.45  选中真模型比例 0.25  样本外MSE 1.0473
LOO    平均选入变量数  3.99  选中真模型比例 0.19  样本外MSE 1.0490
--- n=2000, 300 次重复 ---  真模型 n×(样本外MSE-样本内MSE) 平均 9.0(固定设计理论值 2|S|σ²=8)
train  平均选入变量数 10.00  选中真模型比例 0.00  样本外MSE 1.0054
Cp     平均选入变量数  4.06  选中真模型比例 0.32  样本外MSE 1.0038
AIC    平均选入变量数  4.06  选中真模型比例 0.32  样本外MSE 1.0038
BIC    平均选入变量数  3.04  选中真模型比例 0.96  样本外MSE 1.0021
LOO    平均选入变量数  4.07  选中真模型比例 0.32  样本外MSE 1.0038

读法。

  1. 训练误差永远选全模型,样本外误差也最差。真模型的"样本外减样本内"平方误差之和平均约为 8,与定理 13.15 的 \(2|S|\sigma^2=2\times4\times1\) 吻合(本例协变量是随机抽取的而非固定,理论值只是近似,模拟值在其附近波动)。
  2. \(C_p\)、AIC、留一 CV 几乎给出同样的结果,印证了原书"线性回归中 \(C_p\) 与 CV 几乎相同"的说法,也印证了 AIC 与 \(C_p\) 的等价性。
  3. AIC 不具备选择相合性:样本量从 200 增加到 2000,AIC 选中真模型的比例只从 0.19 升到 0.32,平均总是多选约一个变量——这正是习题 9 中"约 16% 的概率多选一个参数"的多变量版本(7 个多余变量,每个都有被多选的机会)。
  4. BIC 小样本时欠选、大样本时相合:\(n=200\) 时 BIC 平均只选 2.45 个变量,常常漏掉系数 0.15 的弱因子;\(n=2000\) 时 96% 的情况下恰好选中真模型。
  5. 本例中 BIC 的样本外误差也略优于 AIC,因为真模型确实稀疏且在候选集中。如果真实世界是"很多微弱因子各贡献一点",结果会反过来。在量化中两种情况都有:风险模型更接近后者,"这个异象是否存在"的判断更接近前者。

实战二:用 logistic 回归预测涨跌,手写 IRLS

场景。 1500 个交易日,用动量、短期反转两个真特征和三个噪声特征预测次日涨跌。真模型的系数很小(0.20 与 −0.15),这是日频方向预测的典型信噪比。

import numpy as np
import statsmodels.api as sm

rng = np.random.default_rng(7)
n = 1500
mom = rng.normal(size=n)              # 标准化动量
rev = rng.normal(size=n)              # 标准化短期反转
noise = rng.normal(size=(n, 3))       # 三个无关特征
X = np.column_stack([np.ones(n), mom, rev, noise])
beta_true = np.array([0.05, 0.20, -0.15, 0, 0, 0])
p_true = 1 / (1 + np.exp(-X @ beta_true))
y = rng.binomial(1, p_true)

def irls(X, y, tol=1e-10, max_iter=50):
    b = np.zeros(X.shape[1])
    for it in range(max_iter):
        p = 1 / (1 + np.exp(-X @ b))
        w = p * (1 - p)
        z = X @ b + (y - p) / w                    # 工作响应 Z_i
        b_new = np.linalg.solve(X.T @ (w[:, None] * X), X.T @ (w * z))   # Z 对 X 的加权最小二乘
        if np.max(np.abs(b_new - b)) < tol:
            b = b_new; break
        b = b_new
    p = 1 / (1 + np.exp(-X @ b))
    J = np.linalg.inv(X.T @ ((p * (1 - p))[:, None] * X))                # Fisher 信息的逆
    ll = np.sum(y * np.log(p) + (1 - y) * np.log(1 - p))
    return b, np.sqrt(np.diag(J)), ll, it + 1

b, se, ll_full, iters = irls(X, y)
sm_fit = sm.Logit(y, X).fit(disp=0)
print(f"IRLS 迭代 {iters} 次收敛")
print("IRLS  beta:", b.round(3), "\n      se  :", se.round(3))
print("statsmodels beta:", sm_fit.params.round(3), " 最大差异", np.abs(sm_fit.params - b).max().round(10))
b_r, se_r, ll_red, _ = irls(X[:, :3], y)
print(f"AIC 得分 ℓ-|S|:全模型 {ll_full - 6:.2f},去掉噪声特征 {ll_red - 3:.2f}")
print(f"BIC 得分:全模型 {ll_full - 3*np.log(n):.2f},去掉噪声特征 {ll_red - 1.5*np.log(n):.2f}")
print(f"动量系数的优势比 e^b = {np.exp(b_r[1]):.3f},95%CI ({np.exp(b_r[1]-1.96*se_r[1]):.3f}, {np.exp(b_r[1]+1.96*se_r[1]):.3f})")

关键输出:

IRLS 迭代 4 次收敛
IRLS  beta: [ 0.037  0.175 -0.12  -0.008  0.053 -0.081] 
      se  : [0.052 0.054 0.052 0.054 0.054 0.051]
statsmodels beta: [ 0.037  0.175 -0.12  -0.008  0.053 -0.081]  最大差异 0.0
AIC 得分 ℓ-|S|:全模型 -1035.64,去掉噪声特征 -1034.40
BIC 得分:全模型 -1051.58,去掉噪声特征 -1042.37
动量系数的优势比 e^b = 1.185,95%CI (1.067, 1.316)

读法。 IRLS 只用 4 步就收敛,结果与 statsmodels 完全一致,说明 statsmodels 内部做的就是 Newton 法。第三个噪声特征的估计为 −0.081(\(|W|\approx1.6\)),单看已有"边缘显著"的样子——这是 1500 天数据中纯噪声能产生的幅度。AIC 和 BIC 都偏好去掉噪声特征的模型,BIC 的偏好更强(差 9.2 对差 1.2)。动量每增加一个标准差,次日上涨的优势乘以 1.185;但要注意这对应的上涨概率只从 50% 变到约 54%,日频方向预测的信号本来就弱,置信区间的宽度也提醒我们这个估计并不精确。

实战三:时间序列中交叉验证的"泄漏"

原书的交叉验证假设观测相互独立。金融数据里最常见的违反方式是重叠标签:用"未来 20 日累计收益"作为预测目标时,相邻两天的标签共享 19 天的收益,高度相关。若再配上缓慢变化的特征,随机打乱的 \(k\) 折 CV 会让测试点的"时间邻居"出现在训练集中,模型只要记住邻居的标签就能"预测"成功。

下面构造一个完全没有可预测性的例子:3 个慢变特征(AR(1) 系数 0.995),收益与特征独立,标签为未来 20 日累计收益。用 \(k\) 近邻回归分别做随机打乱的 5 折 CV 和"前推 + 隔离 20 天"的时间序列 CV。

import numpy as np
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import KFold, TimeSeriesSplit, cross_val_score

rng = np.random.default_rng(7)
T, H = 3000, 20
x = np.zeros((T, 3))
for t in range(1, T):                         # 3 个慢变特征(如估值、拥挤度、利差),AR(1) 系数 0.995
    x[t] = 0.995 * x[t - 1] + rng.normal(scale=0.1, size=3)
r = rng.normal(scale=0.01, size=T + H)        # 日收益:与特征完全无关
y_fwd = np.array([r[t + 1:t + 1 + H].sum() for t in range(T)])   # 未来 20 日累计收益(重叠标签)
knn = KNeighborsRegressor(n_neighbors=5)
cv_shuffle = cross_val_score(knn, x, y_fwd, cv=KFold(5, shuffle=True, random_state=0), scoring="r2")
cv_block = cross_val_score(knn, x, y_fwd, cv=TimeSeriesSplit(5, gap=H), scoring="r2")
print(f"真实可预测性为 0。随机打乱 5 折 CV 的 R²: {cv_shuffle.mean():.3f};前推+隔离 {H} 天 CV 的 R²: {cv_block.mean():.3f}")

关键输出:

真实可预测性为 0。随机打乱 5 折 CV 的 R²: 0.484;前推+隔离 20 天 CV 的 R²: -0.761

读法。 随机打乱的 CV 报告了约 0.48 的样本外 \(R^2\)——对一个完全没有预测力的模型来说,这是彻底错误的结论。原因不是交叉验证的思想错了,而是"测试点与训练点独立"这个前提被破坏:测试点的近邻在时间上紧挨着它,标签有 19/20 是重叠的。前推(只用过去训练)并在训练与测试之间隔离一个标签长度(purging/embargo)之后,\(R^2\) 为负,正确地反映了"无可预测性"(负值说明近邻模型的噪声比直接用均值预测还大)。

规则:时间序列上的模型选择,交叉验证必须按时间顺序分组,并在训练集与测试集之间留出至少一个标签窗口的间隔;涉及多资产横截面时,还要按日期整组划分。第 06 册与第 11 册会在回测框架中具体实现。


本章小结

训练误差把同一份数据用了两次,因此系统性地低估预测风险,偏差为 \(-2\sum\text{Cov}(\hat Y_i,Y_i)\),线性回归中为 \(-2|S|\sigma^2\)——这就是回测过拟合的数学本质。修正的办法有两类:一类给训练误差加上复杂度惩罚(\(C_p\)、AIC、BIC),一类用未参与拟合的数据评估(交叉验证)。\(C_p\)、AIC 和交叉验证追求预测最优,在线性回归中结果几乎相同;BIC 惩罚更重,追求选中真模型,具有选择相合性,而 AIC 没有。\(2^k\) 个模型无法穷举时用逐步回归或 Zheng–Loh 方法,它们都只是在找好的预测组合,与因果无关。Logistic 回归用 logit 链接处理二元结果,系数是对数优势比,用 IRLS(即 Newton 法)求最大似然,Fisher 信息的逆给出标准误。在金融时间序列上使用交叉验证,必须按时间分组并隔离重叠标签。

概念 公式 / 结论
预测风险 \(R(S)=\sum\mathbb E(\hat Y_i(S)-Y_i^*)^2\)
训练误差偏差 \(\mathbb E\hat R_{\text{tr}}-R=-2\sum\text{Cov}(\hat Y_i,Y_i)=-2\lvert S\rvert\sigma^2\)(线性回归)
Mallows \(C_p\) \(\hat R_{\text{tr}}(S)+2\lvert S\rvert\hat\sigma^2_{\text{full}}\),取最小
AIC \(\ell_S-\lvert S\rvert\),取最大;近似无偏估计期望 KL 意义下的样本外对数似然
BIC \(\ell_S-\frac{\lvert S\rvert}{2}\log n\),取最大;\(\mathbb P(S_j\mid\text{data})\approx e^{\text{BIC}_j}/\sum e^{\text{BIC}_r}\)
留一 CV 捷径 \(\sum\big((Y_i-\hat Y_i)/(1-U_{ii})\big)^2\),\(U=X_S(X_S^TX_S)^{-1}X_S^T\)
AIC 多选概率 一个多余参数时 \(\lim\mathbb P(\text{选小模型})=\mathbb P(\chi^2_1<2)\approx0.843\)
Zheng–Loh 按 \(\lvert W_j\rvert\) 排序,最小化 \(\text{RSS}(j)+j\hat\sigma^2\log n\)
Logistic 模型 \(\text{logit}\,p_i=x_i^T\beta\);\(e^{\beta_j}\) 为优势比
IRLS \(Z=\eta+(Y-p)/(p(1-p))\),\(\hat\beta\leftarrow(X^TWX)^{-1}X^TWZ\),\(W=\text{diag}(p(1-p))\)
Logistic 标准误 \(\widehat{\text{se}}(\hat\beta_j)=\sqrt{[(X^TWX)^{-1}]_{jj}}\)

练习

基础

  1. 证明式 (13.25),并证明线性回归中 \(\sum_i\text{Cov}(\hat Y_i,Y_i)=|S|\sigma^2\)。(原书习题 4。)
  2. 正态误差、\(\sigma\) 已知时,证明 AIC 最高的模型就是 \(C_p\) 最低的模型。(原书习题 8。)
  3. 设 \(n=500\)。分别写出 AIC 与 BIC 下"多加入一个变量"所需的最小对数似然增量,以及对应的 Wald 统计量 \(|W|\) 的近似门槛。(提示:嵌套模型中 \(2\Delta\ell\approx W^2\)。AIC 需 \(\Delta\ell>1\),即 \(|W|>\sqrt2\approx1.41\);BIC 需 \(\Delta\ell>\frac12\log500\approx3.11\),即 \(|W|>2.49\)。可见 AIC 的门槛比通常 5% 显著性水平的 1.96 还宽松。)
  4. 某二元特征(如"是否发布业绩预增公告")作为唯一协变量的 logistic 回归给出 \(\hat\beta_1=0.7\),\(\widehat{\text{se}}=0.2\)。求优势比及其 95% 置信区间,并说明它和第 15 章列联表优势比的关系。(答案:\(e^{0.7}\approx2.01\),区间 \((e^{0.31},e^{1.09})\approx(1.36,2.98)\);二者在这种情况下完全相同。)
  5. 写出 logistic 回归对数似然的梯度与 Hessian,验证 IRLS 的一步就是 Newton 法的一步。

进阶

  1. AIC 的选择不相合性(原书习题 9):比较 \(M_0:N(0,1)\) 与 \(M_1:N(\theta,1)\)。(a) 证明 \(\theta=0\) 时 \(\lim_n\mathbb P(J_n=0)=\mathbb P(\chi^2_1<2)\),\(\theta\neq0\) 时极限为 0;(b) 证明无论 \(\theta\) 取何值,AIC 选出的密度与真密度的 KL 距离依概率趋于 0;(c) 对 BIC 重做。
  2. 用 Sherman–Morrison 公式证明留一 CV 捷径公式 (13.29)。
  3. 修改实战一:把真系数改为 10 个都非零但很小(例如都等于 0.08),比较 AIC 与 BIC 的样本外误差,并与原结果对照解释。
  4. 修改实战一:把 \(k\) 增加到 30,改用前向逐步回归(以 AIC 为得分)代替全枚举,并实现 Zheng–Loh 方法,比较选中真模型的频率与计算量。
  5. 在实战三中把 TimeSeriesSplit 的 gap 改为 0,再把 \(k\) 近邻换成线性回归,观察泄漏程度的变化,并解释为什么灵活模型的泄漏更严重。

原书推荐习题:第 13 章 4(训练误差偏差,必做)、8(AIC 与 \(C_p\) 等价)、9(AIC 与 BIC 的相合性,核心概念题,必做)、7(汽车油耗数据:\(C_p\)、前向/后向逐步、Zheng–Loh、全子集 BIC 的比较)、11(CORIS 数据的 AIC 后向逐步 logistic 回归)。


原书对照

本章内容 原书章节 PDF 页码
偏差–方差、预测风险、训练误差偏差(定理 13.15) 13.6 p.227–232
\(C_p\)、AIC、交叉验证、BIC 13.6 p.227–232
模型搜索、例 13.16、Zheng–Loh 13.6 p.227–232
Logistic 回归、IRLS、例 13.17(CORIS) 13.7 p.232–234
文献评注 13.8 p.234
附录:AIC 的推导 13.9 p.234–235
习题 13.10 p.235–238