第 27 章 案例:预测与金融时间序列
本章对应原书第 27 章(案例研究 5:预测),并附原书附录 A–C 的简要说明。原书案例是为磁悬浮系统建立 NARX 动态模型:用过去的位置和电流预测下一时刻的位置。这是全书唯一一个输入为时间序列、并明确按时间顺序划分测试集的案例,与量化中的收益预测在形式上完全相同。但两者有一个根本差别:磁悬浮是确定性的物理系统,金融收益的信噪比极低且不平稳。本章先把原书案例讲透,再用一节完整的量化实战,说明把 NARX 搬到金融时间序列上时,数据处理、划分、评估、多步预测各要改什么。
学习目标
读完本章,你应当能够:
- 写出 NARX 模型 \(y(t)=f(y(t-1),\dots,y(t-n_y),u(t-1),\dots,u(t-n_u))\),说明它与线性 ARX 的关系。
- 解释系统辨识中激励信号(skyline 函数)的设计原则,以及"测试集取末尾连续一段"的理由。
- 区分 NARX 的并联形式与串并联形式,说明为什么串并联形式可以用静态反向传播训练,以及为什么它只保证一步预测好。
- 用误差自相关和误差–输入互相关检验预测模型,并据此调整延迟阶数;用并联形式的多步迭代预测做更严格的检验。
- 把这套流程用到金融收益预测:无前视的波动标准化、按时间的 walk-forward 与间隔、线性基准、样本外 \(R^2\)/IC/夏普、残差 Ljung–Box 检验、多步预测的衰减。
- 判断一个"神经网络收益预测"结果是否可信。
读前导读
这一章在解决什么问题
一句话:怎样用一个变量自己的过去和其他变量的过去来预测它的下一期,以及怎样判断这个预测"已经把能用的信息用完了"。
你在 CFA 二级的时间序列部分见过 AR(1)、AR(p):\(x_t=b_0+b_1x_{t-1}+\varepsilon_t\),并且学过一条检验规则——残差的自相关系数要用 \(t=\hat\rho/(1/\sqrt T)\) 检验,显著就说明模型还要加滞后项。本章做的是同一件事的两个推广:第一,把右边的线性函数换成神经网络 \(f(\cdot)\),并加入外生变量(ARX → NARX);第二,残差检验从"自己和自己"扩展到"残差和输入之间"。式 (27.7) 的置信界 \(\pm2R_e(0)/\sqrt Q\),本质上就是你熟悉的 \(\pm 2/\sqrt T\) 乘上了残差方差。
前半章是原书的工程案例(磁悬浮),它的作用是让你在一个"答案已知、噪声很小"的系统上看清整套流程。后半章把流程搬到金融收益上,核心结论和你做投资研究的经验一致:信号很弱、关系会漂移、线性模型往往已经够用、多步预测几天后就退化成均值。
需要先想起来的数学
- 导数与微分方程。\(\frac{dy}{dt}\) 是位置对时间的变化率,即速度;\(\frac{d^2y}{dt^2}\) 是速度的变化率,即加速度。式 (27.1) 就是牛顿第二定律"加速度 = 合力 / 质量"写成的方程,含二阶导数,所以叫"二阶"微分方程。离散化时,速度近似为 \(\frac{y(t)-y(t-1)}{\Delta t}\)。例:0.01 秒内位置从 2.000 变到 2.003,速度约 0.3。见 第 00 册第 02 章 导数与泰勒展开。
- 自协方差与求和记号。\(\frac{1}{Q-\tau}\sum_{t=1}^{Q-\tau}e(t)e(t+\tau)\) 就是"把序列错开 \(\tau\) 期,对齐后逐项相乘再取平均",即滞后 \(\tau\) 的样本自协方差(假设均值为零)。\(\tau=0\) 时就是方差。例:\(e=(1,-1,1,-1)\),\(\tau=1\) 时三对乘积都是 \(-1\),\(R_e(1)=-1\),强烈负相关。见 第 00 册第 07 章 概率中的分析工具。
- 样本相关系数的抽样分布。若真实相关为零,\(Q\) 个样本算出的相关系数近似服从均值 0、标准差 \(1/\sqrt Q\) 的正态分布,所以 95% 置信界约为 \(\pm2/\sqrt Q\)。\(Q=1000\) 时界为 \(\pm0.063\)。这是本章所有"超界"判断的来源。
- 几何级数。EWMA 波动 \(\hat\sigma^2_t=\lambda\hat\sigma^2_{t-1}+(1-\lambda)r^2_{t-1}\) 反复展开后,权重是 \((1-\lambda),(1-\lambda)\lambda,(1-\lambda)\lambda^2,\dots\),总和为 \((1-\lambda)\cdot\frac{1}{1-\lambda}=1\),和你算永续年金用的是同一个公式。见 第 00 册第 04 章 级数与收敛。
- tanh 函数。\(\tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}\),取值在 \((-1,1)\),在 0 附近近似 \(x\),绝对值大时饱和到 \(\pm1\)。网络的隐层用它,27.7.6 节的模拟信号 \(0.12\tanh(1.5x)\) 也用它,含义是"外生变量越大收益越高,但效果有上限"。见 第 00 册第 01 章 函数极限与连续。
怎么读这一章
核心必读:27.3(NARX 与两种形式)、27.5.2(误差两条性质与置信界)、27.5.4 和 27.6 末尾的"一步与多步的差别"、整个 27.7。27.1 的物理方程和 27.2 的 skyline 激励第一次可以只看结论;27.4 的有效参数个数如果你没读过第 23 章,先记住"它类似 Ridge 回归的有效自由度"即可。两段代码第一次阅读只看"关键输出"及其后的解读,理解流程后再回头看代码。最后用 27.7.7 的检查清单回顾全章。
27.1 问题:预测与系统辨识
预测是一种动态滤波:用一个或多个时间序列的过去值预测未来值,使用第 10、14 章的动态网络。原书列举的应用包括:金融分析师预测股票、债券等金融工具的未来价值;工程师预测喷气发动机即将失效;以及系统辨识(system identification),即用数据建立物理系统的动态模型,用于制造系统、化工过程、机器人、航空航天等领域的分析、仿真、监控与控制。
本案例的对象是磁悬浮系统:一块磁铁悬浮在电磁铁上方,只能竖直运动,目标是控制它的位置。运动方程为
白话解释:左边 \(\frac{d^2y}{dt^2}\) 是加速度,右边是"每单位质量受的合力",整个式子就是牛顿第二定律 \(a=F/M\)。\(\mathrm{sgn}[i]\) 是符号函数(\(i>0\) 取 1,\(i<0\) 取 \(-1\)),配合 \(i^2\) 使得 \(i^2\,\mathrm{sgn}(i)=i|i|\):大小随电流平方增长,方向随电流方向翻转。\(\frac{dy}{dt}\) 是速度,阻尼项与速度成正比、方向相反,相当于"摩擦"。你不需要会解这个方程,只要知道两点:它是非线性的(\(i^2/y\)),所以需要神经网络而不是线性 ARX;它是二阶的,所以系统的"状态"由位置和速度两个量决定,这直接决定了下面延迟阶数的初值。
案例的目标是建立一个动态神经网络模型,由过去的位置和电流预测下一时刻的位置。模型建好后可以用来设计控制器(确定使磁铁到达期望位置的电流),控制设计不在本章范围。
27.2 数据收集与预处理
27.2.1 激励信号:skyline 函数
原书没有搭建实物,而是用 Simulink 仿真式 (27.1):电流在 \(-1\) 到 4 安之间,每 0.01 秒采样一次,共 4000 个数据点。
要得到准确的模型,系统的输入和输出必须覆盖将来使用的整个工作范围。系统辨识中常用的输入是由随机幅度、随机宽度的脉冲组成的序列,形似城市天际线,称为 skyline 函数。脉冲的宽度和幅度都要仔细选择:
- 长脉冲末端系统接近稳态,用来学稳态特性;短脉冲用来学暂态特性。
- 稳态性能差,可以加长脉冲;但稳态数据过多,训练集就不能代表典型工况,暂态性能反而会变差。
- 所以应当使用宽度和幅度都有一定范围的输入,兼顾暂态与稳态。
这条原则在量化里的对应物是:训练数据应当覆盖不同的市场状态(牛市、熊市、高波动、低波动、流动性危机),否则模型只在单一状态下有效。区别在于,物理系统的激励可以由工程师设计,而市场的"激励"只能等它自己发生。
27.2.2 划分与归一化
用贝叶斯正则化训练,不需要验证集;留 15% 作测试。原书特别指出:输入是时间序列时,测试序列宜取原数据中的连续一段,这里取最后 15%。理由很直接:时间序列相邻样本高度相关,随机抽取的测试点会被训练点"包围",测出来的性能不能代表对未来的预测能力。
输入和目标用式 (22.1) 缩放到 \([-1,1]\)。
27.3 结构选择:NARX 网络
27.3.1 NARX 模型
NARX(nonlinear autoregressive with exogenous inputs,带外生输入的非线性自回归)模型是时间序列建模中线性 ARX 模型的非线性推广:
还要确定两条抽头延迟线的长度 \(n_u\) 和 \(n_y\)。式 (27.1) 是二阶微分方程,所以先取 \(n_y=n_u=2\),之后再检验其他取值。物理直觉是:二阶系统的状态是位置和速度,用 \(y(t-1)\) 和 \(y(t-2)\) 恰好能表示这两者。
推导拆解:为什么两个滞后够用?离散化后,位置就是 \(y(t-1)\),速度可以用差分近似:\(\dot y(t-1)\approx\frac{y(t-1)-y(t-2)}{\Delta t}\)(这里用的是导数的定义,把极限换成有限的 \(\Delta t=0.01\))。知道了"当前位置 + 当前速度 + 当前受力(由电流 \(u\) 决定)",牛顿定律就能推出下一时刻的位置。所以 \(\{y(t-1),y(t-2),u(t-1),u(t-2)\}\) 在原理上包含了预测 \(y(t)\) 所需的全部状态信息。实际中差分近似和采样会带来误差,所以 27.5.3 节最终把阶数加到 4。
金融直觉:金融收益没有"物理阶数"可依,延迟阶数只能靠数据选,通常用信息准则(AIC/BIC)或残差检验,这就是 CFA 里"残差自相关显著就加 AR 阶数"的做法。
27.3.2 并联形式与串并联形式
NARX 有两种形式(原书图 27.5):
- 并联形式(parallel):标准 NARX 把网络自己输出的估计值 \(\hat y\) 反馈到输入端。这是模型实际使用时的形式,也是做多步预测的形式。
- 串并联形式(series-parallel):训练时真实输出是已知的,可以用真实的 \(y(t-1),\dots\) 代替反馈的估计值。
串并联形式有两个好处:一是前馈网络的输入更准确;二是整个网络变成纯前馈结构,可以用静态反向传播训练。此时直接用一个标准多层网络实现 NARX,输入向量由过去的输入和输出组成:
在机器学习中,串并联训练又叫 teacher forcing。它的代价是:训练只优化了一步预测误差,模型在自己的预测被反馈回来时(并联形式)表现如何,训练过程完全没有约束。这一点在验证环节要单独检查。
白话解释:式 (27.4) 里的 "\(t=y(t)\)" 容易看糊涂:左边的 \(t\) 是原书记号里的目标(target,原书用粗体 \(\mathbf t\)),右边括号里的 \(t\) 才是时间。意思是"第 \(t\) 个样本的输入是 \(\mathbf p(t)\),目标是 \(y(t)\)"。这样一来,每个时间点就变成一行普通的回归数据,和你用 Excel 做"\(y\) 对四个滞后变量回归"没有区别。
金融直觉:串并联与并联的区别,相当于回测一个日度模型时"每天都用真实的昨日数据重新预测"与"只给第一天的真实数据,之后用自己的预测值往前滚"。前者检验的是一步预测能力;后者检验的是模型能否独立模拟一条路径,类似用模型做多期情景模拟,误差会层层叠加。
27.4 训练
- Nguyen–Widrow 初始化,贝叶斯正则化训练。预测问题与第 23 章的函数逼近类似,该方法对两者都有效。
- 有 4000 个数据点,而权值和偏置不到 100 个,其实不太可能过拟合,并不需要贝叶斯正则化或提前停止;但贝叶斯正则化能给出有效参数个数,所以作者只要适用就喜欢用。
- \(S^1=10\),训练 1000 次迭代后性能变化很小;多个不同初值训练的最终误差平方和相近,可以确信没有陷入局部极小。
- 有效参数个数收敛到 39。4-10-1 网络共有 \(4\times10+10+10+1=61\) 个参数,有效使用了不到 2/3。若有效参数接近总参数,应当增加隐层神经元重训,这里不需要;也无需减少神经元:计算时间不关键,而就防止过拟合而言,39 个有效参数等价于网络总共只有 39 个参数。这正是贝叶斯正则化的好处:只要网络里潜在的参数足够多,它会为每个问题选出合适的参数数。
白话解释:"有效参数个数"不是数出来的,而是衡量"正则化之后参数实际上还有多少自由度"。最熟悉的类比是 Ridge 回归:惩罚为 \(\lambda\) 时,有效自由度为 \(\sum_j\frac{d_j^2}{d_j^2+\lambda}\)(\(d_j\) 是设计矩阵的奇异值)。每一项在 0 和 1 之间:数据强烈支持的方向(\(d_j^2\gg\lambda\))几乎算一个完整参数,数据不支持的方向(\(d_j^2\ll\lambda\))几乎被压成零、不算参数。贝叶斯正则化的 \(\gamma\) 是同样的思路(第 23 章)。61 个参数里有效 39 个,意味着约 22 个"方向"被正则化压住了,网络大小留有余量。
27.5 验证
27.5.1 散点图
测试集的散点图与训练集一样贴近 45° 线,没有过拟合。但对预测问题,这还远远不够。
27.5.2 预测误差的两条基本性质
预测误差
- 相邻时间步的误差互不相关;
- 误差与输入序列 \(u(t)\) 不相关。
否则就能利用这种相关性改进预测。例如,如果相隔一步的误差正相关,那么当前一个大的正误差就预示下一步误差也为正,把下一步的预测调高就能减小误差。输入与误差相关时同理。
自相关检验:
互相关检验:
推导拆解:两个置信界其实是同一条规则换了单位。 第一步,把自协方差除以方差,得到自相关系数:\(\hat\rho_e(\tau)=R_e(\tau)/R_e(0)\)。 第二步,若误差是白噪声(各期独立),样本自相关系数近似服从 \(N(0,1/Q)\),所以 95% 置信区间约为 \(|\hat\rho_e(\tau)|<1.96/\sqrt Q\approx2/\sqrt Q\)。这就是 CFA 里残差自相关 \(t\) 检验 \(t=\hat\rho/(1/\sqrt T)\) 的同一个结论。 第三步,两边乘回 \(R_e(0)\),得到式 (27.7):\(|R_e(\tau)|<2R_e(0)/\sqrt Q\)。 互相关同理:相关系数是 \(R_{ue}(\tau)/\sqrt{R_e(0)R_u(0)}\)(协方差除以两个标准差),在"误差是白噪声且与 \(u\) 独立"的原假设下标准差也约为 \(1/\sqrt Q\),乘回分母就是式 (27.9)。 注意:同时检验 20 个滞后时,即使模型完美,平均也会有约 1 个滞后"偶然超界"(20×5%),所以看到 1–2 个超界不必紧张,要看超界的数量和幅度。这也是 Ljung–Box 联合检验存在的原因。
27.5.3 用检验结果调整延迟阶数
- \(n_y=n_u=2\)、\(S^1=10\) 时,误差自相关在若干点超出置信界,提示需要增大 \(n_y\)、\(n_u\);互相关都在界内。
- 把 \(n_y\)、\(n_u\) 增到 4 重训后,自相关除 \(\tau=0\) 外都在界内,互相关也都远在界内。此时预测误差是白噪声且与输入不相关,模型是准确的。
这体现了第 22 章的迭代精神:不是看误差小就满意,而是看误差里还有没有可以被利用的结构。
27.5.4 一步预测与多步迭代预测
最终模型的一步预测误差非常小(归一化单位下约 \(10^{-4}\) 量级),但因为是串并联形式,这只是一步预测误差:每一步都用真实的过去位置作输入。更严格的检验是把网络改回并联形式,做多步迭代预测:只给初始几个真实位置,之后每一步都把自己的预测反馈回去。原书图 27.14 显示,即使提前 600 个时间步(6 秒)预测,NARX 仍然非常准确。
27.6 复现:磁悬浮系统的 NARX 辨识
下面用 Python 复现整个案例:按式 (27.1) 仿真 4000 点 skyline 激励数据,缩放到 \([-1,1]\)(统计量只用训练段),用串并联形式训练 \(n=2\) 与 \(n=4\) 两个 NARX 网络,做自相关、互相关检验,然后改回并联形式做 600 步迭代预测,比较 5 个随机初值及其委员会。
与原书有两处实现差异,先说明:一是仿真里电流为负时磁铁会被拉到电磁铁上,我们在 \(y=0.05\) 处加了一个"接触"边界;二是让网络学习标准化的增量 \(y(t)-y(t-1)\),再加回 \(y(t-1)\) 得到 \(y(t)\)。后者只是目标的重新参数化,模型仍是式 (27.2) 的 NARX;这样做是因为 0.01 秒内位置变化极小,直接拟合 \(y(t)\) 时损失函数数值太小,lbfgs 会过早触发停止条件。这也是金融里直接预测收益(增量)而不是价格的原因之一。
import numpy as np, warnings
from sklearn.neural_network import MLPRegressor
warnings.filterwarnings("ignore")
rng = np.random.default_rng(0)
# ---------- 磁悬浮系统式(27.1)的仿真, skyline 随机脉冲输入 ----------
alpha, beta, g, M = 15.0, 12.0, 9.8, 3.0
N, dt, sub = 4000, 0.01, 50 # 4000 点, 每 0.01 秒采样, 内部 50 个欧拉子步
u = np.empty(N); k = 0
while k < N: # 随机幅度 [-1,4] A、随机宽度 0.05~1.5 s
w = rng.integers(5, 150); u[k:k + w] = rng.uniform(-1, 4); k += w
y = np.empty(N); pos, vel, h = 2.0, 0.0, dt / sub
for t in range(N):
y[t] = pos
for _ in range(sub):
acc = -g + alpha / M * u[t] ** 2 * np.sign(u[t]) / pos - beta / M * vel
vel += h * acc; pos += h * vel
if pos < 0.05: pos, vel = 0.05, 0.0 # 磁铁落到电磁铁上
# 式(22.1) 缩放到 [-1,1]; 统计量只用前 85%(训练段)
ntr = int(0.85 * N)
sc = lambda x: 2 * (x - x[:ntr].min()) / (x[:ntr].max() - x[:ntr].min()) - 1
un, yn = sc(u), sc(y)
def design(n): # 串并联 NARX 输入 p(t) = [u(t-1..t-n), y(t-1..t-n)], 目标 y(t)
P = np.column_stack([un[n - i:N - i] for i in range(1, n + 1)] + [yn[n - i:N - i] for i in range(1, n + 1)])
return P, yn[n:]
def corr_check(e, x, maxlag=20):
Q = len(e); Re0, Rx0 = e @ e / Q, x @ x / Q
Re = np.array([e[:Q - k] @ e[k:] / (Q - k) for k in range(1, maxlag + 1)])
Rxe = np.array([x[:Q - k] @ e[k:] / (Q - k) for k in range(0, maxlag + 1)])
return (np.sum(np.abs(Re) > 2 * Re0 / np.sqrt(Q)), np.abs(Re).max() / (2 * Re0 / np.sqrt(Q)),
np.sum(np.abs(Rxe) > 2 * np.sqrt(Re0 * Rx0) / np.sqrt(Q)))
class NARX: # 网络学习增量 y(t)-y(t-1)(标准化后), 输出仍是 y(t); 只是目标的重新参数化
def __init__(self, n, seed=0): self.n, self.seed = n, seed
def fit(self, P, T):
D = T - P[:, self.n]; self.s = D.std()
self.net = MLPRegressor(hidden_layer_sizes=(10,), activation="tanh", solver="lbfgs", alpha=1e-6,
max_iter=20000, max_fun=50000, tol=1e-12, random_state=self.seed).fit(P, D / self.s)
return self
def predict(self, P): return P[:, self.n] + self.s * self.net.predict(P)
for n in (2, 4):
P, T = design(n); tr, te = np.arange(ntr - n), np.arange(ntr - n, len(T)) # 测试 = 末尾连续 15%
net = NARX(n).fit(P[tr], T[tr])
e = T - net.predict(P)
a, ratio, b = corr_check(e[tr], un[n:][tr])
print(f"n_u=n_y={n}: 一步预测 RMSE(归一化单位) 训练 {np.sqrt(np.mean(e[tr]**2)):.2e} 测试 {np.sqrt(np.mean(e[te]**2)):.2e}"
f" | 自相关超界 {a}/20 (最大值为界的 {ratio:.1f} 倍) | 互相关超界 {b}/21")
# ---------- 改回并联形式: 用自己的预测反馈, 从测试段起点迭代预测 600 步 ----------
n, start, H = 4, ntr, 600
to_raw = lambda z: (z + 1) * (y[:ntr].max() - y[:ntr].min()) / 2 + y[:ntr].min()
P, T = design(n); tr = np.arange(ntr - n)
nets = [NARX(n, seed).fit(P[tr], T[tr]) for seed in range(5)]
def iterate(members):
yhat = list(yn[start - n:start]) # 只用起点之前的真实输出初始化
for t in range(start, start + H):
p = np.r_[un[t - n:t][::-1], np.array(yhat[-n:])[::-1]] # [u(t-1..t-n), ŷ(t-1..t-n)]
yhat.append(np.mean([m.predict(p[None])[0] for m in members]))
return to_raw(np.array(yhat[n:]))
truth = y[start:start + H]
for k, m in enumerate(nets):
one = np.sqrt(np.mean((to_raw(m.predict(P[ntr - n:ntr - n + H])) - truth) ** 2))
par = np.sqrt(np.mean((iterate([m]) - truth) ** 2))
print(f"种子 {k}: 原始单位 RMSE: 一步预测 {one:.1e} 并联迭代 {H} 步 {par:.4f}")
yc = iterate(nets)
print(f"5 网络委员会: 并联迭代 RMSE {np.sqrt(np.mean((yc - truth) ** 2)):.4f} (测试段位置标准差 {truth.std():.4f})")
for step in (1, 10, 100, 300, 600):
print(f" 第 {step:>3} 步: 真实 {truth[step - 1]:.3f} 委员会预测 {yc[step - 1]:.3f}")
关键输出:
n_u=n_y=2: 一步预测 RMSE(归一化单位) 训练 3.73e-04 测试 1.60e-04 | 自相关超界 19/20 (最大值为界的 8.7 倍) | 互相关超界 0/21
n_u=n_y=4: 一步预测 RMSE(归一化单位) 训练 3.05e-04 测试 9.83e-05 | 自相关超界 3/20 (最大值为界的 8.5 倍) | 互相关超界 0/21
种子 0: 原始单位 RMSE: 一步预测 2.9e-04 并联迭代 600 步 0.5769
种子 1: 原始单位 RMSE: 一步预测 3.1e-04 并联迭代 600 步 0.1868
种子 2: 原始单位 RMSE: 一步预测 2.4e-04 并联迭代 600 步 0.1289
种子 3: 原始单位 RMSE: 一步预测 1.8e-04 并联迭代 600 步 0.1201
种子 4: 原始单位 RMSE: 一步预测 2.7e-04 并联迭代 600 步 0.2397
5 网络委员会: 并联迭代 RMSE 0.1037 (测试段位置标准差 0.6024)
第 1 步: 真实 2.620 委员会预测 2.621
第 10 步: 真实 2.814 委员会预测 2.817
第 100 步: 真实 4.151 委员会预测 4.016
第 300 步: 真实 3.968 委员会预测 3.974
第 600 步: 真实 4.312 委员会预测 4.095
延迟阶数。 \(n=2\) 时 20 个滞后中有 19 个自相关超界;\(n=4\) 时降到 3 个,与原书"把 2 增到 4 后误差变白"的结论方向一致。我们的 \(n=4\) 模型在一阶滞后上仍超界较多,主要来自仿真中的接触边界(磁铁撞到电磁铁时动态不光滑),按第 22 章的流程,下一步可以再加神经元或延迟,或者为接触状态单独建模。互相关始终在界内。
一步与多步的差别。 这是本节最值得记住的结果。5 个随机初值的一步预测误差都在 \(2\times10^{-4}\) 左右,几乎无法区分;改成并联形式迭代 600 步后,误差却从 0.12 到 0.58 不等,种子 0 的误差几乎和位置本身的标准差一样大。原因是串并联训练只约束了一步映射,而多步迭代时,小的模型误差会沿着反馈回路累积,结果取决于模型在"自己造成的、训练中没见过的状态"附近的行为,不同初值在这些区域差别很大。5 个网络组成委员会后,600 步迭代误差降到 0.104,约为位置标准差的六分之一,比任何单个网络都好,这是第 22 章委员会方法在动态模型上的价值。结论是:对动态模型,必须在并联形式下验证,并且要看多个初值,而不是挑一个一步误差最小的就交差。
推导拆解:为什么一步误差几乎一样,多步误差却差几倍?用最简单的线性情形看。设真实系统 \(y(t)=a\,y(t-1)\),模型估出 \(\hat a=a+\delta\),\(\delta\) 很小。 一步预测:\(\hat y(t)-y(t)=\delta\,y(t-1)\),误差与 \(\delta\) 同阶,很小。 迭代 \(h\) 步:\(\hat y(t+h)=\hat a^{h}y(t)\),误差为 \((\hat a^h-a^h)y(t)\)。对 \(a^h\) 求导(幂函数求导 \(\frac{d}{da}a^h=h\,a^{h-1}\))作一阶泰勒近似,得 \(\hat a^h-a^h\approx h\,a^{h-1}\delta\)。 当 \(|a|\) 接近 1(系统"记忆长",如磁悬浮的位置),\(a^{h-1}\) 衰减很慢,误差约以 \(h\) 倍放大;600 步就是几百倍。非线性系统里还要加上"轨迹进入训练中没见过的区域"这个因素,放大得更不规则。所以一步误差相差 1.7 倍的几个模型,多步误差可以相差近 5 倍。 委员会平均之所以有效,是因为各网络的 \(\delta\) 方向不同,平均后部分抵消,类似组合分散化降低了非系统性误差。
27.7 量化实战:用 NARX 预测金融收益
27.7.1 磁悬浮与金融序列的根本差别
形式上,用收益和外生变量(资金流、情绪、利差、成交量、期货基差等)的滞后项预测下一期收益,就是式 (27.2) 的 NARX,线性版本就是 ARX/ARDL。但两类问题在四个方面截然不同:
| 方面 | 磁悬浮(原书案例) | 金融收益 |
|---|---|---|
| 噪声 | 确定性系统,误差可以压到 \(10^{-4}\) | 信噪比极低,日度可预测部分的 \(R^2\) 通常只有百分之一的量级 |
| 平稳性 | 物理规律不变 | 波动率聚集、关系随时间衰减或反转 |
| 外生输入 | 电流是控制量,未来值已知 | 外生变量的未来值未知,多步预测还要预测它们 |
| 激励设计 | 可以设计 skyline 输入覆盖工况 | 只能被动接受历史上发生过的状态 |
这些差别决定了下面每一条改动。
27.7.2 数据处理
预测收益而不是价格。 价格非平稳且高度自相关,预测"明天价格 ≈ 今天价格"就能得到极高的 \(R^2\) 和漂亮的散点图,但毫无价值。目标应是收益(增量),评估也要针对收益。
无前视的波动标准化。 收益的方差随时间剧烈变化(GARCH 效应,第 06 册第 03a 章),直接用原始收益训练,损失会被高波动时期主导。常用做法是除以只用 \(t-1\) 及以前信息估计的波动,例如 EWMA:
金融直觉:这就是 RiskMetrics 的 EWMA 波动模型,日度常用 \(\lambda=0.94\),也是你在 VaR 计算里见过的那个。把递推式反复代入展开:\(\hat\sigma^2_t=(1-\lambda)\sum_{k\ge1}\lambda^{k-1}r^2_{t-k}\),权重按几何级数衰减、总和为 1,平均"回看期"约 \(1/(1-\lambda)\approx17\) 天。除以 \(\hat\sigma_t\) 后,\(z_t\) 大致变成单位方差的序列,2008 年和 2017 年的一天在损失函数中的分量才可比。 前视的典型错误是用全样本标准差,或用包含当天的滚动窗口(如
rolling(20).std()后忘了滞后一期):这样 \(z_t\) 里暗含了 \(|r_t|\) 的信息,回测会虚高。
时间对齐。 输入里的每个变量都必须在决策时刻已经可得:收盘后才公布的数据只能用于下一个交易日;财务数据要按公告日而不是报告期对齐;宏观数据要用当时的初值而不是事后修订值。
归一化统计量只来自训练窗。 每次重训都重新计算均值、标准差,然后原样用于该窗口之后的测试期。
27.7.3 划分与训练
扩展窗口 walk-forward。 原书"测试集取末尾连续一段"推广为:在 \([0,s)\) 训练、在 \([s,s+\Delta)\) 测试,然后 \(s\leftarrow s+\Delta\) 重训。这样能得到一整段连续的样本外预测,并模拟真实的定期重训。
间隔(purge/embargo)。 标签是 1 日收益时,训练窗末尾与测试窗之间隔 1 天即可;标签是 \(H\) 日累计收益时,要删去训练窗末尾 \(H\) 个样本(第 22 章)。
提前停止的验证集取训练窗末尾,同样隔开,不能随机抽取。
先建线性基准。 原书第 22 章的第一条建议:线性方法够用就不用神经网络。在收益预测中,NARX 必须在同样的 walk-forward 下击败 ARX(如 Ridge),才值得用。
委员会。 低信噪比下单个网络方差很大,5–10 个随机种子的平均几乎总是值得的。
27.7.4 评估
- 样本外 \(R^2\):以训练期均值(或零)为基准,\(R^2_{oos}=1-\sum(y-\hat y)^2/\sum(y-\bar y_{train})^2\)。日度收益上 \(R^2_{oos}\) 为正、哪怕只有 0.5%,在经济上就可能有意义。
- IC:预测值与实现收益的相关系数。
- 策略表现:把预测转成仓位后的收益、夏普比率,扣除交易成本后再看。
- 残差白噪声检验:式 (27.6)–(27.7) 的逐滞后检验,加上 Ljung–Box 联合检验(第 06 册第 02a 章)。在金融里,收益本身就接近白噪声,所以"残差是白噪声"几乎总能通过,它是必要条件而不是模型好的证据。
- 残差与外生变量的互相关:式 (27.8)–(27.9) 的思想。若残差与某个变量(或其非线性变换)的滞后项相关,说明还有信息没用上。
- 分时段评估:非平稳意味着性能会随时间变化,要分段报告,并持续监控。
白话解释:几个指标之间的关系。 样本外 \(R^2\) 与普通 \(R^2\) 不同,它的分母用的是训练期均值,所以可以为负:负值意味着模型还不如"永远预测历史均值"。 \(R^2\) 与 IC 的关系:如果预测值经过最优线性缩放,\(R^2_{oos}\approx\mathrm{IC}^2\)。下文前段 Ridge 的 IC 为 0.089,\(0.089^2\approx0.0079\),与报告的 \(R^2_{oos}=0.0075\) 很接近。这说明 \(R^2\) 小得"吓人"其实只是 IC 平方后的结果;IC 为 0.05–0.1 在实务中已经算可用的信号。 IC 与夏普的联系可以用 Grinold 的主动管理基本定律粗略估计:\(\mathrm{IR}\approx\mathrm{IC}\times\sqrt{\text{每年独立下注次数}}\)。单资产日度择时一年约 252 次下注,\(0.089\times\sqrt{252}\approx1.4\),与下文约 1.1 的夏普同一量级(仓位截断、波动变化会使实际值偏低)。 Ljung–Box 检验把多个滞后的自相关合成一个统计量:\(Q_{LB}=n(n+2)\sum_{k=1}^{m}\frac{\hat\rho_k^2}{n-k}\),原假设"前 \(m\) 阶自相关全为零"下近似服从自由度为 \(m\) 的 \(\chi^2\) 分布。\(p\) 值大表示没发现自相关。
27.7.5 多步预测
磁悬浮可以并联迭代 600 步,是因为系统确定、外生输入已知。金融里做多步预测有两条路:
- 迭代(并联)预测:把自己的一步预测反馈回去,外生变量的未来值用它自己的预测(如 AR 模型的条件期望)代替。误差会累积,且预测值迅速收缩到均值。
- 直接预测:为每个步长 \(h\) 单独训练一个预测 \(y(t+h)\) 的模型,不需要反馈,但要处理重叠标签。
无论哪条路,都要预期预测能力随步长迅速衰减。不要拿原书 600 步的精度去类比收益预测。
推导拆解:为什么迭代预测会"收缩到均值"?以 27.7.6 节的外生变量 \(x_t=0.7x_{t-1}+\varepsilon_t\) 为例。站在 \(t\) 时刻,下一期的条件期望是 \(\mathbb E_t[x_{t+1}]=0.7x_t\)(\(\mathbb E_t\) 表示用 \(t\) 时刻已知信息求的条件期望;\(\varepsilon\) 的期望为 0)。再往后一步,用期望的线性性:\(\mathbb E_t[x_{t+2}]=0.7\,\mathbb E_t[x_{t+1}]=0.7^2x_t\),依此类推 \(\mathbb E_t[x_{t+h}]=0.7^hx_t\)。\(0.7^{9}\approx0.04\),所以 10 步后 \(x\) 能提供的信息只剩约 4%。收益的信号又由 \(x\) 驱动,预测值自然随步长几何衰减到零(均值)。这和债券久期里"远期现金流贴现后权重很小"是同一种几何衰减。
27.7.6 代码:walk-forward NARX 与线性基准
下面模拟 5000 个交易日:收益有 GARCH(1,1) 波动;标准化收益的条件均值由外生变量 \(x\)(AR(1))的非线性函数 \(0.12\tanh(1.5x_{t-1})\) 和一个"大幅波动后反转"项组成,第 3500 天之后信号强度减半(模拟非平稳的信号衰减)。流程:EWMA 无前视波动标准化;NARX 输入为 \(z\) 和 \(x\) 各 5 个滞后;从第 1500 天开始扩展窗口 walk-forward,每 250 天重训;对照 Ridge(ARX)和 5 个 MLP 的委员会(提前停止的验证集取训练窗末尾 15%);分段报告样本外 \(R^2\)、IC、简单策略夏普、Ljung–Box;检验残差与 \(\tanh(1.5x_{t-1})\) 的相关;最后做 1–10 步的并联迭代预测。
import numpy as np, warnings, copy
from sklearn.neural_network import MLPRegressor
from sklearn.linear_model import Ridge
from statsmodels.stats.diagnostic import acorr_ljungbox
warnings.filterwarnings("ignore")
rng = np.random.default_rng(2026)
# ---------- 模拟日频数据: GARCH 波动 + 弱的非线性可预测性 + 外生变量 ----------
T = 5000
x = np.zeros(T); r = np.zeros(T); sig2 = np.full(T, 1e-4); z = np.zeros(T)
for t in range(1, T):
x[t] = 0.7 * x[t - 1] + np.sqrt(1 - 0.49) * rng.normal() # 外生变量(如资金流/情绪), AR(1)
sig2[t] = 1e-6 + 0.08 * r[t - 1] ** 2 + 0.90 * sig2[t - 1] # GARCH(1,1)
k = 1.0 if t < 3500 else 0.5 # 第 3500 天后信号衰减一半(非平稳)
mean = k * (0.12 * np.tanh(1.5 * x[t - 1]) - 0.06 * z[t - 1] * min(abs(z[t - 1]), 2))
z[t] = mean + rng.normal() # 标准化收益
r[t] = np.sqrt(sig2[t]) * z[t]
# 只用 t-1 及以前的信息估计波动(EWMA), 得到无前视的波动标准化收益
ew = np.zeros(T); ew[0] = r[:50].var()
for t in range(1, T): ew[t] = 0.94 * ew[t - 1] + 0.06 * r[t - 1] ** 2
zs = r / np.sqrt(ew)
L = 5 # NARX: 输入 [zs(t-1..t-5), x(t-1..t-5)], 目标 zs(t)
P = np.column_stack([zs[L - i:T - i] for i in range(1, L + 1)] + [x[L - i:T - i] for i in range(1, L + 1)])
Y, idx = zs[L:], np.arange(L, T)
def fit_mlp(Ptr, Ytr, seed):
nv = int(0.85 * len(Ytr)); a, b = np.arange(nv), np.arange(nv + 1, len(Ytr)) # 验证 = 训练窗末尾, 隔 1 天
mu, sd = Ptr[a].mean(0), Ptr[a].std(0)
net = MLPRegressor(hidden_layer_sizes=(8,), activation="tanh", solver="lbfgs", alpha=1.0,
max_iter=5, warm_start=True, random_state=seed)
best, be, wait = None, np.inf, 0
for _ in range(200):
net.fit((Ptr[a] - mu) / sd, Ytr[a])
err = np.mean((net.predict((Ptr[b] - mu) / sd) - Ytr[b]) ** 2)
if err < be: best, be, wait = copy.deepcopy(net), err, 0
else:
wait += 1
if wait >= 10: break
return lambda Q: best.predict((Q - mu) / sd)
# ---------- 扩展窗口 walk-forward: 每 250 天重训, 训练窗与测试窗之间隔 1 天 ----------
pred = {"ridge": np.full(len(Y), np.nan), "mlp": np.full(len(Y), np.nan)}
members = None
for s in range(1500, len(Y), 250):
tr, te = np.arange(0, s - 1), np.arange(s, min(s + 250, len(Y)))
mu, sd = P[tr].mean(0), P[tr].std(0)
lin = Ridge(10.0).fit((P[tr] - mu) / sd, Y[tr])
pred["ridge"][te] = lin.predict((P[te] - mu) / sd)
members = [fit_mlp(P[tr], Y[tr], seed) for seed in range(5)] # 5 网络委员会
pred["mlp"][te] = np.mean([m(P[te]) for m in members], 0)
oos = ~np.isnan(pred["mlp"])
for period, mask in [("前段(信号完整)", oos & (idx < 3500)), ("后段(信号衰减)", idx >= 3500)]:
print(period)
for name, p in pred.items():
e = Y[mask] - p[mask]
r2 = 1 - np.sum(e ** 2) / np.sum((Y[mask] - Y[:1500].mean()) ** 2)
ic = np.corrcoef(p[mask], Y[mask])[0, 1]
pnl = np.clip(p[mask] / 0.15, -1, 1) * r[idx[mask]] # 仓位 = 截断的预测值
sharpe = pnl.mean() / pnl.std() * np.sqrt(252)
lb = acorr_ljungbox(e, lags=[10], return_df=True)["lb_pvalue"].iloc[0]
print(f" {name:<5} 样本外R^2 {r2:+.4f} IC {ic:+.3f} 年化夏普 {sharpe:+.2f} 残差Ljung-Box(10) p={lb:.2f}")
# 残差与外生变量的互相关(式 22.19/27.8 的思想): 线性模型漏掉了 tanh 非线性吗?
for name, p in pred.items():
e = Y[oos] - p[oos]; xx = np.tanh(1.5 * x[idx[oos] - 1])
c = np.corrcoef(e, xx)[0, 1]
print(f"{name:<5} 残差与 tanh(1.5 x_(t-1)) 的相关 {c:+.3f} (95% 界 ±{2/np.sqrt(oos.sum()):.3f})")
# ---------- 多步迭代预测(并联模式): 未来 x 用其 AR(1) 预测代替 ----------
o = np.where(oos)[0][:-12] # 预测起点
H = 10
hist_z = [zs[idx[o] - i] for i in range(L, 0, -1)] # 最近 5 个已知 zs(按时间先后)
hist_x = [x[idx[o] - i] for i in range(L, 0, -1)]
fc = []
for h in range(1, H + 1):
Q = np.column_stack(hist_z[::-1][:L] + hist_x[::-1][:L])
f = np.mean([m(Q) for m in members], 0); fc.append(f)
hist_z.append(f); hist_x.append(0.7 * hist_x[-1]) # 反馈自己的预测; x 的条件期望
print("步长 h: " + " ".join(f"{h:>6d}" for h in (1, 2, 3, 5, 10)))
print("预测值标准差: " + " ".join(f"{fc[h - 1].std():6.3f}" for h in (1, 2, 3, 5, 10)))
print("与实现值的 IC: " + " ".join(f"{np.corrcoef(fc[h - 1], zs[idx[o] + h - 1])[0, 1]:+6.3f}" for h in (1, 2, 3, 5, 10)))
关键输出:
前段(信号完整)
ridge 样本外R^2 +0.0075 IC +0.089 年化夏普 +1.11 残差Ljung-Box(10) p=0.29
mlp 样本外R^2 +0.0041 IC +0.085 年化夏普 +1.03 残差Ljung-Box(10) p=0.29
后段(信号衰减)
ridge 样本外R^2 +0.0022 IC +0.061 年化夏普 +0.83 残差Ljung-Box(10) p=0.16
mlp 样本外R^2 +0.0016 IC +0.059 年化夏普 +0.85 残差Ljung-Box(10) p=0.19
ridge 残差与 tanh(1.5 x_(t-1)) 的相关 +0.003 (95% 界 ±0.034)
mlp 残差与 tanh(1.5 x_(t-1)) 的相关 +0.004 (95% 界 ±0.034)
步长 h: 1 2 3 5 10
预测值标准差: 0.116 0.068 0.042 0.046 0.009
与实现值的 IC: +0.098 +0.064 +0.033 +0.020 +0.002
把这些数字和磁悬浮的结果放在一起看:
- 量级完全不同。 磁悬浮的一步预测误差是 \(10^{-4}\),这里的样本外 \(R^2\) 只有 0.2%–0.75%,IC 约 0.06–0.09。这就是真实收益预测的量级;如果你在真实数据上看到 \(R^2=30\%\),首先要怀疑的是泄漏(第 22 章实验一)。尽管 \(R^2\) 很小,一个截断的线性仓位在模拟中仍有约 1 的年化夏普(未扣交易成本),说明小的 \(R^2\) 在经济上可以有意义。
- 神经网络没有胜过线性基准。 真实的条件均值确实是非线性的(\(\tanh\) 和"大波动后反转"),但在这个信噪比下,这点非线性带来的增益小于网络估计误差的代价:MLP 委员会的 \(R^2\) 和 IC 都略低于 Ridge。残差与 \(\tanh(1.5x_{t-1})\) 的相关在两个模型中都远在界内,说明线性模型并没有漏掉多少可利用的非线性信息。这正是原书"先确认线性方法不够"的意义,在金融里它往往是最终答案。
- 非平稳。 第 3500 天后信号减半,两个模型的 \(R^2\)、IC、夏普都同步下降。扩展窗口仍在用早期较强的关系,会高估后段的信号;实盘中要分段监控,必要时用滚动窗口或给近期样本更大权重。
- 残差检验只是必要条件。 两个模型的 Ljung–Box \(p\) 值都大于 0.1,残差"是白噪声"。但收益本来就接近白噪声,一个什么都不预测的模型也能通过。所以在金融里,残差检验只能用来发现问题(例如 \(p\) 值很小说明还有自相关结构没用上),不能用来证明模型好。
- 多步预测迅速衰减。 迭代预测的标准差从 1 步的 0.116 降到 10 步的 0.009,IC 从 0.098 降到 0.002:几步之后预测就退化为均值。与磁悬浮 600 步仍然准确形成鲜明对比。
金融直觉:为什么真实非线性存在,MLP 却输给 Ridge?这是偏差–方差权衡。\(\tanh(1.5x)\) 在 \(x\) 的常见范围(约 \(\pm1.5\))内大部分接近直线,线性模型的偏差很小;而网络多出来的几十个参数,在 \(R^2\) 不到 1% 的数据上,每个都要用噪声来估计,带来的方差远大于它减少的偏差。类比因子投资:一个简单的单因子打分,样本外常常胜过用大量交互项精细拟合的模型,原因相同。
27.7.7 一份检查清单
看到一个"用神经网络预测收益"的结果时,依次问:
- 目标是收益还是价格?是否用了重叠标签?
- 每个输入在决策时刻是否已经可得?归一化、波动估计、缺失值填补是否只用过去信息?
- 训练/验证/测试是否按时间划分,并有 purge/embargo?
- 是否与线性基准(ARX/Ridge)在同样的 walk-forward 下比较?
- 是否报告了样本外 \(R^2\)、IC,以及扣成本后的策略表现?是否分时段报告?
- 是否用多个随机种子或委员会?结果对种子敏感吗?
- 做多步预测时,是在并联(迭代)模式还是直接模式下评估的?
- 测试期的输入是否落在训练期的分布范围内(新颖性检测)?
这份清单把第 22 章的训练后分析和本章的预测检验合在一起,也是第 11 册综合实战中所有预测模型都要过的一关。
本章小结
预测与系统辨识用 NARX 网络:\(y(t)\) 对自身和外生输入的若干滞后值做非线性回归,用 tansig 隐层 + 线性输出的前馈网络逼近。数据要用宽度和幅度都随机的 skyline 激励覆盖暂态和稳态;时间序列的测试集取末尾连续一段;延迟阶数先按系统的物理阶数设定。训练时用串并联形式(用真实的过去输出作输入),可以用静态反向传播,贝叶斯正则化给出有效参数数。验证时检查误差自相关是否落在 \(\pm2R_e(0)/\sqrt Q\) 内、误差与输入的互相关是否落在 \(\pm2\sqrt{R_e(0)R_u(0)}/\sqrt Q\) 内,有相关就加长延迟;最后改回并联形式做多步迭代预测,这一步可能暴露一步误差看不出的差异,多初值委员会能明显改善。搬到金融收益预测时:预测收益而非价格,用无前视的波动标准化,按时间 walk-forward 并留间隔,先建线性基准,用样本外 \(R^2\)、IC、扣成本的策略表现和分段结果评估;残差白噪声只是必要条件;多步预测会迅速退化为均值。
| 概念 | 公式 / 要点 |
|---|---|
| NARX | \(y(t)=f(y(t-1..n_y),u(t-1..n_u))\);\(f\) 线性时为 ARX |
| 串并联输入 | \(\mathbf p(t)=[u(t-1),u(t-2),y(t-1),y(t-2)]^T\),目标 \(y(t)\) |
| 并联形式 | 反馈 \(\hat y\),用于使用和多步预测 |
| skyline 激励 | 随机幅度、随机宽度脉冲,兼顾暂态与稳态 |
| 预测误差 | \(e(t)=y(t)-\hat y(t)\),应白且与输入无关 |
| 自相关界 | \(\vert R_e(\tau)\vert <2R_e(0)/\sqrt Q\) |
| 互相关界 | \(\vert R_{ue}(\tau)\vert <2\sqrt{R_e(0)R_u(0)}/\sqrt Q\) |
| 有效参数 | 4-10-1 网络 61 个参数,有效 39 个 |
| 无前视波动标准化 | \(\hat\sigma^2_t=\lambda\hat\sigma^2_{t-1}+(1-\lambda)r^2_{t-1}\),\(z_t=r_t/\hat\sigma_t\) |
| 样本外 \(R^2\) | \(1-\sum(y-\hat y)^2/\sum(y-\bar y_{train})^2\) |
练习
基础
- 式 (27.1) 中,电流恒为 \(i>0\) 时,磁铁的平衡位置是多少?取 \(i=2\) A 计算。 答案:令加速度和速度为零,\(g=\alpha i^2/(My)\),\(y=\alpha i^2/(Mg)=15\times4/(3\times9.8)\approx2.04\)。
- 4-10-1 网络有多少个参数?若贝叶斯正则化给出有效参数 58,你会怎么做? 答案:61;有效参数接近总数,说明网络可能不够大,应增加隐层神经元重训。
- 为什么串并联形式可以用静态反向传播训练,而并联形式不行? 提示:串并联形式中反馈的是已知的目标值,网络是纯前馈的;并联形式中输入依赖于网络自己过去的输出,梯度要穿过时间(第 14 章的动态反向传播)。
- 某预测模型在 \(Q=1000\) 的样本上 \(R_e(0)=4\),\(R_e(1)=0.5\)。是否通过白噪声检验?这提示要怎么改模型? 答案:界为 \(2\times4/\sqrt{1000}=0.253\),0.5 超界;一阶误差正相关,应加长延迟线(或加入误差的移动平均项)。
- 为什么"明天价格 = 今天价格"在价格散点图上表现极好,却毫无价值?应当怎样评估? 提示:价格高度持续,散点图和 \(R^2\) 由持续性主导;应评估收益的预测,用样本外 \(R^2\)、IC 等。
进阶
- 修改 27.6 节的代码,把 \(n_u=n_y\) 增到 6,并把隐层增到 20,看自相关超界数和 600 步并联预测误差如何变化。一步误差的改进是否总能带来多步误差的改进?
- 在 27.6 节代码中,把电流范围改为 \([0.5,4]\)(磁铁不会撞到电磁铁),重做 \(n=2\) 与 \(n=4\) 的检验,与原结果比较,验证"接触边界造成残差自相关"的解释。
- 在 27.7.6 节代码中,把条件均值的非线性加强(例如把 \(0.12\tanh(1.5x)\) 换成 \(0.25\,\mathrm{sgn}(x)\,\mathbf 1\{|x|>1\}\)),看 MLP 是否开始胜过 Ridge,并检查 Ridge 残差与该非线性项的相关是否超界。
- 把 27.7.6 节的扩展窗口改为 1000 天的滚动窗口,比较前段与后段的样本外表现。滚动窗口在信号衰减后是更好还是更差?为什么?
- 为 27.7.6 节实现"直接多步预测":为 \(h=5\) 训练一个预测未来 5 日累计标准化收益的模型(注意 purge),与迭代预测比较 IC。
原书推荐习题:第 27 章为案例章,无习题。建议用原书数据 maglev_u.txt/maglev_y.txt 复现 \(n_y=n_u=2\) 与 4 的残差自相关对比,以及串并联训练后改用并联形式的多步迭代预测;再在一个真实的金融收益序列上做同样的残差检验,比较两类数据的可预测性。
原书对照
| 本章小节 | 原书章节 | PDF 页码 |
|---|---|---|
| 27.1 问题 | 27 Objectives;Description of the Magnetic Levitation System(式 27.1) | p.965–967 |
| 27.2 数据 | Data Collection and Preprocessing(skyline 输入,图 27.2–27.3) | p.967–968 |
| 27.3 结构 | Selecting the Architecture(式 27.2–27.4,图 27.4–27.5) | p.968–970 |
| 27.4 训练 | Training the Network(图 27.6–27.7) | p.971–972 |
| 27.5 验证 | Validation(式 27.5–27.9,图 27.8–27.14) | p.972–977 |
| — | Epilogue、Further Reading | p.978–979 |
| 27.6、27.7 | 本册补充的复现与量化实战 | — |
原书附录(PDF p.980–1012)简要说明。
- 附录 A 参考文献(p.980–990):全书文献总表,按作者–年份代码排序,每条注明被引用的章节。注意 [Mill93] 与 [Moll93] 实为同一篇标度共轭梯度论文(作者 M. F. Møller),书中出现两种拼写。
- 附录 B 记号(p.991–998):标量小写斜体、向量小写粗体、矩阵大写粗体;\(w^k_{i,j}\) 为第 \(k\) 层第 \(i\) 行第 \(j\) 列权值,\(\mathbf w_j\) 为列、\({}_i\mathbf w\) 为行;\(M\) 层数、\(S^k\) 第 \(k\) 层神经元数、\(Q\) 样本数、\(R\) 输入维数;动态网络的 \(\mathbf{IW}^{m,l}(d)\)、\(\mathbf{LW}^{m,l}(d)\);ART 与 Hopfield 的专用记号等。读原书公式时可随时查阅。
- 附录 C 软件(p.999–1003):演示程序需 MATLAB,在 MATLAB 中输入
nnd打开主菜单,help nndesign列出全部演示。第 19–21 章正文中引用的演示名沿用第一版编号(nnd16al1、nnd17ds、nnd18hn 等),附录 C 中第二版编号为 nnd19al1、nnd20ds、nnd21hn 等,以附录为准。案例数据文件随演示软件提供。 - 索引与封底(p.1004–1012)。