Skip to content

模型评估与过拟合防范

概述

在金融机器学习中,模型评估 (Model Evaluation) 面临独特挑战:时间序列的自相关性 (Autocorrelation) 使传统交叉验证失效,低信噪比 (Low SNR) 极易导致过拟合 (Overfitting),而各类回测偏差 (Backtesting Bias) 则可能制造虚假的优异表现。本文系统梳理金融场景下的模型评估方法与过拟合防范策略。

时间序列交叉验证

为什么不能随机切分?

传统 K-Fold 交叉验证假设样本独立同分布 (i.i.d.),但金融时间序列具有时序依赖性。随机切分会导致未来数据泄漏到训练集中,产生过于乐观的评估结果。

滚动窗口法 (Walk-Forward Validation)

\[\text{Train}_k = [t_0, t_k), \quad \text{Test}_k = [t_k, t_{k+1})\]
from sklearn.model_selection import TimeSeriesSplit

def walk_forward_cv(X, y, model, n_splits=5):
    """时间序列滚动交叉验证"""
    tscv = TimeSeriesSplit(n_splits=n_splits)
    scores = []
    for train_idx, test_idx in tscv.split(X):
        X_train, X_test = X[train_idx], X[test_idx]
        y_train, y_test = y[train_idx], y[test_idx]
        model.fit(X_train, y_train)
        y_pred = model.predict(X_test)
        ic = spearmanr(y_pred, y_test)[0]
        scores.append(ic)
    return scores

带间隔的滚动验证 (Purged Cross-Validation)

为消除训练集与测试集之间的信息泄漏,引入清洗间隔 (Purging Gap):

\[\text{Train}_k = [t_0, t_k - \Delta), \quad \text{Gap} = [t_k - \Delta, t_k), \quad \text{Test}_k = [t_k, t_{k+1})\]

其中 \(\Delta\) 为清洗窗口长度,通常设为标签构建的前瞻期 (Horizon)。

Embargo 机制

Lopez de Prado (2018) 提出的 Purged K-Fold CV 在清洗的基础上增加 Embargo 期,进一步隔离训练集与测试集之间因标签重叠导致的信息泄漏。这在使用重叠标签(如 5 日收益率)时尤为关键。

信息系数 (Information Coefficient, IC)

IC 是量化投资中最常用的因子评估指标,定义为因子值与未来收益率的秩相关系数 (Rank Correlation):

\[\text{IC}_t = \text{Spearman}(\hat{r}_{t}, r_{t+1})\]

衍生指标包括:

  • IC 均值 (IC Mean):\(\overline{\text{IC}} = \frac{1}{T}\sum_{t=1}^T \text{IC}_t\)
  • IC 标准差 (IC Std):衡量 IC 的波动性
  • ICIR (IC Information Ratio):\(\text{ICIR} = \frac{\overline{\text{IC}}}{\text{Std}(\text{IC})}\)
\[\text{ICIR} > 0.5 \text{ 通常认为是优秀因子}\]
def evaluate_factor(factor_values, future_returns):
    """计算因子的IC系列与ICIR"""
    ic_series = factor_values.corrwith(
        future_returns, method='spearman', axis=1
    )
    ic_mean = ic_series.mean()
    ic_std = ic_series.std()
    icir = ic_mean / ic_std
    ic_positive_ratio = (ic_series > 0).mean()
    return {
        'IC_mean': ic_mean,
        'IC_std': ic_std,
        'ICIR': icir,
        'IC_positive_ratio': ic_positive_ratio
    }

回测偏差 (Backtesting Bias)

前视偏差 (Look-Ahead Bias)

使用了在决策时刻尚不可得的信息。常见来源:

  • 使用报告期末日而非公告日对齐财务数据
  • 使用当期因子值预测当期收益(而非下期)
  • 因子标准化使用了全样本统计量

前视偏差是最致命的错误

即使微小的前视偏差也可能使策略从无效变为"高效"。检验方法:将所有特征延迟一期,观察性能变化。如果性能骤降,很可能存在前视偏差。

存活偏差 (Survivorship Bias)

仅使用当前仍然存续的标的进行回测,忽略了退市、破产的标的。这会系统性高估策略收益。

过度拟合偏差 (Overfitting Bias)

通过反复试验大量策略参数组合,选择表现最好的结果呈现。设在 \(N\) 个独立策略中选择最优,则期望的虚假夏普比率 (Sharpe Ratio) 为:

\[\mathbb{E}[\max_{n=1}^N \text{SR}_n] \approx \sqrt{2 \ln N} \cdot \sigma_{\text{SR}}\]

这意味着尝试的策略越多,找到虚假高夏普策略的概率越大。

数据窥探偏差 (Data Snooping Bias)

反复在同一数据集上测试假设,导致显著性检验失效。校正方法包括 Bonferroni 校正和 FDR 控制:

\[p_{\text{adjusted}} = \min(p \times N_{\text{tests}}, 1)\]

过拟合防范策略

1. 模型复杂度控制

通过正则化限制模型容量 (Model Capacity),偏差-方差权衡 (Bias-Variance Tradeoff) 中倾向于简单模型:

\[\text{Total Error} = \text{Bias}^2 + \text{Variance} + \text{Irreducible Noise}\]

2. 样本外严格验证

将数据划分为 Train / Validation / Test 三段。Test 集仅在最终评估时使用一次。

# 严格的三段式划分
train_end = '2018-12-31'
val_end = '2020-12-31'

train_data = data[data.index <= train_end]
val_data = data[(data.index > train_end) & (data.index <= val_end)]
test_data = data[data.index > val_end]  # 仅最终使用一次

3. 多数据集验证

在不同市场(A 股、美股、港股)或不同时间段验证策略的稳健性 (Robustness)。

4. 经济逻辑检验

因子应具备合理的经济解释。纯粹由数据驱动的信号更可能是过拟合的产物。

Bailey-Lopez de Prado 的最低回测长度

给定策略的夏普比率 \(\hat{\text{SR}}\) 和回测中的试验次数 \(N\),最低回测长度 (Minimum Backtest Length, MinBTL) 为:

\[\text{MinBTL} \approx \frac{2 \ln N}{\hat{\text{SR}}^2}\]

这提供了判断回测结果是否具有统计显著性的定量标准。

小结

金融模型评估的核心原则是:对模型表现持怀疑态度。时间序列交叉验证、IC/ICIR 分析、偏差识别与校正构成了完整的评估框架。避免过拟合不仅需要技术手段,更需要研究者的纪律性——抵制"数据折磨" (Data Torture) 的诱惑。