2. 回放验证的数据准备:历史数据清洗、数据对齐、时间窗口划分

回放验证(Backtesting)的核心在于用历史数据模拟模型在真实环境中的表现。数据准备的质量直接决定验证结论的可信度。本节聚焦三个关键环节:历史数据清洗、数据对齐与时间窗口划分,确保回放过程不引入前瞻偏差(Look-Ahead Bias)或数据泄漏。

2.1 历史数据清洗:剔除噪声与异常

原始保单与理赔数据通常包含录入错误、重复记录、缺失字段和极端异常值。清洗步骤应遵循“先结构后内容”的顺序:

  1. 去重:按保单号+出险日期+赔案号联合去重,保留最新修改记录。
  2. 缺失值处理:关键字段(如保额、费率因子、出险时间)缺失时,优先追溯源系统补全;无法补全的整条记录标记为“不可用”并记录剔除原因。
  3. 异常值截断:对理赔金额、保额等连续变量,使用分位数法(如99.5%分位)或业务阈值截断,避免极端值扭曲模型评估指标。
  4. 业务规则校验:例如出险日期不得早于保单生效日,理赔金额不得大于保额等。
精算提示: 清洗日志必须保留原始值与清洗后值的映射关系,便于审计与回溯。建议使用版本控制管理清洗脚本。

2.2 数据对齐:消除时间与口径差异

回放验证要求模型输入特征与历史观测值在时间点、聚合粒度、业务定义上完全对齐。常见对齐维度如下:

对齐维度 常见问题 对齐方法
时间戳对齐 保单生效日、出险日、报案日、结案日混用 统一使用“评估基准日”作为时间锚点,其余日期仅用于衍生变量
聚合粒度对齐 模型按保单粒度训练,但回放数据按赔案粒度汇总 将赔案数据按保单号+评估期聚合为保单-期记录
业务口径对齐 历史数据中“已赚保费”计算方式发生过变更 统一使用最新口径重新计算历史字段,或分段使用不同口径
特征衍生对齐 模型训练时使用了未来信息(如后续理赔次数) 严格限定特征只使用评估基准日之前的信息
常见陷阱: 数据对齐中最容易被忽视的是“特征衍生时的未来信息”。例如用整个保单年度的理赔次数预测中期退保概率,这在回放中会高估模型效果。务必对每个特征做“时间戳穿透检查”。

2.3 时间窗口划分:训练、验证与回放期

回放验证需要将历史数据划分为三个互不重叠的时间窗口,模拟模型上线后的真实预测场景。下图展示了标准的三段式划分结构:

回放验证时间窗口划分示意 训练期 模型拟合与参数估计 验证期 超参数调优 回放期(Out-of-Time) 模拟模型上线后的预测表现 T₀ T₁ T₂ T₃(当前) 关键原则: 1. 训练期与回放期之间必须保留足够的时间间隔(如12个月),避免时间序列自相关影响。 2. 验证期用于模型选择,不可与回放期重叠,否则会高估模型泛化能力。 3. 回放期应覆盖至少一个完整业务周期(如一个承保年度),以捕捉季节性波动。

窗口划分的常见策略包括:

  • 固定窗口法:训练期固定,回放期向后滚动。适用于业务环境相对稳定的场景。
  • 扩展窗口法:每次回放时训练期向前扩展,保留更多历史信息。适用于数据量较小的场景。
  • 滑动窗口法:训练期与回放期同步向前滑动,保持窗口长度不变。适用于快速变化的市场环境。

以下代码示例展示了使用 Python 实现固定窗口划分的典型逻辑:

import pandas as pd
from datetime import timedelta

def split_backtest_windows(df, date_col, train_end, test_start, test_end):
    """
    固定窗口划分:训练期 [min_date, train_end]
                 回放期 [test_start, test_end]
    """
    train = df[df[date_col] <= train_end].copy()
    test  = df[(df[date_col] >= test_start) & (df[date_col] < test_end)].copy()
    return train, test

# 示例:训练期截止 2022-12-31,回放期 2024-01-01 至 2024-12-31
train_data, test_data = split_backtest_windows(
    df=policy_data,
    date_col='评估基准日',
    train_end='2022-12-31',
    test_start='2024-01-01',
    test_end='2024-12-31'
)

2.4 数据准备流程总览

将上述三个环节串联起来,形成完整的数据准备流水线:

回放验证数据准备流水线 原始保单/理赔 数据清洗 数据对齐 窗口划分 训练集 验证集 回放集(Out-of-Time) 流水线输出产物: • 清洗日志(记录每条记录的清洗操作与原因) • 对齐映射表(原始字段→回放特征字段的转换规则) • 窗口划分元数据(各窗口起止时间、记录数、关键统计量)
最佳实践: 建议将数据准备流水线封装为可重复执行的脚本或 DAG(如 Airflow),每次回放验证前重新运行,确保数据版本与模型版本一一对应。使用 YAML 配置文件管理窗口起止时间、清洗阈值等参数,避免硬编码。