保险定价:广义线性模型与梯度提升预测赔付

FreeGuideOnline 最新 2026-06-23

python import statsmodels.api as sm import pandas as pd

示例数据:暴露量(年数)用于处理不同保险期限

data = pd.DataFrame({ 'claims': [0, 1, 0, 2, 1], 'exposure': [1.0, 1.0, 0.5, 2.0, 1.0], 'age': [25, 35, 45, 22, 30], 'vehicle_age': [3, 5, 8, 2, 4] })

添加截距

X = sm.add_constant(data[['age', 'vehicle_age']]) y = data['claims'] exposure = data['exposure']

泊松回归,带偏移项(offset)

model = sm.GLM(y, X, family=sm.families.Poisson(), offset=np.log(exposure)) result = model.fit() print(result.summary())

`offset = log(exposure)` 将不同期限的保单拉平到同一年化频率基准。

### 2.3 强度建模:伽马回归

单次赔付金额通常用**伽马分布**拟合,连接函数常用对数。这保证了预测值为正,并且能捕捉乘法效应。

```python
# 假设severe_data包含strictly 正的赔付金额
import statsmodels.api as sm
import pandas as pd

severe_data = pd.DataFrame({
    'severity': [1200, 500, 3400, 800, 2100],
    'age': [25, 35, 45, 22, 30],
    'vehicle_age': [3, 5, 8, 2, 4]
})

X = sm.add_constant(severe_data[['age', 'vehicle_age']])
y = severe_data['severity']

model_gamma = sm.GLM(y, X, family=sm.families.Gamma(link=sm.families.links.Log()))
result_gamma = model_gamma.fit()
print(result_gamma.summary())

2.4 将频率与强度合并

纯风险保费预测值 = 预测频率 × 预测强度。
注意:如果两个模型都用对数连接,那么最终保费可表达为所有特征效果的指数之和,这与乘法费率结构天然一致,极具可解释性——这正是GLM在监管严格的市场中仍占主导地位的原因。


3. 梯度提升预测:突破线性假设的利器

即使GLM包含交互项,也难以捕捉复杂的非线性关系和变量间的深层依赖。梯度提升机(Gradient Boosting Machines) 作为一种强大的机器学习方法,能自动学习复杂结构,显著提升预测精度。

3.1 GBDT如何适应保险赔付问题?

针对频率和强度的目标特性,我们采用特定损失函数:

  • 泊松损失(Poisson deviance):用于预测索赔频率,天然处理计数。
  • 伽马损失(Gamma deviance):用于预测赔付强度,处理正数偏态。
  • 另一种常用策略:直接预测综合赔款(Tweedie损失)。Tweedie分布是泊松-伽马复合分布,在0处有概率质量,在正数区域连续,完美匹配聚合赔付数据。这是许多Kaggle保险竞赛的标准做法。

3.2 实战:用XGBoost预测纯风险保费

数据准备:假设有保单ID、特征、暴露量、总赔款(频繁为零)。

Tweedie回归方案(一步到位)

import xgboost as xgb
import numpy as np

# 训练数据:X特征,y为总赔款(非负,大量零)
# exposure权重通过样本权重传递
dtrain = xgb.DMatrix(X, label=y)
# 设置Tweedie回归:参数tweedie_variance_power介于1-2
params = {
    'objective': 'reg:tweedie',
    'tweedie_variance_power': 1.5,  # 1代表泊松,2代表伽马,1.5是常用折中
    'eval_metric': 'tweedie-nloglik@1.5',
    'max_depth': 5,
    'learning_rate': 0.05,
    'subsample': 0.8,
    'colsample_bytree': 0.8
}
# 样本权重设为暴露量,因为更长保险期的总赔款规模更大
model = xgb.train(params, dtrain, num_boost_round=500,
                  sample_weight=exposure)
# 预测:输出即为期望总赔款,除以暴露即得到年化纯风险保费
pred = model.predict(dtest)
pure_premium = pred / exposure_test

频率-强度两阶段方案(更精细)

  1. objective='count:poisson' 建模频率,暴露量作为样本权重。
  2. 仅用出险记录(赔款>0)的样本,用 objective='reg:gamma' 建模强度。
  3. 最终预期赔款 = 预测频率 × 预测强度。注意:需要对无法见到的零赔款保单做频率平均校准。

3.3 模型解释性保障:SHAP值

黑箱模型在承保和监管中面临挑战。SHAP(SHapley Additive exPlanations) 可以为每个预测分配特征贡献,生成与GLM系数解读类似的一致性解释。

import shap

explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)
# 可视化特征重要性
shap.summary_plot(shap_values, X)