开头我直接从一个真实的业务场景切入吧。某财险公司理赔部每天收到几千件车险报案,审核员一个个看材料,平均每件案子的审核时间是十几分钟。人力成本高不说,欺诈案件的漏网率也让人头疼。有的客户本来只是轻微剐蹭,却伙同修理厂把定损金额抬高好几倍;有的团伙在不同地区用同一套手法反复作案,单靠人工经验很难跨案件串起关联。智能保险理赔欺诈预防系统干的事,就是把这些环节自动化:通过规则引擎、特征工程和机器学习模型,对每件理赔申请打一个欺诈风险分,让审核员优先处理高风险案件,同时把低风险案件放到快速通道。这篇文章把这套系统从设计到落地完整拆一遍,包括模型怎么建、特征怎么算、阈值怎么定、线上怎么接,适合做保险科技或风控建模的同学参考。
1. 整体思路与架构设计
1.1 保险反欺诈到底难在哪
先聊一个很多人容易忽略的背景。保险欺诈识别和一般风控场景不一样,它有四个很特殊的难点。
第一是对抗性。信贷风控面对的对手大多是非专业化个体,手段相对固定;但保险欺诈团伙是“专业选手”,他们会研究理赔规则,会试探模型的判定边界,你抓一种手法,他们就换一种手法。这意味着模型必须持续迭代,不可能一次训练完就一劳永逸。
第二是强依赖关联关系。单车欺诈可以从保单和事故特征看出来,但团伙欺诈必须看人和人、人和车、人和修理厂之间的关系。单看某一次理赔,所有特征都正常;把十次理赔放在一起,才发现报案人、伤者、修理厂、定损员之间存在大量重合。所以系统设计里必须有“社交网络分析”这一层,不能只靠单条样本的静态特征。
第三是标签极度稀疏。一家中等规模财险公司,一年车险理赔案件可能上百万件,但最终被确认欺诈并进入黑名单的,往往只有千分之一到万分之几。欺诈案件又是典型的“冰山之下”,大量漏网案件根本没被发现,标签本身也存在噪声。
第四是代价不对等。反欺诈系统如果误杀太多正常案件,会严重伤害客户体验,甚至引发投诉和监管问题。所以这个系统的目标从来不是“尽量抓多”,而是在“抓得准”和“放得快”之间找平衡。
这四个难点决定了系统不能只有一个模型,必须有规则、模型、关系网络、人工调查协同的完整链路。
1.2 为什么选“规则+模型”的混合架构
我刚接手这个项目的时候,团队里有两种声音。一种说直接上个深度学习模型,把文本、图片、结构化数据全扔进去端到端训练;另一种说传统评分卡够用,简单可解释,上线快。
最后定的是混合架构:规则引擎在前,机器学习模型在后,两者串联。讲一下为什么。
深度学习方案在理论上很诱人,但落地时遇到两个现实问题:一是理赔数据里真正干净的结构化标签太少了,文本和图像数据的清洗成本高到吓人;二是理赔审核员和监管机构都要求“为什么拒绝”,深度学习给出的分数很难解释,业务方不买账。而纯规则方案的问题也很明显——规则是死的,欺诈手法是活的,一旦团伙摸清规则就能精准绕开。
混合架构把两类思路的长处接起来了:
- 规则引擎负责处理那些“证据确凿”的场景,比如同一身份证号一个月内报案超过5次、保单刚生效3天就出险、出险时间在保单生效前等,这些直接命中风控红线,不需要模型参与。
- 机器学习模型负责评估“模棱两可”的案件,把规则无法覆盖的复杂特征拿过来打分,输出欺诈概率和风险等级。
- 关系网络模块在模型之上做二次叠加,发现团伙关联时额外提权。
这套架构上线后,我们实测的欺诈识别量比纯规则方案翻了大约4倍,同时把低风险案件的审核时间压缩了60%左右。数字供参考,不同公司的基础不同,结果会有差异,但方向是对的。
1.3 系统整体链路
整个系统从数据流的角度划分为四层,每一层职责单一:
数据接入层:对接核心理赔系统、承保系统、客户关系管理系统,实时抓取报案、查勘、定损、理算、支付等环节事件,经过清洗后写入统一的特征数据库。这里有一个关键设计,就是必须做事件日志回流,不能只存最终结果。比如一笔理赔后来改了三次金额,这三个变更记录都是重要特征来源,只存最终值会丢失大量信息。
规则与模型层:规则引擎先跑,命中红线的直接拦截或转人工;之后模型计算欺诈评分,分箱映射为风险等级。这一层输出三个东西:风险分、风险等级、命中规则列表,三者共同构成审核依据。
关系网络层:基于历史赔案构建人、车、手机号、设备、修理厂、银行卡等实体的关联图谱,实时计算当前案件在网络中的聚集度指标。
业务应用层:审核工作台按风险等级分流案件。高风险进入人工调查队列,中风险进入常规审核,低风险自动通过或极简审核。
整个链路用异步消息队列串联,从案件进入系统到拿到欺诈分,平均耗时控制在3秒以内,不会让客户在报案环节感到延迟。
2. 特征体系与模型选型细节
2.1 特征设计:四类特征缺一不可
模型效果的上限其实在特征设计阶段就决定了,算法只是把特征里的信号释放出来。我在这套系统里把特征分成四大类。
第一类是保单特征。这类特征反映“这份保单是否正常”。典型的有:保单生效到出险的天数、保费与保额之比、投保时是否有异常行为(如短时间内频繁询价后立即投保)、保单批改次数、历史续保记录等。其中“保单生效到出险天数”是强信号,很多欺诈案件在投保后一到两周内就会出险,这个数字如果是负数或者小于3,欺诈概率明显上升。
第二类是赔案特征。反映“这次事故本身是否合理”。包括:报案时间分布(深夜和凌晨出险占比高)、报案延迟天数、出险地点与保单所在地的距离、事故类型(单方事故 vs 多方事故)、是否有目击者、查勘员反馈照片质量等。这里有个容易被忽略的点:报案时间要精确到小时,而且要做节假日标记。节假日凌晨的酒驾顶包案件,特征表现和普通事故差异非常大。
第三类是人员特征。反映“涉案人员是不是老手”。包括:被保险人的历史出险频次、历史理赔金额、驾驶证年龄、年龄、职业稳定性、是否有历史拒赔记录等。这里特别推荐一个强特征:“高频小额出险模式”。有些人专挑1000到3000元的小额事故反复索赔,单次金额低,容易被理赔员忽略,但累计起来非常可观。这个特征用滑动窗口统计过去6个月出险次数,欺诈识别贡献度排在前列。
第四类是关联特征。这是拉开差距的地方。计算当前案件的驾驶人、车辆、手机号在过去12个月里是否与其他欺诈案件存在二度关联。比如A车出险,驾驶员B是C的配偶,而C的车去年被确认欺诈——有这层关系,当前案件的欺诈风险就要显著上调。这类特征在团伙欺诈识别中作用最大,但也是计算成本最高的,一般放在离线批处理中做,在线阶段只查预计算结果。
特征不是越多越好。我们第一版搭了300多个特征,后来用特征重要性和相关性分析砍到80个左右,离线指标不降反升,线上推理速度还快了。特征工程是个不断做减法的过程。
2.2 模型选型:为什么是LightGBM而不是Scorecard
模型选型我们走了一条弯路,这里详细说说。
一开始团队里的资深同事主张用逻辑回归评分卡,理由是保险行业传统、监管看可解释性。我们做了个对比实验,把300多个特征全部标准化后跑逻辑回归,KS值大约0.32,效果能接受。后来我把同样数据用LightGBM跑了一版,KS值直接到0.45以上,AUC也从0.78升到了0.88,差距非常明显。
但这里有一个深层原因:逻辑回归对特征之间非线性关系和高阶交互的捕捉能力太弱。而理赔欺诈场景恰恰是“多特征组合出异常”——单看报案时间正常、单看修车厂正常、单看金额正常,但“凌晨2点 + 修理厂A + 标的车是二手车 + 保单生效第5天”这个组合就非常可疑。GBDT这类树模型天然擅长发现这种组合模式。
那为什么不是更复杂的深度模型?因为样本量不够。我们的建模样本大概20万条有效赔案,对LightGBM来说足够,对深度模型来说就偏少了,很容易过拟合。而且深度模型在表格数据上并没有绝对优势,不如把时间花在特征上。
最后我们采用LightGBM作为主模型,同时保留了评分卡模型做交叉验证。两套模型打分做一致性比对,偏差超过一定阈值的案件自动标记为“争议案件”进入人工复核。这个设计让业务方更放心,也帮我们发现过几批特征计算bug。
2.3 模型评估:KS、AUC都不是核心指标
很多人做风控模型喜欢盯着AUC和KS,但在反欺诈场景里,我最关注的是Top N捕获率(Lift)。
原因是反欺诈系统的价值不是对所有案件排序都准确,而是对风险最高的那部分案件排序准确。人工审核力量是有限的,假设一天有1万件理赔,审核人力只能重点看300件,那么系统真正重要的是:这300件里到底抓到了多少真正的欺诈案件。AUC衡量的是整体排序能力,但整体排序里有大量低风险案件,它们对业务没有意义。
实际操作中,我们按模型分数从高到低排序,计算Top 1%、Top 3%、Top 5%案件中的欺诈案件捕获比例。一个模型如果在Top 3%里捕获了70%以上的欺诈案件,业务价值就非常高。我们的目标设定是:Top 3%捕获率不低于60%才允许上线。
另外还加了一个指标叫干预率误杀率,也就是在模型判定高风险的高分案件里,经人工调查后确认为正常案件的比例。这个指标控制的是客户体验底线,正常不能超过15%,超过就需要调阈值或者优化特征。
3. 实操过程:从数据到上线的完整复现
3.1 样本设计:标签定义是最容易被骂的坑
建模第一步不是调参,是定标签。标签定义错了,后面所有工作都是白做,这是我在这个项目里最深的体会。
我们最终把确认欺诈定义为三类:
- 实赔欺诈:理赔调查人员或第三方调查公司介入后,确认客户存在伪造事故、夸大损失、虚假材料等行为,并完成拒赔或追偿的案件。
- 拒赔欺诈:审核阶段就发现明显欺诈行为并拒赔的。
- 司法认定欺诈:涉及诉讼,法院认定为欺诈的案件。
三类合并为欺诈标签,取值为1。其他案件取值0。
这里有一个细节:标签需要加表现期。理赔案件从报案到结案往往有几个月周期,调查和诉讼时间更长。如果只用当前已定性案件做训练,会把大量“实际上是欺诈但还在调查流程中”的案件当成负样本,模型会学到错误信号。我们的做法是把样本观察期和表现期错开:用某一时期的理赔特征预测未来6个月内是否被定性为欺诈,训练样本只保留已经过完表现期的案件。
样本量上,我们取了近两年的240万条报案记录,最终有效建模样本约52万条,其中欺诈样本约2600条,正负比约1:200。这个比例单靠原始样本没法训练,后面做了欠采样加样本权重处理。
3.2 特征计算:一个容易被忽略的细节
特征计算这里我举个真实例子,展示“高频小额出险频次”这个特征怎么落地。
SELECT policy_holder_id, COUNT(DISTINCT claim_id) AS claim_cnt_6m, SUM(CASE WHEN paid_amount <= 3000 THEN 1 ELSE 0 END) AS small_claim_cnt_6m, AVG(paid_amount) AS avg_paid_amount_6m FROM dwd_claim_event_detail WHERE event_time BETWEEN DATE_SUB(CURRENT_DATE, 180) AND CURRENT_DATE GROUP BY policy_holder_id单看这段SQL功能很简单,但上线的时候踩了两个坑。第一个是数据口径问题:“报案、立案、结案”三个时间点到底用哪个算“发生时间”决定了特征的含义。我们最终统一用“出险时间”字段,避免因理赔流程快慢造成统计偏差。第二个是窗口重叠问题:如果每次在线请求都现算180天的滑动窗口,计算压力太大,而且高并发下容易超时。最终方案是每日离线预计算全量人员特征,在线环节直接查表,只有当日新增案件才触发增量计算。
3.3 LightGBM训练:参数组合参考
训练过程我直接给出一组实测下来稳定可复现的参数组合,供参考:
import lightgbm as lgb params = { 'objective': 'binary', 'boosting_type': 'gbdt', 'learning_rate': 0.03, 'num_leaves': 63, 'max_depth': 7, 'min_child_samples': 20, 'subsample': 0.8, 'subsample_freq': 1, 'colsample_bytree': 0.8, 'reg_alpha': 0.1, 'reg_lambda': 1.0, 'scale_pos_weight': 50, 'n_estimators': 2000, 'early_stopping_rounds': 100 } train_data = lgb.Dataset(X_train, label=y_train, weight=w_train) valid_data = lgb.Dataset(X_val, label=y_val, weight=w_val) model = lgb.train( params, train_data, valid_sets=[valid_data], num_boost_round=2000, callbacks=[lgb.early_stopping(100), lgb.log_evaluation(50)] )几个关键参数说明一下。
scale_pos_weight=50是因为正负样本比例约1:200,直接训练会让模型把全部样本预测为负类。通过权重把少数类的错误代价放大,模型才会有动力去区分欺诈样本。
num_leaves=63和max_depth=7是控制模型复杂度的。一开始我把num_leaves调到127,线下AUC高了一点点,但线上表现明显变差,典型过拟合。63是交叉验证后的折中值。
min_child_samples=20用来防止树在小样本上分得太碎。欺诈样本本来就少,如果叶子节点里只有几条记录,预测结果会非常不稳定。
另外要强调:训练集和验证集必须按时间切分,不能用随机切分。我们用前18个月做训练,后6个月做验证,模拟真实上线后的场景。随机切分在时间序列数据上会高估模型效果,这个坑很常见。
3.4 阈值设定:模型分数不等于业务决策
模型输出的是一个0到1的概率,但业务上不能直接用0.5做分界点,原因就是前面说的正负样本不平衡。
我们是这样定阈值的。先按分数从高到低排序,计算不同截断点的Top N捕获率、误杀率、拦截案件量。然后和理赔部门确定人力上限:每天能人工深度调查的案件量约300件,加上常规审核人力,整体可承受的高风险案件量是每天约500件。根据历史数据反推,500件大约对应分数排名Top 2.5%,于是模型阈值就定在排名Top 2.5%对应的分数值上。
这个阈值不是一成不变的。每个月我们会重新统计最近30天的数据,如果欺诈案件在Top 2.5%中的捕获率出现下滑,说明欺诈手法可能变了,要触发模型重训或特征更新。这种做法比固定阈值要实用得多。
线上部署还有一个细节建议:模型文件要带版本号,预测结果把模型版本和特征版本都记录下来。否则后面模型迭代时,你根本说不清楚某个案件是旧模型判的还是新模型判的。
3.5 与业务系统集成:解耦比什么都重要
系统真正上线时,最容易出问题的地方其实不在模型,而在集成。
我们的做法是:理赔系统在审核员打开案件详情页时,异步调用反欺诈系统的评分接口,拿到风险分后再展示到页面上。整个过程不对理赔主流程造成阻塞,即使反欺诈系统挂了,理赔审核也照常进行,只是页面多了一个“评分暂不可用”的提示。
接口设计上只传案件编号,反欺诈系统通过内部查询拉取需要的特征数据。好处有两个:一是接口调用方不需要传一大堆参数,简单稳定;二是特征计算逻辑全部收敛在反欺诈系统内部,改特征不影响外部系统。
规则引擎和模型的串联顺序也有讲究。先跑规则,命中红色规则的案件直接进人工调查队列,不再走模型评分;绿色规则的案件直接快速通过;只有灰色区域案件进入模型打分。这套路由机制可以把模型的计算量降低大约40%,因为大量明显正常和明显异常的案件都不需要模型参与。规则不是用来替代模型的,是用来帮模型筛选处理对象的。
4. 常见问题与排查技巧实录
4.1 坏样本延迟导致模型失效
现象:模型训练完离线指标不错,线上跑两个月后,Top 3%捕获率从68%掉到45%。
排查过程:一开始以为是特征漂移,检查PSI发现特征分布基本稳定。后来把线上预测结果和3个月后的定性结果做回看,发现模型漏掉的案件大多是“刚报案不久的新案件”,而判断欺诈需要等调查结束。问题出在训练样本上——我们把表现期设定为6个月,但实际案件从报案到确认欺诈平均需要9个月,导致训练标签里“近3个月的案件”大量被错误标记为负样本。
解决方式:把表现期从6个月延长到12个月,并增加一个“标签置信度”字段,只对已经结案的样本赋予确定性标签,未结案样本直接丢弃。重新训练后,线上捕获率回到61%左右。
这是反欺诈建模里最常见的坑,而且很难从数据本身察觉,必须定期做标签回看分析。
4.2 正负样本不平衡导致的“全零”预测
现象:第一版模型训练完,预测概率全部集中在0.01到0.05之间,几乎没有高分样本。
原因:正负样本比例1:200,模型损失函数里正确预测负样本带来的收益远大于正确预测正样本,模型选择了“躺平”——全部预测为负类,整体损失依然很小。
解决方式:除了scale_pos_weight,还用了欠采样加权重组合。具体来说,把所有欺诈样本保留,负样本按1:5的比例随机采样,同时给负样本乘以0.2的样本权重。这样既保证模型见过足够多的负样本多样性,又把训练计算量降下来了。经验值参考:欠采样比例1:5到1:10之间效果较好,太极端会导致负样本多样性不足。
4.3 特征穿越:线下指标虚高的元凶
现象:有个特征“是否命中欺诈黑名单”在特征重要性排名中排第一,模型离线AUC高达0.95,但上线后完全失效。
根因:这个特征在构造时用了未来信息。黑名单是在案件结案后建立的,训练集里有些案件,实际上是在出险之后被加入黑名单的,但在特征计算时,我们用了“当前”的黑名单状态,而建模时没有做时间对齐。这就相当于模型偷看了答案。
排查方式:对每个特征检查它的“时间戳”,确认特征值使用的信息在预测时点已经存在。这是风控建模里必须严格把关的一环,靠代码评审很难全查出来,建议对TOP 20重要特征做逐个人工审查。
4.4 上线后模型漂移的监控
模型上线不是终点,监控才是。我们建了一套简易监控看板,每天对比以下几个指标:
| 指标 | 监控项 | 阈值 | 触发动作 |
|---|---|---|---|
| 分数分布 | 当日评分均值与近30日均值偏差 | ±2个标准差 | 告警,检查特征 |
| 特征分布 | 核心特征PSI | PSI < 0.1稳定,>0.25告警 | 告警,排查特征来源 |
| 业务结果 | Top 3%案件的拒赔率/调查确认率 | 连续7日下降超过20% | 触发模型重训 |
| 规则命中 | 规则命中率变化 | 超过30%波动 | 复核规则有效性 |
这套监控本身不复杂,但价值很大。有一次我们发现“保单生效到出险天数”特征的分布突然偏移,排查后确认是前端投保流程改版,把投保时间字段的逻辑改了。如果没有监控,这个特征会悄悄带偏所有案件评分,而且很难被发现。
4.5 关系网络特征的计算性能问题
关联特征的在线计算曾经是我们性能瓶颈。最初设计是每笔案件实时查三度关联,结果高峰期接口响应时间从2秒涨到15秒。
后来改成两级策略:离线预计算 + 在线查表。离线每天构建一次全量关系图谱,预计算每个实体的“聚集度”“关联欺诈案件数”等指标并写入特征库。在线环节只做字段查询,复杂度从图遍历降为一次内存读取。改造后接口P99耗时稳定在800毫秒以内。
代价是实时性下降,新增的欺诈案件要等第二天才会反映到关联特征里。对反欺诈这个场景来说,半天的延迟完全可接受,毕竟调查和拒赔本来就不是分钟级决策。
写在最后
这个项目做下来,我最大的体会是:反欺诈系统的技术难度其实不在模型,而在数据质量的打磨和业务逻辑的深度理解。我见过很多团队花大量时间调参、换模型框架,却忽略了标签定义、特征穿越、表现期这些“脏活累活”。实际上,把样本和特征做扎实,用最普通的LightGBM也能达到很好的效果。
另外分享一个经验:做反欺诈系统一定要拉上理赔业务人员深度参与,最好是让他们坐进项目组。原因很简单,欺诈手法本质上是一线审核员最先感知到的,他们脑子里积累了无数“只可意会不可言传”的判断经验。这些经验翻译成特征和规则,比任何公开数据集都值钱。我甚至觉得,这个项目后续真正值得投入的方向,就是把一线审核员的定性判断结构化,沉淀成可复用的规则和标注样本,这比继续堆模型复杂度有意义得多。