30、保险理赔欺诈检测的 Lambda 架构实践

保险理赔欺诈检测的 Lambda 架构实践

1. 数据模型概述

1.1 实体与关系

在保险业务的数据环境中,存在多个关键实体,如 Claim_status Claim_type Policy_type 等。 Policy_owner 实体包含 PolicyOwnerDOB (保单所有者出生日期)和 PolicyStartDate (保单开始日期)列, Claim 实体有 ClaimWeatherCond (理赔申请时的天气状况)列。此外, PO_Drv_Hist 实体存储保单所有者的驾驶历史详细信息,其属性如下:
| 属性 | 描述 |
| ---- | ---- |
| PolicyOwnerId (FK) | 保单所有者 ID(外键) |
| ViolationNum | 违规次数 |
| ViolationSeverity | 违规严重程度 |
| ViolationDate | 违规日期 |
| ViolationDetails | 违规详情 |

PolicyOwner PO_Drv_Hist 实体之间存在一对多关系,即一个保单所有者可能有一个或多个违规记录,如果没有违规记录,则 PO_Drv_Hist 实体中不会有该保单所有者的记录。

1.2 事实模型考量

可以将当前的数据模型视为基于事实的模型。数据模型已处于第三范式,动态表(如 Claim Claim_resubmission Claim_settelement Claim_status )已有用于捕获日期/时间的列, Policy 实体也添加了 PolicyStartDate 列。静态表(如 Claim_type Claim_status_type 等)虽无时间戳列,但假设静态数据不变,可对数据进行反规范化处理,用于批量层视图。

2. 欺诈数据条件

为了设计批量层视图,需要明确用于确定欺诈可能性的数据条件:
1. 若客户在过去 12 个月内提交了超过 5 次理赔申请,则其下一次理赔申请可能存在欺诈。
2. 理赔申请时间在晚上 10 点之后,表明存在欺诈可能性。
3. 雪、雨、风暴、雪崩、龙卷风等天气状况下的理赔申请,可能存在欺诈。
4. 过去 12 个月内至少有 2 次严重程度为 1 的违规记录的青少年司机,可能提交欺诈性理赔申请。
5. 过去 12 个月内至少有 3 次严重程度为 1 的违规记录的司机,可能提交欺诈性理赔申请。

保险公司根据其预测模型确定,满足条件(1)以及另外两个条件的理赔申请,需要放入额外评估/调查队列;满足条件 2、3 以及条件 4 或 5 的理赔申请,也需要放入额外评估/调查队列;其他理赔申请则被视为真实申请,可快速处理,无需额外约束。

3. 批量层设计

3.1 数据反规范化

首先对数据进行反规范化处理:
- 理赔相关反规范化 :从 Claim 实体开始,包含 Claim_line_item Claim_status Claim_status_type Claim_type 实体的相关列,仅包含所需列,用于与理赔相关的批量视图。
- 保单相关反规范化 :对 Policy 实体进行反规范化,包含 Policy_owner Policy_type 实体的列,用于与保单相关的批量视图。同时,为两个视图添加 LastModified 属性,以处理时间变化。

反规范化后的实体如下:
| 理赔实体 | 保单实体 |
| ---- | ---- |
| ClaimId
PolicyId (FK)
ClaimSubmissionDate
ClaimSeqId
ClaimAmount
ClaimType
ClaimStatus
ClaimWeatherCond
LastModified | PolicyOwnerId
PolicyOwnerSSNFEIN
PolicyOwnerType
PolicyType
PolicyId
PolicyEndDate
LastModified
PolicyStartDate
PolicyOwnerDOB |

3.2 批量视图设计

理赔相关批量视图
  • 视图 1 :统计过去 12 个月内某个保单的理赔申请数量,将数量大于 5 的记录存入临时表,然后将该临时表与反规范化后的 Policy 实体连接,获取保单所有者详细信息,构成批量视图。
  • 视图 2 :过滤出雪、雨、风暴、雪崩、龙卷风等天气状况下的理赔申请。
