周五下午两点,你在上海某私募的因子研究组里收到一张 12,000 × 600 的设计矩阵——600 个候选 alpha 因子在沪深300 成分股上 18 个月日频的横截面暴露。组合经理希望你下班前给一组系数,明早接入回测。你写下普通最小二乘(ordinary least squares, OLS)的闭式解 beta = np.linalg.solve(X.T @ X, X.T @ y),按下回车——进程吃掉 40GB 内存后被 kill。X⊤X 是 600 × 600,但其条件数(condition number)轻松突破 108,直接求逆既不稳定又烧内存。你需要一个不依赖矩阵求逆、按梯度一步步逼近的迭代解法(iterative method)。
最陡下降方向
设目标 f:Rn→R 可微。在点 xk 处沿单位向量 d 的方向导数(directional derivative)为 ∇f(xk)⊤d,柯西-施瓦茨不等式给出
∇f(xk)⊤d≥−∥∇f(xk)∥⋅∥d∥,
等号在 d=−∇f(xk)/∥∇f(xk)∥ 时取到。也就是说,负梯度方向是当前点局部下降最快的方向——这就是「最陡下降」(steepest descent)的来源。配上一个步长 tk>0,便得到梯度下降的标准更新规则:
xk+1=xk−tk∇f(xk).
三种步长
固定步长(fixed step)、精确线搜索(exact line search)、回溯线搜索(backtracking line search)是三种典型选择,对应三种「肯花多少代价换收敛保证」的权衡。
- 固定步长 tk=t:当梯度满足 L-Lipschitz 条件 ∥∇f(x)−∇f(y)∥≤L∥x−y∥ 时,取 t≤1/L 可保证每步单调下降。代价是你得先估出 L,估高了收敛慢,估低了直接发散。
- 精确线搜索 tk=argmintf(xk−t∇f(xk)):只有当 f 是二次型才能写出闭式解,一般非线性问题里没人用。
- 回溯线搜索(Armijo 充分下降条件):先取一个较大的试探步长 t,若不满足 Armijo 条件就把 t 减半,直到满足为止。Armijo 条件写作
f(xk+tdk)≤f(xk)+αt∇f(xk)⊤dk,
其中 dk=−∇f(xk),α∈(0,1) 是「实际下降占一阶预测下降的最低比例」,工程上常取 α=0.25。它要求你真正走出去的下降量至少有一阶模型预测量的 α 倍——这是把「迈一步」和「迈一大步」分开的常用闸门。
当 f 是二次型,沿搜索方向的一维限制 ϕ(t)=f(xk−t∇f(xk)) 退化成开口向上的抛物线,精确线搜索就是该抛物线的解析极小点。下方滑块演示其形状——调节曲率 a 与斜率 b 即可读出极小位置:
Formula Explorer
0.5 * a * t^2 - b * t
收敛速率与条件数
记 f∗=minxf(x),κ=L/μ 为该问题的条件数,其中 μ 是 f 的强凸常数(strong-convexity constant)。两类标准结论:
- 凸 + L-Lipschitz 梯度(不强凸):固定步长 t=1/L 给出次线性收敛 f(xk)−f∗≤∥x0−x∗∥2/(2tk)=O(1/k)。把误差砍到 10−3 需要约 103/ϵ0 步。
- μ-强凸 + L-Lipschitz 梯度:精确线搜索给出线性收敛
f(xk)−f∗≤(κ+1κ−1)2k(f(x0)−f∗).
κ 越接近 1,每步几乎砍掉一个数量级;κ 越大,速率 ((κ−1)/(κ+1))2 越逼近 1,相当于线性收敛但每步只能蹭走 O(1/κ) 比例的误差。
这一点对量化场景至关重要:500 只股票样本协方差矩阵(covariance matrix)在数据稀疏或共线性强时 κ 轻松突破 104,在它上面做均值方差优化(mean-variance optimization, MVO)或最小方差组合求解时,梯度下降所需的步数被放大成千倍。条件数不是抽象的数值分析指标,它就是你今晚能不能算完的实际指标。
病态二次型:zig-zag 的几何
取 f(x)=21x⊤Ax,A=diag(1,κ)。等高线是长短轴比为 κ 的椭圆。
- κ=1:A=I,等高线为圆,精确线搜索一步即到原点。
- κ=10,初值 x0=(10, 1),精确线搜索:
| k | xk | f(xk) | f(xk)/f(xk−1) |
|---|
| 0 | (10.00, 1.00) | 55.00 | — |
| 1 | (8.18, −0.82) | 36.82 | 0.669 |
| 2 | (6.70, 0.67) | 24.65 | 0.670 |
| 3 | (5.48, −0.55) | 16.51 | 0.670 |
| 4 | (4.48, 0.45) | 11.06 | 0.670 |
理论速率 ((κ−1)/(κ+1))2=(9/11)2≈0.669,与表中观测的下降比例完全吻合。注意第二坐标每步都翻转符号——这就是教科书上常画的「之字形」(zig-zag)轨迹:椭圆等高线把负梯度方向「掰歪」了,负梯度指向的不是椭圆的中心而是其本地圆切线,每一步都要在长轴方向上反复矫正。
把 κ 拉到 100(合约要求 κ≈1 vs κ≈100 直接对照),取 x0=(100,1)、t=2/(κ+1)=2/101,沿用上一节最优固定步:
| k | κ=1: f(xk) | κ=100: f(xk) |
|---|
| 0 | 1.000 | 5050.000 |
| 1 | 0.000 | 4851.980 |
| 2 | 0.000 | 4661.725 |
| 5 | 0.000 | 4134.563 |
| 50 | 0.000 | 683.398 |
| 200 | 0.000 | 1.694 |
速率退化为 (99/101)2≈0.961,把 f 砍到 10−3f0 需要约 log(10−3)/log(0.961)≈174 步;把 κ 拉到 104,所需步数飙到约 1.7×104。这就是一阶梯度法在 κ 大时失效的真正原因——它只看「往哪个方向下降最快」,看不见「等高线被压扁了多少」。
一阶法的真实战场
在量化实践里,梯度下降不是替代闭式解的「玩具」,而是闭式解不可用时的唯一选择:
- 神经网络因子模型:把 50ETF / 300ETF 的高频量价特征喂进一个三层 MLP 预测下一分钟收益,损失对参数高度非线性,根本没有闭式解。
- 隐含波动率(implied volatility, IV)曲面校准:把 SABR 或 SVI 五参数模型同时拟合到 30 个行权价和 5 个到期日上的市价,最小化加权平方误差——一阶法(带回溯)是 Black-Scholes 反演的工业标配。
- 大规模均值方差优化:当组合维度 n 上千时,O(n3) 的协方差矩阵直接求逆已经不实用,按一阶法迭代逼近最优组合权重往往是唯一可行的路线。
练习
Exercise
考虑 f(x1,x2)=x12+4x22,初值 x0=(2, 1)⊤。
- 用试探步长 t=0.1 算出一次梯度下降。
- 用 Armijo 规则(α=0.25)判断是接受该步还是把步长减半。
提示
梯度
∇f(x)=(2x1, 8x2)⊤,在
x0 处
∇f(x0)=(4, 8)⊤,所以
x1=x0−t∇f(x0)=(1.6, 0.2)。
提示
代入 Armijo,
d0=−∇f(x0):右端
8+0.25⋅0.1⋅(−80)=6.0,
f(x1)=2.72,不等式成立——接受该步,无需减半。
课末过渡
到这里你已经能用 −∇f 决定走向、用 Armijo 决定走多远、用 κ=L/μ 预判要走多少步。但 zig-zag 暴露了一阶方法的天花板——它对各向异性的等高线无能为力。下一课要把二阶曲率信息加进来:牛顿方向 dk=−[∇2f(xk)]−1∇f(xk) 相当于在每一步本地把空间拉直,让椭圆变回圆,zig-zag 消失。代价是每步要解一个 n×n 的线性系统——这是「每步代价」换「总步数」的另一笔交易。