3、标签生成基础:基于未来信息的标签生成、避免未来函数、标签与特征的时序对齐
在事件驱动回测中,标签(Label)是监督学习的目标变量,通常代表未来一段时间的收益、波动或事件是否发生。标签生成的核心矛盾在于:必须使用未来信息来定义“正确答案”,但又不能在未来信息尚未发生时将其泄露给当前时刻的特征。本章围绕这一矛盾,系统讲解标签生成的基础原则、未来函数的识别与规避方法,以及标签与特征之间的严格时序对齐技术。
3.1 标签生成的基本逻辑
标签的本质是对未来状态的量化描述。常见的标签类型包括:
| 标签类型 | 定义方式 | 典型应用 |
|---|---|---|
| 未来N日收益率 | \( r_{t+N} = (P_{t+N} - P_t) / P_t \) | 趋势预测、选股 |
| 未来波动率 | 未来N日收益率的标准差 | 风险预测、仓位管理 |
| 事件标签 | 未来是否发生突破/回撤/财报 | 事件驱动策略 |
| 排序标签 | 未来收益在截面上的分位数 | 因子排序、多空组合 |
所有标签都依赖未来数据,但生成过程必须在回测的数据准备阶段完成,而非在策略运行阶段动态计算。这是避免未来函数的第一道防线。
3.2 未来函数的识别与规避
未来函数(Future Function)是指模型在回测时使用了当前时刻尚不可知的信息,导致回测结果虚高。在标签生成场景中,未来函数通常表现为:
- 标签泄露:特征计算时无意中包含了标签本身或标签的衍生信息。
- 时序错位:用 t+1 时刻的数据计算 t 时刻的特征。
- 全局统计:使用全样本均值、标准差等统计量进行归一化,而未按时间窗口滚动计算。
⚠️ 常见未来函数陷阱
1. 使用未来收益率作为特征输入(如用未来5日涨跌幅预测未来1日涨跌幅)。
2. 在计算移动平均时,使用了包含未来数据的窗口(如未做shift操作)。
3. 使用未来数据计算标签后,又将该标签作为特征参与其他模型训练。
1. 使用未来收益率作为特征输入(如用未来5日涨跌幅预测未来1日涨跌幅)。
2. 在计算移动平均时,使用了包含未来数据的窗口(如未做shift操作)。
3. 使用未来数据计算标签后,又将该标签作为特征参与其他模型训练。
规避未来函数的核心原则是:在生成标签时,只允许使用当前时刻及之前的数据;在生成特征时,同样只允许使用当前时刻及之前的数据;标签与特征之间的时间关系必须严格定义并验证。
3.3 标签与特征的时序对齐
时序对齐是标签生成中最容易出错、也最容易被忽视的环节。对齐的核心是确定预测点与标签终点之间的时间偏移关系。
上图中,预测点 t 是特征计算的截止时刻,也是标签计算的起始时刻。特征只能使用 t 及之前的数据,标签则使用 t+1 到 t+N 的未来数据。两者在 t 时刻完成对齐,形成一条训练样本。
3.4 标签生成的代码实现
以下代码展示了如何在 Pandas 中安全地生成未来N日收益率标签,并避免未来函数:
import pandas as pd
import numpy as np
def generate_future_return_label(df, price_col='close', horizon=5):
"""
生成未来N日收益率标签,严格避免未来函数。
参数:
df: DataFrame,必须包含价格列,且按时间升序排列
price_col: 价格列名
horizon: 未来天数
返回:
df: 新增 'label' 列,表示未来 horizon 日的收益率
"""
df = df.copy()
# 计算未来N日收益率:shift(-horizon) 获取未来价格
df['future_price'] = df[price_col].shift(-horizon)
df['label'] = (df['future_price'] - df[price_col]) / df[price_col]
# 删除未来价格列,避免泄露
df.drop(columns=['future_price'], inplace=True)
# 最后 horizon 行标签为 NaN,因为未来数据不足
return df
# 示例用法
dates = pd.date_range('2023-01-01', periods=20, freq='D')
prices = np.random.randn(20).cumsum() + 100
df = pd.DataFrame({'date': dates, 'close': prices})
df = generate_future_return_label(df, horizon=5)
print(df[['date', 'close', 'label']].head(10))
💡 关键点说明
-
- 最后 horizon 行的标签为 NaN,在训练时需要丢弃,避免使用不完整的未来信息。
- 特征计算必须在
-
shift(-horizon) 将未来价格向前移动,使得当前行与未来价格对齐。- 最后 horizon 行的标签为 NaN,在训练时需要丢弃,避免使用不完整的未来信息。
- 特征计算必须在
shift 之前完成,确保特征只使用当前及历史数据。
3.5 标签与特征的严格对齐流程
在实际回测框架中,标签与特征的对齐需要遵循以下步骤:
- 数据准备:确保原始数据按时间升序排列,无缺失值。
- 特征计算:在 t 时刻计算所有特征,仅使用 t 及之前的数据。
- 标签生成:在 t 时刻生成标签,使用 t+1 到 t+N 的未来数据。
- 对齐合并:将特征与标签按时间索引对齐,形成训练样本。
- 去尾处理:删除标签为 NaN 的样本(通常是最后 N 行)。
- 验证检查:随机抽取样本,人工验证特征与标签的时间关系是否正确。
3.6 常见错误与避坑指南
| 错误类型 | 错误示例 | 正确做法 |
|---|---|---|
| 标签泄露 | 特征中包含未来收益率 | 特征只使用历史数据,标签单独生成 |
| 时序错位 | 使用 shift(1) 后未对齐索引 |
使用 shift(-horizon) 并检查索引 |
| 全局统计 | 用全样本均值归一化特征 | 使用滚动窗口或扩展窗口计算统计量 |
| 数据泄露 | 训练集包含测试集数据 | 按时间划分训练/验证/测试集 |
| 标签不完整 | 未处理最后 N 行 NaN | 显式删除或填充标签为 NaN 的样本 |
📌 核心原则总结
1. 标签必须使用未来信息,但生成过程必须在数据准备阶段完成。
2. 特征只能使用当前及历史数据,严禁包含未来信息。
3. 标签与特征在预测点 t 严格对齐,形成训练样本。
4. 每次生成标签后,必须进行去尾处理和验证检查。
1. 标签必须使用未来信息,但生成过程必须在数据准备阶段完成。
2. 特征只能使用当前及历史数据,严禁包含未来信息。
3. 标签与特征在预测点 t 严格对齐,形成训练样本。
4. 每次生成标签后,必须进行去尾处理和验证检查。
掌握标签生成的基础原则,是构建可靠事件驱动回测框架的第一步。只有确保标签与特征的时序对齐,才能避免未来函数对回测结果的污染,为后续模型训练和策略评估打下坚实基础。