14

关联网络在金融风控中的应用实践

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzI1NDc5MzIxMw%3D%3D&%3Bmid=2247490448&%3Bidx=1&%3Bsn=dbb15a97d04eb06829ae886e4abdb6cb
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

导读

异常检测、设备指纹和关联网络是大数据风控实践中的重要技术手段。在金融风控实践中,欺诈者往往呈现出团伙作案或高聚集性等特征,关联网络作为将数据建立关联的垂直类知识图谱,是识别身份伪装、贷款中介等欺诈行为非常有效的手段。

背景

在金融产品的各个环节中,均存在一定程度的欺诈风险。 通过对欺诈案例的分析我们发现,由于受到资源限制等因素,欺诈用户表现出团伙聚集、多设备、多银行卡共用等现象; 同时,存在贷款中介盗用或者骗用他人信息进行集中骗贷的现象。 而上述这些特征,仅通过申请人这一视角很难发现。 因此我们引入关联网络,从个人视角扩展到网络视角,借助关联计算、图算法等手段,在授信、放款、还款等业务环节,提供线上图谱反欺诈能力。

此外,关联网络对于失联修复,智能获客方面也有很好的表现。

fQVnMn.png!mobile

图1 金融产品过程中的典型欺诈表现

金融关联网络介绍

关联网络是将现实中的关联信息通过数据抽取和转换, 以图的形式进行存储、加工和计算, 并提供图查询和图分析等能力的垂直类知识图谱。 在金融业务中,存在大量关联关系,如图 2 所示,包括用户与用户,用户与设备,用户与地址,用户与销售等。 我们将这些实体和关系进行了梳理,共提炼了常用实体类型 40 多种,常用关系 70 多种,总数据量近百亿。

f6ZJneF.png!mobile

图2  关联关系示意图

实体: 用户id、设备id、手机号、身份证、银行卡、地址和车商等。

关系: 亲属关系、联系人关系、好友关系、实名认证、手机绑定和家庭住址等。

在金融关联网络的构建和应用过程中,会面临以下几个比较关键的问题:

1.当将众多现实中的业务概念、实体、关系表达成关联网络的数据结构时,比如用户 A 与用户 B 共用设备既可以用“用户实体  +  设备实体  +  用户使用设备关系”进行表达;也可以使用“用户实体  +  共用设备关系”进行表达,如何定义一套合理的 schema ,既保证不复杂,又可以支持上层业务灵活扩展?

2.用户在企业各个业务线上的行为数据较多,既有金融场景的行为,包括实名认证、申请贷款、还款等,也有找工作、找房、找家政等日常生活轨迹。如何保证这些数据能够准确、高效的写入关联网络,提供线上实时风控应用?

3.图查询、图计算本身就是一种耗时较高的计算,随着与用户关联的实体或关系越来越多,遍历深度的增加使得耗时呈指数级增长,如何保证线上服务的快速响应以及计算结果的准确?

关联网络技术架构

目前,业界针对关联网络主要基于关系型数据库或图数据库进行建设。利用关系型数据库,如MySql,这种方式适用于关系结构相对简单的情况,对于复杂的图计算及图查询实现困难,且对于两度以上的查询效率较为低下,难以满足实际生产的需要;利用图数据库,常用的图形数据库有Neo4j,JanusGraph,OrientDB,HugeGraph等,利用Neo4j图数据库,这种方式对于图计算和图查询有很好的支持,但是对于社区版Neo4j,缺少集群及横向扩展能力,对于数据规模较大的场景,难以满足要求。

我们主要基于图数据库的本身特性以及企业技术架构平台的优势进行综合考虑,选型了基于JanusGraph打造金融的关联网络。本文不对各图数据库的性能对比情况进行详细介绍,相关的文章比较多,我们把主要精力放在关联网络在金融业务线具体落地实践的介绍上。

针对我们金融风控业务的实际情况,我们分四层建设金融关联网络,分别是存储层、计算层、服务层和应用层,如图3所示。

BbAnYbY.png!mobile

3 关联网络技术架构

存储层: 我们选择了开源的 JanusGraph 作为图引擎,存储后端采用 HBase ,外部索引使用 Elasticsearch ,数据导入借助 kafka ,采用MySql对业务级的 schema 进行定义和封装,结合企业架构部自研的 kv 存储组件 wtable 缓存预计算的图特征或热度关系,以提供线上毫秒级的响应。

