为什么 MVO 权重不稳定(以及应对办法)
Michaud (1989) 称均值-方差优化为"误差放大器"。本文给出数学解释,并介绍收缩、重采样和稳健优化三种应对手段。
Markowitz 1952 年的论文给出一个优美、简洁的二次规划。求解它,就能得到有效前沿。闭式解、两基金分离、诺奖级的数学。
只是有一个问题:实际上它跑不通。
1989 年,Richard Michaud 在《Financial Analysts Journal》发文指出,按通常方式实现的均值-方差优化是”误差放大器”而非”均值-方差优化器”。他并没有玩文字游戏。他的意思是:优化器对输入估计误差的放大程度,超过了对输出中真实均值-方差结构的捕捉。
本文用数学讲清楚为什么。然后介绍三族修复方法:收缩、重采样和稳健优化。
输入是骗人的
Markowitz 的 QP 接受两个输入: 和 。两者都需要从数据中估计。在标准设置下,你取历史收益、计算样本均值和样本协方差,再喂给优化器。
问题就出在这里。
资产收益的样本均值极其有噪声。如果你用 60 个月度收益(5 年)来估计单只股票的预期收益,估计的标准误就是收益标准差除以 。对一只月波动率 6% 的典型股票,结果是 每月,年化约 9%。对 10% 的预期收益估计,信噪比约为 1。你在猜。
协方差矩阵相对更稳定,但也有自己的问题。对 个资产、 个观测,你需要估计 个自由参数。对 、,参数多达 1,275 个,数据点却只有 3,000 个。当 较小时,样本协方差矩阵众所周知地不稳定。其特征值在尾部方向上偏大、在领头方向上偏小(这就是 Marčenko-Pastur 定律)。
然后你把这些含噪声的估计喂给优化器,它要计算 的逆并求解 。 放大了小特征值上的估计误差。与 相乘又叠加上噪声。得到的 与”真实”最优权重差异巨大,更糟的是这些权重高度集中且不稳定。
问题的数学
我们把话说得更精确一些。假设真实输入为 ,但你估计出 。优化器返回 。真实输入下的最优组合是 。
Kan & Zhou (2007) 给出的一个经典结果延续了 Frost & Savarino (1986) 等人的早期工作,把估计误差引起的期望损失分解为四项:
具体而言,对 GMV 组合,期望平方跟踪误差为:
位于前面的 就是把协方差估计的误差”接住”的部分。如果 的特征值很小(风险集中), 会爆炸。如果 是用太少数据估计的, 会很大。两者相乘。这就是”误差放大器”效应。
对切线组合更糟,因为你还要承受 的噪声:
所以,你对收益估计越自信,优化器就会把你犯下的任何错误放大得越厉害。最优 Markowitz 组合恰恰是你能从金融数据中构造出来的最不稳定的对象。
Michaud 真正说了什么
下面这段是 Michaud (1989) 的核心论点:
“用样本估计的均值-方差优化,有望产生一个’优化’组合,它在样本外表现上以高概率劣于等权组合。”
1989 年这是一句极具争议的话。它的隐含之意是:一个复杂的优化器在样本外 Sharpe 上可能输给 1/N 这种朴素启发式。二十年后,DeMiguel, Garlappi & Uppal (2009) 在 7 个数据集上对比 1/N 与 14 个优化组合,恰好证实了这一点。优化组合在样本外长期跑输 1/N。
本文并非要批驳 Markowitz。Markowitz 的理论没有问题。问题在于,他的理论假设你已知 。实际中你并不知道,而优化器对这些输入的敏感性是残酷的。
修复一:收缩
最简单、最稳健的修复是:不要直接用样本估计,而是把它们向某个结构化目标做收缩。
Ledoit & Wolf (2004) 给出了协方差矩阵的闭式收缩估计:
其中 是”结构化目标”,通常取单位阵的倍数 , 是收缩强度,通过解析方式选择以最小化期望平方误差:
用文字描述:把样本协方差向”平均方差乘以单位阵”做收缩,强度选择要使收缩后估计的均方误差低于样本估计。
Ledoit-Wolf 收缩是”旋转不变”的,也就是说它不关心资产的方位。在”协方差应接近 “的先验下,结合高斯假设,它也是最大似然估计。
更灵活的一个版本是”近似 oracle 收缩”(OAS),它使用了不同的目标,在高维场景下通常表现更好。
对 ,可以向横截面均值 收缩、向零收缩,或向均衡先验收缩(这正是 Black-Litterman 的做法,见下一篇文章)。
收缩的效果:把权重拉向等权或拉向结构化目标。从数学上保证降低样本外权重的方差,代价是引入一些样本内偏差。实践中几乎总是净赚的。
修复二:重采样
Michaud 自己的方案是重采样(后来在 Michaud & Michaud, 1998 中正式成型,并由 López de Prado 的 Advances in Financial Machine Learning(2018,第 16 章)落地为可操作流程)。
步骤如下:
- 从历史收益中生成 个 bootstrap 样本。
- 对每个 bootstrap 样本,估计 并计算最优组合 。
- 平均权重:。
直觉:bootstrap 样本是对同一潜在分布的有噪声估计,它们的最优解围绕真实最优分散开。取平均就能得到中心位置的更稳定估计,同时也抹平了来自任一 bootstrap 样本的极端权重分配。
数学上的可行性来自:每个 具有相同的期望值(真实最优),bootstrap 过程提供了来自优化器抽样分布的(近似)独立抽样。在中心极限定理下,平均权重的方差以 缩放。
代码层面,核心循环很短:
import numpy as np
from scipy.optimize import minimize
def resampled_weights(returns, target_return, n_bootstrap=200):
n_obs, n_assets = returns.shape
weights = np.zeros((n_bootstrap, n_assets))
for b in range(n_bootstrap):
# Bootstrap resample with replacement
idx = np.random.choice(n_obs, size=n_obs, replace=True)
boot = returns[idx]
mu_b = boot.mean(axis=0)
Sigma_b = np.cov(boot.T)
# Solve MVO on this bootstrap sample
weights[b] = solve_mvo(mu_b, Sigma_b, target_return)
# Average the optimal weights
return weights.mean(axis=0)
López de Prado 在 mlfinlab 中的实现给这套流程加了额外的安全检查。他还指出了一个重要的细节:如果在第 2 步中配合使用收缩或稳健输入,可以叠加各种改进。重采样可以和所有其他方法叠加。
代价:重采样很慢。每轮迭代都是一个 QP 求解。对 、,相当于求解 200 个二次规划。在现代机器上配合 cvxpy 或 quadprog 是几秒钟的事,而在 1990 年代的彭博终端上则不可行,这也是 Michaud 的思想花了 30 年才被采纳的部分原因。
修复三:稳健优化
第三族修复把输入视为不确定的,并针对最坏情况进行优化。Goldfarb & Iyengar (2003) 是经典文献。本模块后面会单独写一篇文章。
核心思路:不求解
而求解
其中 是围绕 的不确定集。 的常见选择:
- 盒式不确定:每个 独立地在 内变化。
- 椭球不确定:, 为某椭球。
稳健对偶问题仍是凸规划(事实上常常仍是 QP 或 SOCP)。它给出的权重能保证在不确定集中的任意输入下都接近最优。代价是权重通常比名义最优更保守。
Tütüncü & Koenig (2004) 证明:椭球不确定下的稳健 MVO 等价于对协方差矩阵”加稳健化”后的 MVO:
即加上单位阵的倍数。这本质上就是换了件外衣的 Ledoit-Wolf 收缩,只不过推导来自 max-min 论证而非 min-MSE 论证。
实践中的选择
实践建议:
- 样本 MVO:永远不要在生产环境中使用。仅供学习。
- 对 做收缩(Ledoit-Wolf):便宜、理论扎实,几乎总能改善样本外表现。用它。
- 对 做收缩:也不错,但目标选择更重要。Black-Litterman 提供了一个有原则的目标。
- 重采样:效果好,但计算代价不小。López de Prado 推荐它在回测中作为默认方法。
- 稳健 MVO:当你对输入不确定度有强先验时很有用。在纯多头股票组合中较少部署。
- 约束:这是隐形的杀手。加上 、 以及行业/资产上限,能在不使用上述任何工具的情况下大幅稳定权重。
合理的生产配置:对 做 Ledoit-Wolf 收缩,对 用 Black-Litterman 先验(下一篇文章),重采样得到最终权重,并配合不允许做空和集中度约束。这是一个站得住脚的机构级配置。
文献综述
- Michaud (1989). “The Markowitz Optimization Enigma: Is ‘Optimized’ Optimal?” Financial Analysts Journal 45(1): 31-42. “误差放大器”的批评。
- Michaud & Michaud (1998). Efficient Asset Management. Harvard Business School Press. 重采样方案。
- Ledoit & Wolf (2004). “A Well-Conditioned Estimator for Large-Dimensional Covariance Matrices.” Journal of Multivariate Analysis 88(2): 365-411. 收缩估计量。
- Ledoit & Wolf (2003). “Improved Estimation of the Covariance Matrix of Stock Returns with an Application to Portfolio Selection.” Journal of Empirical Finance 10(5): 603-621.
- Frost & Savarino (1986). “An Empirical Bayes Approach to Efficient Portfolio Selection.” Journal of Financial and Quantitative Analysis 21(3): 293-305.
- Kan & Zhou (2007). “Optimal Portfolio Selection with Risk-Constraint.” Quantitative Finance 7(2): 165-185. 偏差-方差分解。
- DeMiguel, Garlappi & Uppal (2009). “Optimal Versus Naive Diversification: How Inefficient is the 1/N Portfolio Strategy?” Review of Financial Studies 22(5): 1915-1953. 1/N 跑赢优化组合的结果。
- Goldfarb & Iyengar (2003). “Robust Portfolio Selection Problems.” Mathematics of Operations Research 28(1): 1-21. 稳健 MVO 基础。
- López de Prado (2018). Advances in Financial Machine Learning. Wiley. 第 16 章详细讨论重采样。ISBN: 978-1-119-48208-6.
- Tütüncü & Koenig (2004). “Robust Asset Allocation.” Annals of Operations Research 132(1-4): 157-187. 稳健 MVO 的等价性。
仿真研究
“误差放大器”效应在仿真中最为直观。下面是一个完整实验:
- 从已知真实分布(例如,均值为 、协方差为 的多元正态)生成 个资产、 个月的收益。
- 计算样本估计 。
- 求解 MVO。计算差距 。
- 重复 1000 次。绘制差距的直方图。
对 、,差距常常超过 本身。也就是说,估计出的最优点平均而言比等权组合离真实最优还要更远。这就是”误差放大器”效应在起作用。
import numpy as np
from scipy.optimize import minimize
def simulate_mvo_error(N=50, T=60, n_trials=1000):
# True parameters
mu_0 = np.random.uniform(0.05, 0.15, N) / 12 # Monthly
A = np.random.randn(N, N) * 0.02
Sigma_0 = A @ A.T + np.eye(N) * 0.001 # PSD
# True optimum (long-only for realism)
def neg_sharpe_unconstrained(w):
return -(w @ mu_0) / np.sqrt(w @ Sigma_0 @ w)
# Run trials
gaps_naive = []
for _ in range(n_trials):
# Generate sample
returns = np.random.multivariate_normal(mu_0, Sigma_0, T)
mu_hat = returns.mean(axis=0)
Sigma_hat = np.cov(returns.T)
# Solve MVO with sample estimates
w_naive = np.linalg.solve(Sigma_hat, mu_hat)
w_naive = w_naive / w_naive.sum() # Normalize
# True optimum (unconstrained, then normalized)
w_true = np.linalg.solve(Sigma_0, mu_0)
w_true = w_true / w_true.sum()
gaps_naive.append(np.linalg.norm(w_naive - w_true))
return np.mean(gaps_naive), np.std(gaps_naive)
mean_gap, std_gap = simulate_mvo_error()
print(f"Mean gap: {mean_gap:.4f}, Std: {std_gap:.4f}")
对典型参数,平均差距在 1.5-3.0 之间(归一化权重空间)。等权组合的差距约为 0.5-1.0。所以使用样本估计的 MVO 平均而言比等权还差。这不是偶然,而是结构性特征。
贝叶斯替代方案
一种更有原则的处理估计误差的方法是:对 做贝叶斯推断。
模型:
带有先验超参数 。
后验:
后验均值就是一种收缩估计量,它把样本均值 向先验均值 收缩,强度取决于相对精度。
贝叶斯最优组合为:
即把后验均值代回标准的 MVO。
这套思路在数学上很干净。它推广了 Black-Litterman(后者本身就是一个贝叶斯模型,其中 取均衡收益)。它也推广了 James-Stein 收缩(即 时这一框架的经验贝叶斯版本)。
层次贝叶斯
对多层估计问题(例如,行业组合嵌套股票组合),层次贝叶斯给出部分池化。思路是:
估计股票层面的均值需要数据,但向行业层均值部分池化能减少估计误差。这正是因子模型底层的结构。
对时变预期收益 还可以引入布朗运动先验。模型为:
并有 。Kalman 滤波器给出最优的 ,它就是一个时变收缩估计量。
这是应对”时变 alpha 主动管理”的正确框架。Black-Litterman 模型可以扩展来处理这种情况(Meucci, 2008)。
交叉验证用于超参数选择
上述大多数方法都有超参数:收缩强度 、观点协方差 、稳健不确定集大小。标准做法是通过交叉验证来选择它们。
步骤:
- 将历史数据切分为 折(按时间序列感知的方式,而非随机)。
- 对每一折,在训练部分拟合超参数。
- 在留出部分上评估样本外表现。
- 选取平均留出表现最好的超参数。
López de Prado 提出的”组合式净化交叉验证”(CPCV)是金融时间序列上的严格版本。它考虑了序列自相关和多重检验问题。
实践中,多数机构是通过回测(而非交叉验证)来选超参数。回测更易解读,也与策略评估方式一致。代价是过拟合:如果你测试 100 组超参数,必然挑到一组”恰好在过去有效”的。
诚实的做法:把数据切分为训练、验证、测试三段。在验证段上调参。最终只在测试段评估一次,且只评估一次。把测试段当成只能考一次的期末考试。
为什么这篇文章重要
只要你打算运行任何 MVO 变体,就必须理解估计误差问题。数学不可省。仿真结果不可省。修复方法不可省。
本模块接下来的 11 篇文章在某种意义上都是对本文的回应。我们要讨论的每种方法(Black-Litterman、风险平价、HRP、CVaR、稳健 MVO)都是在应对 未知这一事实。
要点回顾
Markowitz 优化在数学上优美、在实践上不稳定。不稳定性来源于 和 的估计误差,被优化器对这些估计的敏感性进一步放大。
“误差放大器”效应是 MVO 的结构性特征,而非 bug。仿真显示,使用样本估计的 MVO 在平均误差上高于等权。这正是 Michaud 在 1989 年抱怨的事。
存在三族修复方法:收缩(对输入做正则化)、重采样(平均掉优化器的不稳定性)、稳健优化(针对最坏情形优化)。贝叶斯推断是第四种思路,它把前三者统一起来。这四种都有效。
最站得住脚的生产配置是把它们和合理的约束组合起来:对 做 Ledoit-Wolf,对 做 Black-Litterman,用重采样得到最终权重,全程不允许做空。
下一篇文章:Black-Litterman,让 MVO 的贝叶斯升级,把 估计从缺陷变成特性。