保单相关批量视图
  • 视图 3 :列出过去 12 个月内至少有 2 次严重程度为 1 的违规记录的青少年司机。先使用 PO_Drv_Hist 实体填充一个临时表,存储过去 12 个月内有 2 次或更多严重程度为 1 的违规记录的司机信息,然后使用反规范化后的 Policy 实体中的 DOB 过滤出年龄小于等于 19 岁的司机。
  • 视图 4 :使用视图 3 创建的临时表,过滤出年龄大于 19 岁的司机。

以下是批量视图设计的 mermaid 流程图:

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A[数据反规范化]:::process --> B[理赔相关批量视图]:::process
    A --> C[保单相关批量视图]:::process
    B --> B1[视图 1: 统计理赔数量]:::process
    B --> B2[视图 2: 按天气过滤]:::process
    C --> C1[视图 3: 青少年违规司机]:::process
    C --> C2[视图 4: 成年违规司机]:::process

4. 批量层实现

4.1 存储与分区

使用 HDFS 存储主数据和批量层视图(Hive 表),Hive 用于元数据管理,也可使用 MySQL 存储元数据。为了追加垂直或基于时间的数据,使用 Hive 分区(按日、周或月,根据应用需求而定),以 LastModified 时间戳进行表分区。以下是构成主数据的 Hive 表创建语句:

CREATE TABLE ClaimsMaster(
    ClaimId INT,
    ClaimSeqId INT,
    PolicyId INT,
    ClaimSubmissionDate TIMESTAMP,
    ClaimType STRING,
    ClaimAmount INT,
    ClaimSTATUS STRING,
    ClaimWeatherCond STRING
)
PARTITIONED BY (LastModified TIMESTAMP)
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\;";

CREATE TABLE PolicyMaster(
    PolicyId INT,
    PolicyOwnerId INT,
    PolicyOwnerDOB DATE,
    PolicyOwnerSSNFEIN STRING,
    PolicyOwnerType STRING,
    PolicyType STRING,
    PolicyStartDate TIMESTAMP,
    PolicyEndDate TIMESTAMP
)
PARTITIONED BY (LastModified TIMESTAMP)
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\;";

CREATE TABLE PO_Drv_Hist(
    PolicyOwnerId INT,
    ViolationNum SMALLINT,
    ViolationSeverity TINYINT,
    ViolationDate TIMESTAMP,
    ViolationDetails STRING
)
PARTITIONED BY (LastModified TIMESTAMP)
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\;";

4.2 数据添加

使用动态分区按日(或其他必要频率)添加新数据。以 ClaimsMaster 表为例,创建临时表并添加新分区的步骤如下:
1. 创建外部临时表 ClaimsMaster_stg

