4. 数据探索性分析(EDA):赔付率分布可视化、时间序列趋势分析、季节性分解

数据探索性分析(EDA)是赔付率尖峰检测的基石。在构建任何检测模型之前,必须通过可视化与统计手段理解赔付率数据的分布形态、长期趋势以及周期性规律。本节将围绕三个核心维度展开:分布可视化、时间序列趋势分析、季节性分解。

4.1 赔付率分布可视化

赔付率(Loss Ratio)通常定义为 已发生赔款 / 已赚保费。其分布特征直接影响尖峰阈值的设定方法。

4.1.1 直方图与核密度估计(KDE)

通过直方图观察赔付率的整体分布形状,判断是否存在明显的右偏(长尾)或多峰特征。KDE 曲线可平滑估计概率密度函数。

关键观察指标:
  • 偏度(Skewness): 正偏态(右偏)意味着大部分保单赔付率较低,但存在少数极高赔付率(潜在尖峰)。
  • 峰度(Kurtosis): 高峰度(>3)表明数据在均值附近集中,且尾部较厚,尖峰风险更高。
  • 异常值区间: 超过 99% 分位数的赔付率值应被标记为候选尖峰。
赔付率分布对比:正常 vs 尖峰期 正常时期 KDE 99% 阈值 尖峰时期 KDE 99% 阈值 尖峰 尖峰期分布尾部明显变厚,KDE 曲线出现次峰

4.1.2 箱线图与分位数分析

箱线图可直观展示赔付率的中位数、四分位距(IQR)以及异常值。结合分位数表,可量化尖峰的严重程度。

分位数 正常时期赔付率 尖峰时期赔付率 偏差幅度
25% (Q1) 0.45 0.48 +6.7%
50% (中位数) 0.62 0.68 +9.7%
75% (Q3) 0.78 0.92 +17.9%
99% (阈值) 1.20 1.85 +54.2%
最大值 1.45 2.60 +79.3%
实践建议: 在 EDA 阶段,建议同时绘制 log 变换后的赔付率分布。对数变换可压缩右偏尾部,使尖峰特征在正态 Q-Q 图上更易识别。

4.2 时间序列趋势分析

赔付率随时间的变化趋势是判断尖峰是否由系统性因素(如费率不足、理赔通胀)引起的核心依据。

4.2.1 滚动统计量(Rolling Statistics)

计算赔付率的滚动均值与滚动标准差,可平滑短期波动,暴露长期趋势。

  • 滚动窗口选择: 月度数据通常使用 12 个月窗口(消除年周期);周度数据使用 4 周或 13 周窗口。
  • 趋势信号: 当滚动均值持续上升超过 2 个标准差时,提示可能存在结构性趋势变化。
  • 尖峰叠加趋势: 若尖峰出现在趋势上升期,需区分是趋势加速还是孤立事件。

4.2.2 趋势分解(Trend Decomposition)

使用 STL(Seasonal-Trend decomposition using LOESS)或移动平均法将时间序列拆解为趋势分量、季节分量和残差分量。

# Python 示例:使用 statsmodels 进行 STL 分解
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import STL

# 假设 df 包含 'date' 和 'loss_ratio' 列
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date').asfreq('MS')  # 月度频率

stl = STL(df['loss_ratio'], period=12)
result = stl.fit()

# 提取分量
trend = result.trend
seasonal = result.seasonal
residual = result.resid

# 可视化(此处仅展示代码逻辑)
fig, axes = plt.subplots(4, 1, figsize=(12, 8))
df['loss_ratio'].plot(ax=axes[0], title='原始序列')
trend.plot(ax=axes[1], title='趋势分量')
seasonal.plot(ax=axes[2], title='季节分量')
residual.plot(ax=axes[3], title='残差分量')
plt.tight_layout()
plt.show()
注意: 趋势分解假设季节成分是稳定的。若业务存在费率调整、再保结构变化等结构性断点,需先进行断点检测(如 Chow 检验),再分段分解。

4.3 季节性分解

赔付率常受自然季节(如台风季、冬季冰雪)、财务季节(如年末冲业绩)或承保周期影响。季节性分解可量化这些规律,避免将正常季节性波动误判为尖峰。

4.3.1 季节性子序列图(Seasonal Subseries Plot)

将每年同月份(或同季度)的赔付率绘制在同一张图上,可直观对比年际变化与季节模式。

月份 2021 年 2022 年 2023 年 季节均值 季节标准差
1 月 0.55 0.58 0.62 0.583 0.035
2 月 0.50 0.52 0.55 0.523 0.025
7 月(台风季) 0.85 0.92 1.10 0.957 0.130
8 月(台风季) 0.90 0.88 1.25 1.010 0.210
12 月 0.60 0.65 0.68 0.643 0.040

从上表可见,7-8 月(台风季)的季节均值显著高于其他月份,且 2023 年 8 月的赔付率(1.25)超出季节均值 2 个标准差以上,应标记为季节性尖峰候选。

4.3.2 季节调整(Seasonal Adjustment)

通过季节调整剔除可预期的季节波动,使残差序列更清晰地反映异常事件。

# 季节调整:原始值 - 季节分量
seasonally_adjusted = df['loss_ratio'] - seasonal

# 在调整后的序列上检测尖峰
threshold = seasonally_adjusted.mean() + 3 * seasonally_adjusted.std()
spikes = seasonally_adjusted[seasonally_adjusted > threshold]

print(f"季节调整后检测到 {len(spikes)} 个尖峰点")
print(spikes.head())
季节性分解与尖峰检测流程 原始赔付率序列 STL 分解 趋势分量 季节分量 残差分量 季节调整(减季节分量) 尖峰检测 尖峰标记列表

4.4 EDA 综合输出清单

完成上述分析后,应输出以下关键成果,作为后续建模的输入:

  1. 分布统计表: 包含均值、中位数、标准差、偏度、峰度、99% 分位数。
  2. 趋势图: 原始序列 + 滚动均值(12 个月) + 滚动标准差(12 个月)。
  3. 季节因子表: 每个月份/季度的季节指数(乘性)或季节增量(加性)。
  4. 残差序列: 剔除趋势和季节后的纯随机波动序列,用于尖峰阈值设定。
  5. 候选尖峰列表: 基于残差超过 3σ 或 99% 分位数的点,附带时间戳和原始赔付率。
精算实务提示: EDA 不是一次性工作。当业务环境(如新费率表、新再保合约)发生变化时,应重新执行 EDA 以更新季节因子和趋势基线。建议将 EDA 流程封装为自动化报告(如 Quarto 或 Jupyter Notebook),每月自动生成。