计算层: 分为基于 OLAP 的图计算和图分析,以及基于 OLTP 场景的图查询。本文侧重于介绍 OLTP 方面的建设, OLAP 不做细致介绍。由于 JanusGraph 原生集成 Apache TinkerPop 图技术栈,我们主要基于 Gremlin 图查询语言设计查询业务逻辑和接口。

服务层: 我们将图数据库的管理操作、在线图查询和计算、图特征和图模型的预计算结果进行封装,为应用层提供标准化的基础服务接口。

应用层: 直接面向金融风控的业务场景,提供包括风险预测、团伙挖掘、一致性核验、关联反查和失联修复等功能。

图实例构建

在金融风控场景中,我们采用了属性图来对图数据进行建模,实践中采用两个三元组来表达这种知识结构:

实体 - 关系 - 实体 ,例如“用户 U 使用身份证 C 通过实名认证”即可表达为 U – bind – C ,其中 U 为用户实体, C 为身份证实体, bind 描述了两者构成绑定关系。实际业务中,用户实名认证身份证、绑定手机、绑定银行卡,用户使用设备登录,申请人填写的联系电话等都可以梳理成类似这样的实体 - 关系 - 实体三元组。

实体 - 属性 - 属性值 ,例如“用户 U 性别为男”即可表达为  U – sex –  男,其中 U 为用户实体, sex 为用户实体中的性别属性,“男”表示该用户的性别取值为男性。属性是对实体的描述,同时也可用作对实体进行查询过滤的条件。

接下来我们讨论如何在关联网络中将这些知识表达成计算机可以识别的结构。

1. schema

我们将schema分成两种类型,一种是纯图schema,如实体、关系、属性的固有图结构定义,另一种是业务级别的schema,如年龄的取值范围(1~99岁)等。

a)图数据结构schema

针对图数据结构的schema,我们直接采用JanusGraph的schema设计,对图数据结构定义如下:

  • Vertex Label: 节点类型,表示实体类型,用于标记节点的分组,多个节点可以有相同的标签。

  • Vertex: 节点/顶点,描述具体实体,每个实体都有一个唯一的 id, 每个实体都有零个,一个或多个属性。

  • Edge Label: 边类型,表示关系类型。用于标记关系的类型,多个关系可以有相同的关系类型

  • Edge 边,描述具体关系。每个关系也都有零个,一个或多个属性。

  • Property 属性,具体的属性。属性是一个键值对( key/value ),用于为节点或关系提供信息。

  • Property Key 属性类型,支持 single/list/set  三种值类型。

另外, JanusGraph 还提供了一些图数据结构级的约束,用于保障数据的准确性。对于点及边可以建立一定的约束关系。例如,针对点约束, JanusGraph 提供了唯一索引,支持基于属性的唯一性控制,这样可以避免点数据重复;对于边约束, JanusGraph 提供了如下几种约束关系: multisimplemany2oneone2manyone2one ,可以用于保障不同要求的关系约束。

b)   业务级schema

针对业务级 schema ,主要是对属性取值的约束,图数据库本身缺少属性值的约束能力,因此我们引入MySql数据库,存储业务中的约束要求。

bi22mme.png!mobile

  业务约束表示例  

对属性取值的约束我们使用三种方式:

  • 范围约束:年龄取值范围为1~99

  • 枚举值约束:性别仅能取值为“男”或者“女”

  • 正则表达式匹配:11位手机号码校验

在数据写入过程中,通过以上业务级规则的校验,保证数据的业务正确性。

2. 多图实例

在金融风控业务中,有两种常见的关联网络应用场景,一种是多实体关联,如在车金融场景中,需要通过手机号或身份证等信息查找对应订单,再通过订单中的申请人、联系人电话、销售、车商等信息继续进行层层递进查询关联分析,帮助识别隐藏的欺诈特征;另一种是只关心单一实体,多账号关联就是一种典型的场景,在风控分析过程中,我们需要将企业各个业务线的多种用户账号进行关联,综合各个业务线的数据进行风控判断。显然,前者存在多种实体的关联关系使用,包括用户-手机关系,用户-销售关系,销售-车商关系等,这是异构图的使用场景;后者则只关心同一种实体之间构成关联,即账号-账号关系,这是典型的同构图使用场景。所谓同构图是指图中仅有一种实体和一种关系,而异构图则指图中的实体类型或关系类型不只一种。

22aquyb.png!mobile

图4 同构图和异构图示例