CREATE EXTERNAL TABLE ClaimsMaster_stg(
    ClaimId INT,
    ClaimSeqId INT,
    PolicyId INT,
    ClaimSubmissionDate TIMESTAMP,
    ClaimType STRING,
    ClaimAmount INT,
    ClaimSTATUS STRING,
    ClaimWeatherCond STRING,
    LastModified TIMESTAMP
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\;"
LOCATION "/InsuranceExample/ClaimsMaster/staging";
  1. 将临时表数据插入 ClaimsMaster 表:
FROM ClaimsMaster_stg INSERT OVERWRITE TABLE ClaimsMaster PARTITION (LastModified)
SELECT ClaimId, ClaimSeqId, PolicyId,
    ClaimSubmissionDate, ClaimType, ClaimAmount, ClaimSTATUS, ClaimWeatherCond,
    LastModified;

相同的原则可应用于 PolicyMaster PO_Drv_Hist 表,且该过程可自动化和调度。

4.3 批量视图创建

创建 BatchProcHist 表来维护批量视图创建历史:

CREATE TABLE BatchProcHist(
    ViewName STRING,
    CreatedAt timestamp
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\;";
视图 1:过去 12 个月内提交超过 5 次理赔申请的保单所有者
-- 第一步:获取过去 12 个月内理赔申请超过 5 次的保单列表
Create table ClaimDeftemp1 as
Select PolicyId, count(ClaimId) as Claimcount
from ClaimsMaster
where datediff(current_date, add_months(to_date(ClaimSubmissionDate), 12)) <= 0
group by PolicyId
having count(ClaimId) > 5;

-- 第二步:连接临时表与反规范化的 Policy 实体,获取保单所有者详细信息
Create table ClaimDefView as
Select P.PolicyOwnerID, P.PolicyId, C.Claimcount
from PolicyMaster P, ClaimDeftemp1 C
where P.PolicyId = C.PolicyId;

-- 写入历史表
INSERT INTO TABLE BatchProcHist
VALUES ('ClaimDefView', from_unixtime(unix_timestamp()));
视图 2:按天气条件过滤的理赔申请
-- 创建视图
CREATE table ClaimWeatherView as
Select distinct ClaimId, ClaimWeatherCond
from ClaimsMaster
where ClaimWeatherCond in ('Snow', 'Rain', 'Storm', 'Avalanche', 'Tornado');

-- 写入历史表
INSERT INTO TABLE BatchProcHist
VALUES ('ClaimWeatherView', from_unixtime(unix_timestamp()));
视图 3:过去 12 个月内至少有 2 次严重程度为 1 的违规记录的青少年司机
-- 第一步:获取过去 12 个月内至少有 2 次严重程度为 1 的违规记录的司机列表
Create table TeenageVioltemp1 as
Select PolicyOwnerId, count(ViolationSeverity) as TotalViolations
from PO_Drv_Hist
where (datediff(current_date, add_months(to_date(ViolationDate), 12)) <= 0)
    and (ViolationSeverity = 1)
group by PolicyOwnerId
having count(ViolationSeverity) > 2;

-- 第二步:过滤出年龄小于等于 19 岁的司机
Create table TeenageViolView as
Select T.PolicyOwnerId, T.TotalViolations
from TeenageVioltemp1 T, PolicyMaster P
where T.PolicyOwnerId = P.PolicyOwnerId
    and (datediff(current_date, add_months(P.PolicyOwnerDOB, 228)) <= 0);

-- 写入历史表
INSERT INTO TABLE BatchProcHist
VALUES ('TeenageViolView', from_unixtime(unix_timestamp()));
视图 4:过去 12 个月内至少有 3 次严重程度为 1 的违规记录的成年司机
-- 第一步:获取过去 12 个月内至少有 3 次严重程度为 1 的违规记录的司机列表
Create table Violtemp1 as
Select PolicyOwnerId, count(ViolationSeverity) as TotalViolations
from PO_Drv_Hist
where (datediff(current_date, add_months(to_date(ViolationDate), 12)) <= 0)
    and (ViolationSeverity = 1)
group by PolicyOwnerId
having count(ViolationSeverity) > 3;

-- 第二步:过滤出年龄大于 19 岁的司机
Create table AdultViolView as
Select T.PolicyOwnerId, T.TotalViolations
from Violtemp1 T, PolicyMaster P
where T.PolicyOwnerId = P.PolicyOwnerId
    and (datediff(add_months(P.PolicyOwnerDOB, 228), current_date) < 0);

-- 写入历史表
INSERT INTO TABLE BatchProcHist
VALUES ('AdultViolView ', from_unixtime(unix_timestamp()));

重要提示:创建批量视图后,不要忘记删除临时表,否则脚本可能会出错。

5. 服务层实现

5.1 服务层要求

服务层的主要功能是提供批量视图的快速访问,减少延迟。因此,服务层需要是一个专门的分布式数据库,具备以下特性:
- 托管批量视图,支持随机和顺序数据访问(仅读)的良好性能。
- 当批量层重建批量视图时,能够快速替换为新版本(支持批量更新)。
- 具有容错能力,因为视图可从批量层快速重新部署。
- 具备索引功能,以便快速检索数据。

5.2 Splout SQL 应用

使用 Splout SQL 部署批量层视图。Splout SQL 可将批量层视图作为表部署在表空间中,表空间用于分组具有相同键列的表,可使用相同的分区键对多个表进行分区。

表空间设计

观察到批量视图 1、3 和 4 使用 PolicyOwnerId 作为键列,可设计一个包含这三个批量视图的表空间;另一个表空间可包含使用 ClaimId 作为键列的批量视图 2。

表空间生成

使用 “generate” 工具生成表空间,需要使用 JSON 表空间描述符。以 PolicyTblspace 为例,描述符如下:

{
    "name": "PolicyTblspace",
    "nPartitions": 12,
    "partitionedTables": [
        {
            "name": "ClaimDefView",
            "partitionFields": "PolicyOwnerId",
            "tableInputs": [
                {
                    "inputType": "HIVE",
                    "hiveTableName": "ClaimDefView",
                    "hiveDbName": "MyHiveDB"
                }
            ]
        },
        {
            "name": "TeenageViolView",
            "partitionFields": "PolicyOwnerId",
            "tableInputs": [
                {
                    "inputType": "HIVE",
                    "hiveTableName": "TeenageViolView",
                    "hiveDbName": "MyHiveDB"
                }
            ]
        },
        {
            "name": "AdultViolView",
            "partitionFields": "PolicyOwnerId",
            "tableInputs": [
                {
                    "inputType": "HIVE",
                    "hiveTableName": "AdultViolView",
                    "hiveDbName": "MyHiveDB"
                }
            ]
        }
    ]
}

执行以下命令生成 PolicyTblspace 表空间:

hadoop jar splout-*-hadoop.jar generate -tf file:///`pwd`/PolicyTblspace.json -o out-MyHiveDB_splout_example
索引添加

对于性能优化,可使用 simple-generate 工具添加索引。以 ClaimTblspace 为例,创建带有额外索引的表空间的命令如下:

hadoop jar splout-hadoop-*-hadoop.jar simple-generate –it HIVE –hdb MyHiveDB –htn ClaimWeatherView -o out-MyHiveDB_splout_example -pby ClaimId -p 1 -idx "ClaimWeatherCond" -t ClaimWeatherView -tb ClaimTblspace
表空间部署

生成表空间后,使用以下命令部署:

hadoop jar splout-hadoop-*-hadoop.jar deploy -q http://localhost:4412 -root out-MyHiveDB1_splout_example -ts PolicyTblspace
hadoop jar splout-hadoop-*-hadoop.jar deploy -q http://localhost:4412 -root out-MyHiveDB2_splout_example -ts ClaimTblspace

部署后,可使用 REST API 查询表空间。例如,检查特定理赔申请( ClaimId=14124736 )是否在恶劣天气条件下提交:

http://localhost:4412/api/query/ClaimTblspace?sql=SELECT * FROM ClaimWeatherView;&key=14124736

6. 速度层实现

6.1 速度层目的

速度层的目的是使批量层视图尚未处理的数据能够无延迟地可用。与批量层视图不同,速度层对视图进行增量处理,仅处理自上次增量处理后执行的新事务。

6.2 异步更新选择

考虑到分析应用更注重复杂计算和聚合,而非交互式用户输入,且数据量较大,异步更新更有用,可更好地控制更新(如临时分配额外请求以处理不同负载)。

6.3 Spark 实现

使用 Spark 和 Spark SQL 实现速度层。以 ClaimDefView_S 视图为例,创建速度层视图的步骤如下:
1. 获取批量视图的最新创建时间:

Create table MaxTable as
select ViewName, max(CreatedAt) as MaxDate
from BatchProcHist
group by ViewName
having ViewName = 'ClaimDefView';
  1. 获取速度层视图的最新创建时间:
Insert into MaxTable
select ViewName, max(CreatedAt)
from BatchProcHist
group by ViewName
having ViewName = 'ClaimDefView_S';
  1. 确定最新的创建时间:
Create table MaxTbl1 as
select max(MaxDate) as MaxDate
from MaxTable;
  1. 获取未处理的记录并创建临时表:
Create table ClaimDeftemp11 as
Select PolicyId, ClaimId
from ClaimsMaster a, MaxTbl1 b
where a.LastModified > b.MaxDate;

Create table ClaimDeftemp12 as
Select PolicyId, count(ClaimId) as Claimcount
from ClaimDeftemp11
where datediff(current_date, add_months(to_date(ClaimSubmissionDate), 12)) <= 0
group by PolicyId
having count(ClaimId) > 5;
  1. 连接临时表与反规范化的 Policy 实体,创建速度层视图并写入历史表:
Create table ClaimDefView_S as
Select P.PolicyOwnerID, P.PolicyId, C.Claimcount
from PolicyMaster P, ClaimDeftemp12 C
where P.PolicyId = C.PolicyId;

INSERT INTO TABLE BatchProcHist
VALUES ('ClaimDefView_S', from_unixtime(unix_timestamp()));
  1. 删除临时表:
Drop Table MaxTable;
Drop Table MaxTbl1;
Drop Table ClaimDeftemp11;
Drop Table ClaimDeftemp12;

其他速度层视图(如 ClaimWeatherView_S TeenageViolView_S AdultViolView_S )的创建过程类似。

通过以上步骤,完成了保险理赔欺诈检测的 Lambda 架构实践,包括数据模型设计、批量层实现、服务层部署和速度层处理,能够有效处理保险理赔数据,检测欺诈可能性。

7. 速度层其他视图创建

7.1 ClaimWeatherView_S 视图创建

此视图用于筛选出未处理且天气状况符合欺诈条件的理赔申请。具体步骤如下:
1. 获取批量视图和速度层视图的最新创建时间:

Create table MaxTable as
select ViewName, max(CreatedAt) as MaxDate
from BatchProcHist
group by ViewName
having ViewName = 'ClaimWeatherView';

Insert into MaxTable
select ViewName, max(CreatedAt)
from BatchProcHist
group by ViewName
having ViewName = 'ClaimWeatherView_S';
  1. 确定最新的创建时间:
Create table MaxTbl1 as
select max(MaxDate) as MaxDate
from MaxTable;
  1. 创建速度层视图并写入历史表:
CREATE table ClaimWeatherView_S as
Select distinct a.ClaimId, a.ClaimWeatherCond
from ClaimsMaster a, MaxTbl1 b
where a.LastModified > b.MaxDate
    and a.ClaimWeatherCond in ('Snow', 'Rain', 'Storm', 'Avalanche', 'Tornado');

INSERT INTO TABLE BatchProcHist
VALUES ('ClaimWeatherView_S', from_unixtime(unix_timestamp()));
  1. 删除临时表:
Drop Table MaxTable;
Drop Table MaxTbl1;

7.2 TeenageViolView_S 视图创建

该视图用于找出未处理的、过去 12 个月内至少有 2 次严重程度为 1 的违规记录的青少年司机。步骤如下:
1. 获取批量视图和速度层视图的最新创建时间:

Create table MaxTable as
select ViewName, max(CreatedAt) as MaxDate
from BatchProcHist
group by ViewName
having ViewName = 'TeenageViolView';

Insert into MaxTable
select ViewName, max(CreatedAt)
from BatchProcHist
group by ViewName
having ViewName = 'TeenageViolView_S';
  1. 确定最新的创建时间:
Create table MaxTbl1 as
select max(MaxDate) as MaxDate
from MaxTable;
  1. 获取未处理的记录并创建临时表:
Create table TeenageVioltemp11 as
Select a.PolicyOwnerId, a.ViolationSeverity
from PO_Drv_Hist a, MaxTbl1 b
where a.LastModified > b.MaxDate;

Create table TeenageVioltemp12 as
Select PolicyOwnerId, count(ViolationSeverity) as TotalViolations
from TeenageVioltemp11
where (datediff(current_date, add_months(to_date(ViolationDate), 12)) <= 0)
    and (ViolationSeverity = 1)
group by PolicyOwnerId
having count(ViolationSeverity) > 2;
  1. 创建速度层视图并写入历史表:
Create table TeenageViolView_S as
Select T.PolicyOwnerId, T.TotalViolations
from TeenageVioltemp12 T, PolicyMaster P
where T.PolicyOwnerId = P.PolicyOwnerId
    and (datediff(current_date, add_months(P.PolicyOwnerDOB, 228)) <= 0);

INSERT INTO TABLE BatchProcHist
VALUES ('TeenageViolView_S', from_unixtime(unix_timestamp()));
  1. 删除临时表:
Drop Table MaxTable;
Drop Table MaxTbl1;
Drop Table TeenageVioltemp11;
Drop Table TeenageVioltemp12;

7.3 AdultViolView_S 视图创建

此视图用于筛选出未处理的、过去 12 个月内至少有 3 次严重程度为 1 的违规记录的成年司机。步骤如下:
1. 获取批量视图和速度层视图的最新创建时间:

Create table MaxTable as
select ViewName, max(CreatedAt) as MaxDate
from BatchProcHist
group by ViewName
having ViewName = 'AdultViolView';

Insert into MaxTable
select ViewName, max(CreatedAt)
from BatchProcHist
group by ViewName
having ViewName = 'AdultViolView_S';
  1. 确定最新的创建时间:
Create table MaxTbl1 as
select max(MaxDate) as MaxDate
from MaxTable;
  1. 获取未处理的记录并创建临时表:
Create table Violtemp11 as
Select a.PolicyOwnerId, a.ViolationSeverity
from PO_Drv_Hist a, MaxTbl1 b
where a.LastModified > b.MaxDate;

Create table Violtemp12 as
Select PolicyOwnerId, count(ViolationSeverity) as TotalViolations
from Violtemp11
where (datediff(current_date, add_months(to_date(ViolationDate), 12)) <= 0)
    and (ViolationSeverity = 1)
group by PolicyOwnerId
having count(ViolationSeverity) > 3;
  1. 创建速度层视图并写入历史表:
Create table AdultViolView_S as
Select T.PolicyOwnerId, T.TotalViolations
from Violtemp12 T, PolicyMaster P
where T.PolicyOwnerId = P.PolicyOwnerId
    and (datediff(add_months(P.PolicyOwnerDOB, 228), current_date) < 0);

INSERT INTO TABLE BatchProcHist
VALUES ('AdultViolView_S', from_unixtime(unix_timestamp()));
  1. 删除临时表:
Drop Table MaxTable;
Drop Table MaxTbl1;
Drop Table Violtemp11;
Drop Table Violtemp12;

以下是速度层视图创建的 mermaid 流程图:

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px

    A[获取批量视图最新时间]:::process --> B[获取速度层视图最新时间]:::process
    B --> C[确定最新时间]:::process
    C --> D[获取未处理记录]:::process
    D --> E[创建临时表]:::process
    E --> F[创建速度层视图]:::process
    F --> G[写入历史表]:::process
    G --> H[删除临时表]:::process

8. 总结

8.1 架构优势

通过 Lambda 架构实现保险理赔欺诈检测,结合了批量层、服务层和速度层的优势。批量层对数据进行全面处理和分析,生成稳定的视图;服务层提供快速的数据访问,减少查询延迟;速度层则能及时处理未被批量层处理的数据,保证数据的实时性。

8.2 操作要点

  • 数据处理 :在数据处理过程中,要注意数据的反规范化、分区和增量处理,以提高数据处理效率。
  • 视图创建 :创建批量视图和速度层视图时,要合理使用临时表,并及时删除,避免脚本出错。
  • 表空间管理 :使用 Splout SQL 管理表空间时,要根据键列合理设计表空间,并可通过添加索引提高查询性能。

8.3 整体流程回顾

层次 操作内容
批量层 数据反规范化 -> 创建批量视图 -> 存储在 HDFS 和 Hive 中
服务层 使用 Splout SQL 部署表空间 -> 添加索引 -> 部署表空间到分布式数据库
速度层 确定未处理数据 -> 增量处理 -> 创建速度层视图

通过以上架构和操作流程,能够有效地对保险理赔数据进行管理和分析,及时发现可能的欺诈行为,为保险公司的风险控制提供有力支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值