本文约6800字,建议阅读15+分钟
本文为你分享腾讯的姜亚松老师的图计算框架Angel Graph。
[ 导读 ] 图计算在智能风控场景有着广泛的应用,但是图的规模和计算的复杂度往往会制约落地的使用,目前各家机构都开展了图计算框架的自研,来解决实际使用中的性能瓶颈。今天我们邀请了腾讯的姜亚松老师来分享腾讯的图计算框架Angel Graph,本次分享题目为 Angel Graph 图计算及在智能风控中的应用,主要介绍:
Angel 图计算框架
节点度量算法原理与优化
社区发现算法原理与性能优化
图计算在智能风控中的应用实践
01、Angel 图计算框架
从数据类型中可以看到,风控中存在很多种图数据。比如:在点赞关注评论时构建的社交网络、在转账发红包时构成的移动支付网络、在购买浏览收藏时构成的电商购物网络,以及电话短信构成的通信网络。
从算法风控的角度,对一个人的分析可分为4个角度:第一是属性,比如性别年龄等;第二是背景,比如教育宗教;第三是行为,比如购物行为、通信行为、下单行为等;最后是关系维度,比如好友关系、家庭关系。
我们以关系的角度进一步分析,可以对一个人从单一的视角扩展为全局的视角。首先在分析的过程中,不仅可以使用这个人自身的数据,还可使用与这个人有联系的其他人的数据辅助进行评估;另一方面,关系数据的造假成本较高,因为风控是一个对抗性比较强的场景,因为造假成本高所以真实性更可靠;第三是关系数据的覆盖率较高,比如用户的属性信息往往是缺失的,但是用户的关系往往更全面从而有更好的召回的效果;最后是借助关系网络进行团伙挖掘,能够反哺原有算法效果,达到性能提升。
我们从图的四个不同粒度对图数据进行了划分。
首先是线的粒度,这种是节点的邻居对其产生的影响,可以是一跳的直接邻居,也可以是二跳三跳的间接邻居,这一块的主要应用方式是基于邻居用户进行特征拟合,来进行风险评估。
第二块是子图结构的一些指标,比如局部聚集系数,一些motif的局部结构特征。
另外是整图的一些属性,通常评估节点在整图中的一些重要性程度,比如常见的pagerank算法、节点的中介中心性、K-core、closeness等。这两部分通常作为节点特征补充到机器学习模型中弥补单点分析的不足。
最后的维度是社区发现的问题,将图中的节点进行社区的划分得到较小的团伙,进一步去分析团伙自身的属性等信息,这一块常用于反欺诈团伙作案的挖掘。但是在工业应用中数据量是非常大的,往往会面临十亿节点,百亿或千亿边的规模,对这么大规模的数据实现一种多种类和高性能的图算法会带来较大挑战。
因此我们希望构建一个高性能、高可靠、易用的、完备的图计算框架,也就是这里介绍的Angel Graph框架。
在高性能方面:能够支持十亿级节点、千亿级边的传统图挖掘算法,以及百亿边的图表示学习和图神经网络算法需求。
在高可靠方面:可运行于多任务共享集群以及公有云环境,具备高效容错恢复机制。
在易用性方面:端到端训练,与大数据生态结合,对其中的算子和函数进行抽象复用,新算法以及用户二次开发都容易得到支持。
在完备性方面:支持图挖掘、图表示、图神经网络算法,具备图计算与图学习能力。
整个框架的结构分为多层,下层支持多种数据类型的读取,同时支持Yarn和K8s的资源调度;在上层我们对常用的图抽象算子进行了实现以及常用的图算法进行支持;中间层就是我们的Angel分布式图计算平台,可以分为两部分,上半部分是参数服务器PS,提供了模型的划分和同步异步方式,以及对常用数据结构和模型访问方式进行了抽象,可以与下面计算单元进行交互;下半部分计算单元集成了多种图切分方式,以及实现了对传统Spark图计算框架和Pytorch的图神经网络算法的支持,所以在整个框架下可以运行多种类型的图算法。
下面具体介绍我们实现传统图挖掘算法的Spark on Angel框架。
整个框架分为上下两部分,上半部分使用Angel PS来管理需要频繁更新和随机访问的数据,比如模型参数、消息等,同时支持良好的容错方式,在某些节点出错时能进行快速的恢复;下面是基于spark的基础框架,使用Spark RDD管理只读和不需要随机读取的数据(图结构),在spark的每个executor中引入batch的批量计算的方式,进行流量控制,来保证资源不足时也能正常运行。
02、节点度量算法原理与优化
下面介绍节点度量算法的相关应用。
在风控场景中每个节点的重要性是不同的,也就是常说的二八定律,而且往往需要对一些重要节点进行特殊的处理;重要成员可以分为两种类型,一种是一些“领袖”型成员,一般处于操控、组织、分发位置,可通过其反向发现“从属”成员,另一种类似“黑产中介”,行为隐蔽,自身行为信息无害,检测难度大,但是可以通过图结构的特征检测其为中介的一些行为;第三个是一些特殊的子图结构,在风控中一些特定行为模式体现为特殊子图结构,识别子图结构可应用于用户行为分析与预测。
下面看一下Angel Graph已经实现的一些节点度量的算法,比如常见的出入度的计算、betweeness中介中心性作为桥梁的重要性程度、pagerank表征节点在全图的重要性程度以及K-core算法等,这些算法都已经在开源框架中实现了,而且支持了大规模的工业应用。
再来看一下motif的应用。
Motif是一种在网络中反复出现,且具有一定辨识能力的子结构,最早出现在生物学上,用来表述蛋白质网络里蛋白之间的一些连接和相互作用模式。但是由于在工业中数据量比较大,在计算motif时通常只考虑三个节点的motif结构,这里我们设定了33种motif结构,边之间都是有向的关系,将其中部分结构对应在资金交易网络中,可以发现一些一阶付款、一阶收款、资金汇聚、资金发散等模式。我们可以通过有向的motif结构映射到具体的物理含义上,实际使用时可以将节点适配的33种结构的个数形成33维的特征,然后进行特征拼接来进行模型的训练和预测,同时还能兼顾很好的可解释性。
下面介绍节点度量算法在实现时的一些优化的处理。
首先是超级节点优化的过程,超级节点就是有少数节点的度数非常高,比如微信公众号有些大V的粉丝数特别多,金融支付网络中可能最高的度数大于50万,通信网络中一些客服号码可能达到上亿的量级。超级节点带来的问题,一方面与PS(参数服务器)交互时传输信息量过大会影响通信效率,另一方面在使用Spark 分区时存在不均衡,某些分区计算压力较大,影响任务总体运行。
对于超级节点的处理,我们使用了两种方案:
第一种方案,是基于缓存的方案缓存超级节点的邻居,从而避免每次都要从参数服务器重新进行数据拉取,超级节点的选取基于重要性的度量,选择重要性靠前的节点,比如无向图采用节点的度数作为重要性,有向图采用入度和出度的比值作为重要性,实际使用中我们按照重要性前20%的节点进行缓存,能将性能提升一倍。
第二种方案,采用数据压缩的方式,压缩后邻接表大小由1.1T降低为0.6T,通信效率提升30%。
下面介绍节点度量实现时在通信优化的相关工作。
在实际场景中数据量比较大,因此我们申请的PS资源和Spark Executor的资源都比较大,这样会造成连接数爆炸的问题,比如每个executor会与很多PS进行连接,如果是有m个Executor n个PS带来的连接数是n×m,通信耗时占比非常高。第二个问题是计算存储分离的问题,这个在很多场景会带来额外的网络通信开销,数据的存储是放在PS上,计算都是在executor上,所以会带来这样的问题。
我们针对性的解决如下:
①剪枝
Data Partitions按PS上数据分布重新分区,使PS和executor通信量级从1对m降低至1对k(k<m),从而减少通信的连接。
②计算下推
使用PS Function定制最优化计算流程,将数据下推至模型处(PS)进行计算,在ps端得到计算结果,只将计算结果返回,从而减少网络传输数据量。
03、社区发现算法原理与优化
先看一下团伙欺诈的相关背景,团伙欺诈呈现越来越高的趋势,同时组织化与地域化也非常明显,团伙核心成员数可以达到百万到千万的量级,地域上基本集中在少数几个省份和城市中;手段也比较多样、破坏性较大,产业链、作案手段多元,如:黑中介、逾期团、羊毛党、黄牛党、水军等,与此同时一旦产生会造成巨大损失且难以补救。
下面介绍社区发现相关的概念。
社区的概念可以用常说的“人以类聚,物以群分”来理解,复杂网络中的节点往往也呈现出集群特性,社会网络中总是存在熟人圈、朋友圈、兴趣圈,其中每个成员都认识其他部分成员。集群程度的意义是网络集团化的程度;这是一种网络的内聚倾向。
在学术界和工业界比较标准的社区定义:社区结构是复杂网络节点集合的若干子集,每个子集内部的节点之间的连接相对紧密,而不同子集的节点之间的边相对稀疏。
我们可以跟进一步看一下社区发现背后隐藏的一些社会学定义,就是一个同质性特性,这是社交网络最本质的一个特性,表明在一个社交网络中,节点周围的邻居往往与中心节点非常接近,而造成同质性的根源是:影响(social influence)和选择(selection),其中影响的含义是“人们会因为需要和朋友们保持一致而改变自己的行为(教唆)”,选择的含义是“人们倾向于在和他们相似的人之间形成友谊(组团)”。
下面介绍社区发现中重要的概念——弱连通分量。
在无向图中,从一个顶点到达另一顶点,若存在至少一条路径,则称这两个顶点是连通的;如果无向图任意两个顶点之间都能够连通,则称此无向图为连通图。若无向图不是连通图,但图中存在某个子图符合连通图的性质,则称该子图为连通分量。无向图中的连通分量常被称作弱连通分量(CC)。
上面示例中整个无向图可以分成三个无向的连通子图。关于弱连通分量的分布式实现:
①每轮迭代时各节点发送自己的连通id给连通id比自身大的邻居;
②Aggregator则从中找出最小的连通id作为当前节点新的连通id;
③如此循环迭代,直到无消息可发;
④迭代轮次跟图的直径正相关,一般而言,图的直径越大,迭代轮次也越多。
下面介绍在我们实际应用弱连通分量相关的异步优化。
从理论上,异步拉取发生的次数越多,那么迭代的轮次也会大幅度减少,总体的运行时间也会减少。PS的更新是分批次的,每一个Batch都进行一次PS的update,那么在并行的其它worker上执行拉取PS操作的时候就有可能拉取到最新更新的节点值,相当于提前拉取了同步的连通算法中下一轮的值。通过这样的方式,可以减少迭代轮次。然后通过增加Batch批次数量来更新PS的的方式,虽然可以刺激异步拉取的发生,但是同时也增加了与PS通信的次数,原本每个partition进行一次通信,现在每个partition要进行BatchNum次通信。这个 batchNum 的定义等于分区内节点的个数除以batchSize的大小。
在实际应用中需要控制batchNum来降低通信开销,使得运行时间和迭代次数得到平衡。从图中的测试结果也可以看出,运行耗时与batchNum的关系并不是一个线性递减的过程,而是需要在相对合理的范围才能达到整体耗时较少。原因是:batchSize较小时,频繁的通信开销,导致运行时间长;而batchSize较大时,退化为无batchSize的方式,迭代的次数相对也会比较高。
第二个的优化操作是一个折叠优化的方式。
我们知道在单机的连通分量查找中是有个非常高效的算法并查集,如果将比较大的图压缩到一个单机可计算的规模再使用并查集,那么可以想像加速效果是显著的。
具体操作上当我们执行了有限次迭代(比如3轮)分布式迭代之后,我们在大图上的每个点都有一个新的连通id,而且有许多不同的顶点已经拥有了相同的连通id,将拥有相同连通id的节点看作同一个节点,将两端节点连通id不同的边组织成一张以连通id为节点标签的新的图进行图的压缩,最后在压缩图上进行单机的连通图查找。我们在三个不同量级的数据集上进行测试,可以看到带来了很大的性能提升。
下面介绍下指标优化类的社区发现算法,顾名思义就是通过定义一个指标,然后在社区发现过程中以这个指标为最终优化的目标进行迭代的计算。
虽然指标有很多种定义,但是基本的流程是相似的,如下:
①初始化,将每个节点划分在不同的社区中;
②逐一选择各个节点,根据公式计算将它划分到它的邻居社区中得到的Modularity增益。如果最大增益大于0,则将它划分到对应的邻居社区;否则,保持归属于原社区;
③重复步骤2,直到节点的社区不再发生变化;
④构建新图。新图中的点代表上一阶段产生的不同社区,边的权重为两个社区中所有节点对的边权重之和。重复步骤2,直到获得最大的Modularity值。
下面介绍社区发现中一个典型的指标——模块度。
模块度是社区发现中一个最重要的概念,其有两个作用,一个是在优化过程中作为优化的指标,另外是在社区发现的评估过程中作为评估的指标,最终的模块度值越高以表征社区发现的结果越好。我们看一下模块度一个本质的定义,它是基于这样一个假设:随机网络不具有社区结构;保持节点度不变,节点之间随机产生边,若图G具有社区结构,社区内部边占总边数的比例应该大于随机情况下的该比例的期望;实际社区内部边与期望的差越大,说明网络与随机网络的差异越大,即网络越具有社区结构。
在我们实际应用中,模块度是有个分辨率受限的问题,基于模块度最优化方法寻找到的社区划分倾向于将小社区合并成更大的社区,从而不能发现网络中较小的社区,如果社区的规模小于根号2m,是不能用模块度进行社区发现优化的。
为了解决这个问题,有很多学者提出了一些解决方案,其基本的方式是相似的,也就是对模块度的定义做一些相应的改造,比如设置一些超参数等,但是参数最合适的值是较难设置的,还有一些处理是自动调节的方式。
下面介绍我们指标优化类社区发现算法实现过程中的一些优化策略。
首先是并行优化的策略,这是在相比传统串行方式,并行处理天然的会遇到的问题:分布式下并行更新社区id,引发社区震荡影响算法效果。比如我们用AB两节点加1条边的简单结构作为示意,在并行计算时,B选用A的社区作为归属社区,与此同时A又会选用B的社区作为归属社区,导致迭代过程中A和B永远不会属于同一社区导致反复震荡的问题。
在并行中这种现象会经常发生,我们提出了两种解决方案:
①概率更新,节点以一定概率维持原有社区。
②社区合并,使用(节点id,社区id)为边,进行连通子图计算,将同一子图内社区id更新为同一id,达到社区合并的操作,来解决社区震荡的问题。
在效果上,我们Angel相比GraphX可以达到效果和性能的双重提升。
关于指标优化类社区发现算法引入先验知识场景的一个优化。
关于先验知识引入的场景:业务中存在先验知识,预先知道哪些顶点不在同一社区,哪些顶点一定在同一个社区的情况。比如,设置负边代表两个节点一定不能存在社区关系,正边代表两个节点一定要在一个社区,在社区发现过程中要考虑正边和负边的属性关系。
在分布式场景想解决这样的问题,需要引入一个本地计算,节点在更新自身社区时,必须同时感知其他节点社区信息,更新时需要采用本地串行计算。解决步骤如下:
第一步:将整体图切分为子图,计算节点相关属性;
第二步:利用第一步得到的子图进行串行Louvain算法计算,在计算过程中考虑节点的正负边属性信息。
实现这个步骤也会带来这样一些问题:
一是连通子图切分,单子图规模过大的问题,比如单个连通子图可能占整体数据量的20%,呈现超大子图现象(整体节点数10亿,最大连通子图节点数2亿),造成数据严重倾斜、甚至任务失败。我们的解决方案使用并行Louvain算法对图进行切分,将得到的社区当做子图。虽然louvain切分是一种有损的方式,但是本身社区之间的连边是稀疏的,可以控制损失尽可能小,同时可控制Louvain算法最大迭代次数控制子图相对规模,来适配不同类型数据。
第二个问题是图上的冗余信息过多的问题,比如在实际数据中,图中共有47亿边,其中有38亿负边,占比80.8%,产生大量的shuffle,且在worker进行串行计算时保存大量本地信息,造成内存巨大开销。我们的解决方案是删除冗余的负边信息,比如负边两端节点中至少有一个节点度为1、负边两端节点不在同一子图内的情况可以提前进行过滤删除。使用这种优化的策略,可以使得正负边预测的准确率提升10~20%,同时时间开销能减少70~90%。
04、图计算在智能风控中的应用实践
最后介绍我们图计算在金融风控中一些应用的案例。
1. 节点度量在金融支付中异常检测的应用
关于金融支付网络的特点,数据海量:十亿节点,接近万亿笔交易[年];有向用户交易有三种关系:收款,付款,收付款;不仅需要效果好还需要可解释性。在这个应用中引入前面提到的motif计算,可以表示出节点在不同的motif范式出现的个数,以此作为特征向量来用于风控模型。
我们可以进一步看到在转账商户、多级分销、刷单等不同范式下,motif分布的模式是具有明显差异性的。与此同时我们对比了支付网络和社交网络在motif模式的差异性,在社交网络中三角结构比较容易出现,而在转账网络中三角模式出现的就比较少。我们也可以定量地看到motif在一些业务模型上的效果,相比baseline,引入motif作为特征后单模型的AUC性能可以提升1.28%,而且查看TOP20的重要特征,发现有6个就是motif相关的特征。
2. 社区发现在异常团伙挖掘中的应用
我们使用支付网络和相应的社交网络来构图,与此同时,我们会引入正边和负边的信息,筛选一些大于阈值的边进行构造,将整个大图且分为多个子图。通过对比标准的louvian算法和在Angel中实现的louvian算法,我们可以将正负边的识别率提升11%~22%。
当我们将大图切分成多个社区时,可以进一步细粒度的查看每个团伙的信息,比如找到的某个社区人数27,异常用户19人,异常浓度70.37%,虽然剩下的8人没有被设别,但是通过社区可以判定异常的嫌疑较大,以及可以进一步判断社区中哪些节点是一些关键的中介节点等。
最后,关于Angel的开源社区所沉淀的一些算法,以及使用中需要的一些问题,欢迎大家扫码或访问链接。
05、精彩问答
Q1:louvian算法中社区震荡问题?
A1:关于社区震荡主要是在并行实现的算法时会发生,而在原有的串行算法上是不会存在社区震荡的。所以我们引入了两种解决方案:一是概率更新,让节点以一定概率更新为邻近社区;二是社区合并,将连通子图的所有节点共享为同一个社区。
Q2:关于本次介绍算法的代码获取?
A2:所有算法都是在Angel社区中开源提供的。
今天的分享就到这里,谢谢大家。
分享嘉宾
姜亚松 博士
腾讯 高级算法工程师
姜亚松,博士毕业于中国科学院声学研究所,专业信号与信息处理,历任中科院声学所助理研究员、融360高级算法工程师,现于腾讯担任高级算法工程师,主要研究方向为大规模图算法研究与应用、超大规模图计算加速与优化。
编辑:于腾凯
校对:杨学俊