显然,仅仅在图实例中存储同构图,会丢失一些信息,或者在关系上冗余比较复杂的信息才能达到异构图的效果;而仅仅存储异构图,也能满足同构图的使用功能需求,但是在查询和计算效率上要低很多,尤其是现在主流的图算法大多是建立在同构图基础上,这也为图算法在关联网络中的应用提供更多便利。另外,在一些特殊场景,如idmapping场景,也可以建立专有的子图实例,从而提供更好的线上应用效率和效果。基于此,我们根据典型的应用场景构建了多图实例,在构图成本和线上效率间取得平衡。

在工程实践中,我们在RPC服务层对JanusGraph的访问进行了封装,来管理多图实例。将每张图实例的schema及连接信息存储在MySql中,在服务启动时获取并初始化,使用ThreadLocal进行读写隔离。

数据导入与更新

完成图schema准备后,接下来比较重要且耗时较长的工作就是数据的导入。数据导入需要对各种结构化、半结构化和非结构化数据进行清洗、抽取、加工和融合,并按照既定schema进行校验入图。本文中我们不对数据的具体处理过程进行介绍。只侧重说明如何保障数据的写入效率及质量。

金融关联网络当前全量数据近百亿,单日增量超千万,针对不同的数据写入场景,需要使用不同的数据更新策略。我们采用离线全量、T+1增量和实时更新相结合的方式进行。其中离线全量用于图谱初始化,T+1增量针对实时性要求不高的数据,实时更新则针对需要同步更新入图的数据。在数据质量方面,由于数据量庞大,逐条数据校验显然是不现实的,因此我们需要建立合理的数据校验及修复机制,保障数据质量。

1. 导入方案

为了简化入图的复杂流程及保证在线离线数据的一致性,我们采用统一的基于kafka的数据导入方案,如图5所示。

JfqUv2M.png!mobile

图5 基于kafka的数据导入方案

由于实体和关系在图数据库中存储的结构不一样,关系是作为实体的“对象属性”进行存储的,因此我们针对实体数据导入和关系数据导入设计了不同的导入流程。

a)实体数据导入

下面以用户实体为例,简述实体导入过程。实体数据消息体我们采用如下json格式定义:

{"graphName":"network","propertyMap":{"productid":"1","real_name":"张三","create_time":"2019-12-02 15:25:40.0","user_id":"11111111"},"label":"user","messageType":"entity"}

IfuiQrj.png!mobile

图6 实体导入流程

针对实体节点,数据的导入流程一般经过数据解析、实体schema校验、实体存在性校验,写入更新等步骤,如图6所示,其中一些关键技术点如下:

  • 校验未定义属性是为了防止数据源中有未在图数据库schema中定义的属性,避免数据写入失败。

  • 节点id既可以使用JanusGraph自动生成的id作为全局唯一id,也可以使用业务中的唯一id,但是考虑到我们实际业务中的节点类型较多,保证全局唯一性成本较高,因此我们采用前者。

  • 描述用户实体的唯一主键user_id是通过实体的“数据属性”写入的,并通过唯一索引进行保证。在实际使用中发现,创建点这一步是JanusGraph分配点id的过程,这一步是不会对索引唯一性进行校验的,在写入点属性时,才会进行唯一性校验,并且抛出异常,而这个异常仅仅针对user_id这个属性写入失败,其他非唯一约束的属性还是写入成功了,这将导致图中产生了一个没有user_id属性的用户节点,影响数据准确性。为规避此问题,我们采用先读后写的方式,通过user_id读取判断不存在对应点时,再进行点的新增。

  • 关系数据导入

下面以用户与用户之间的好友关系为例,简述关系导入过程,关系数据消息体我们采用如下json格式定义:

 {"graphName":"network","label":"is_friend","messageType":"relation","propertyMap":
{"productid":"3","resource":"E000101"},"source":
{"label":"user","propertyMap":{"user_id":"11111111"},"target":
{"label":"user","propertyMap":{"user_id":"22222222"}}

AnYNfqa.png!mobile图7 关系导入流程

关系数据的导入流程一般经过数据解析、关系schema校验、起始节点存在性校验,目的节点存在性校验,边约束性校验,写入更新等步骤,如图7所示,其中一些关键技术点如下:

  • 与节点导入类似,校验未定义属性是为了防止数据源中有未在图数据库schema中定义的属性,避免数据写入失败。

  • 如果边存在相关性约束,也需要采用先读后写的方式。

  • 对于边约束,我们主要使用simple和many2one。使用simple进行唯一性强约束,例如用户对身份证的绑定关系。many2one是节点可以有多条该类型入边,但是只能有一条出边,例如父子关系、车与车商的关系等。

2. 数据质量保障

我们主要从约束校验、数据质量监控、数据修复等角度对数据质量进行保障。

约束校验: 我们基于schema层的图约束及业务约束对数据的准确性进行校验,详见数据的导入流程。当多台服务节点同时往图数据库写入数据时,会带来更新数据的不一致问题,这块我们主要使用本地锁和JanusGraph提供的分布式锁进行协调,来保证并发情况下的数据写入的正确性。

数据质量监控: 对数据准确性的验证,我们通过以下两种方式进行:

  • 快速抽验: 通过SparkGraphComputer进行各实体、关系数量的统计,随机抽取部分原始数据与入图数据进行比对。

  • 全量监控: 定期通过SparkGremlin计算相关监控指标,如增量入图的实体、关系数据量分布,重点属性分布等,观察监控指标的异常变化。

数据 修复: 通过dump图数据库的数据,离线筛查异常数据,针对这部分数据进行删除或更新操作。

3. 导入效率

由于每天入图的数据量较大,除了要保障数据质量,数据导入的效率也是需要重点关注的问题。我们根据JanusGraph的性能情况,对kafka设置了多个partition,并根据实体id将相同实体数据路由至同一个partition,在服务器处理时,相同实体的数据合并在同一个JanusGraph事务内提交,减少锁冲突,提升导入效率。

通过前述的数据导入方式,完全满足日常实时数据及T+1增量数据更新的需求。但是对于大批量数据的导入,尤其对于关系数据必须通过分布式锁保障并发问题,一次数十亿关系数据的导入,需要周级别的时间消耗,这是业务不能接受的。因此,针对大批量数据导入的场景,我们专门进行了优化。     

JanusGraph底层使用的存储是HBase,每个rowkey对应一个节点,节点的属性和关系数据存储在column及cell中。对于图schema,及图本身的配置信息,我们依然通过JanusGraph提供的api进行创建。优化后方案其实是离线实现JanusGraph数据导入流程,具体步骤如下:首先生成图的全局id,然后把源数据与全局id关联并根据属性个数预留索引全局id索引值,其次就是根据JanusGraph序列化方式生成序列化数据并把序列化后的数据做二级排序,最后按照JanusGraph的数据格式要求,我们将数据直接格式化为HFile文件,然后将HFile文件加载到指定的HBase表的数据目录下,在HBase表中生效,在亿级别的数据下大幅度提升批量数据导入速度,如图8所示 ,可以看到在10亿级的数据量下,优化后导入效率比优化前的效率提升了12.5倍,但两种方案在小批量数据下的导入效率差异并不明显。

QBjQVji.png!mobile

图8 优化前后耗时对比  

由于和kafka数据导入系统采用了独立的两种方式,数据一致性及准确性风险有所提升,需要在离线写入HFile数据时,进行细致的逻辑验证和测试。

图应用及优化

完成图结构构建及数据写入工作后,在应用层,关联网络提供了准入防控、关联分析和失联修复等能力:

准入防控: 在授信、放款阶段,我们会利用申请人的实体、关系等信息,在关联网络中进行图特征挖掘,并计算候选人的关联风险得分,给出风险等级提示和欺诈判断,效果展示如下图9所示。

NBRnAbJ.png!mobile

图9 用户风险报告

关联分析: 利用关联网络,对未被拦截的用户进行风险表现分析,如下图10所示,通过历史数据进行回溯验证,更新风控策略。

VVjy6n3.png!mobile

图10 用户的关联分析

失联修复 :利用各个业务线的数据,通过关联网络进行数据打通,扩展用户数据,进行逾期用户的失联修复。

我们在服务层统一对各应用的逻辑进行抽象和封装,而各应用都离不开对底层图数据的查询,我们将涉及到的图数据库查询归为三类:关联查询,路径查询,属性查询。另外,还有一种特殊的图查询,查询节点所属的连通子图,比如查询账号所属的idmapping集合。

1. 关联查询及索引

所谓关联查询,是通过属性值条件查询节点,包括精确查询及范围查询。精确查询,我们利用JanusGraph提供的组合索引提高效率,组合索引通过HBase本身实现,速度快,但是仅支持精确匹配。范围查询我们通过混合索引优化查询效率,混合索引通过Elasticsearch实现,例如地理位置范围查询、时间范围查询等,但是混合索引相较组合索引效率略低。

在实际业务中,我们将所有需要进行关联查询的实体属性均创建了组合索引。如身份证实体的身份证号属性。为需要进行范围查询的属性创建了混合索引。但是,随着索引创建的增多,会影响数据写入效率。因此,我们只针对常用的查询属性构建索引。

值得注意的是,如果数据导入前创建索引,索引提交后可以立即生效,后续导入的数据将可以直接通过索引进行查询。如果库中已经存在了一些数据,图数据库需要对存量数据进行索引构建,这要消耗不少的时间。提前对数据索引进行设计考虑,可以节约大量的构建索引时间。

2. 路径查询

22mAryy.png!mobile

图11 路径查询

在进行图关联分析时,我们经常需要判断“用户a”和“用户b”是否存在可达路径,并计算二者距离。一种比较容易想到的方法是,从起始点“用户a”出发进行广度遍历,直到找到“用户b”为止。

当节点的度数较高或遍历路径较长时,查询响应时间较长,无法满足实际业务需求。因此我们对其做出改进,从起点和终点出发,并行向中间进行广度遍历查找,直到查询到交点为止。

当节点的度数很高时,这种两端并行遍历的方式响应时间也较长,我们针对度数很高的节点,采用剪枝算法进行优化,在我们的场景中使用1/(N*logN)(N取图中节点最大度数)的概率进行剪枝。经过优化,4度以内的路径查询可以控制到1秒内返回。

3. 属性查询

图中针对属性的查询,主要是针对实体属性的查询。根据使用用途,实体属性可以划分为两种类型:一种用于描述实体的基础信息,本文称为基础属性,一般用于实体的关联查询;另一种是计算的画像特征,本文称为画像属性,一般用于关联分析或建模使用。基础属性一般数量较少,我们将其作为实体的数据属性直接存储在图数据库中,而画像属性会随着业务的迭代逐渐增多,我们将其存储在外部的特征中心,例如,挖掘的用户社团标签,我们会将其作为画像标签,以k-v形式直接存储在特征中心的用户特征列表中,避免大量读写画像标签影响图数据库的性能。

4. idmapping

为提升风控效果,除了金融业务线本身的数据外,企业各个业务线的行为数据也是识别用户风险行为的重要补充,包括买房、买车、找工作、找家政等,而不同源的数据的引入,首先需要解决的就是各系统之间用户数据打通的问题,我们采用了idmapping技术。在离线场景,我们可以通过连通子图等算法进行计算。但在我们的场景中,需要实时计算用户的idmapping结果,我们直接采用并查集算法解决这一问题。

首先我们通过离线预计算的方式,利用并查集算法,生成一系列连通集合,我们规定集合中所有元素的id(元素id由实体id+实体类型组成)最小值作为集合的唯一标识(本文称为集合id)。在计算过程中,需要注意:

我们使用Map结构实现并查集,并发更新集合时要保证数据的正确性;

并查集中“查”步骤需要进行路径压缩,将当前查询节点的路径上的所有节点的父节点指向集合id对应的节点;

并查集生成后,将得到一系列(元素id,集合id)数据,通过该数据,生成(集合id, 元素idList)连通集合数据,将这两类数据以k-v形式存储在wtable中。

离线完成全量数据加工后,通过在线系统进行增量数据更新:对新输入的关系对(id1,id2),分别查询其对应的集合id,根据查询结果分别处理:

  • 均不存在集合id:将两点组成新的集合,生成集合id,写入wtable

  • 其中一个账号存在集合id:将另一账号加入该集合,新增其与该集合id关系

  • 两个不同的集合id:将两个集合id合并,选取集合id小的作为新的集合id,并更新相应数据

  • 两个相同的集合id:无需变化

注意的是,在并发场景下,需要在写数据时保证数据效率和数据质量,这里我们使用锁保证数据的正确 性。

完成idmapping数据的引入后,在关联网络查询过程中,根据业务需要,首先通过请求的账号元素id,从wtable中查询到关联的所有元素id,再进行后续关联查询。

展望与规划

随着金融业务的发展,关联网络在业务中的应用深度和广度也会随之增加,我们会进一步优化相应的功能,包括关联分析、一致性核验、关联风险报告等,将关联网络的工程能力同大数据计算、图算法进行有效结合,提升关联网络在金融风控中的整体应用效果。

参考文献:

1. JanusGraph官方文档

作者简介

高思宇: 金融公司数据智能部资深开发工程师,负责金融公司关联网络建设与开发 。

张建军: 金融公司数据智能部资深数据开发工程师,负责金融公司风控数据建设与开发。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK