金融智能风控系统演进开发实践
分享嘉宾:贺鹏 融360 高级技术经理
编辑整理:安然
出品平台:DataFunTalk
导读:在我们的风控工作中,风控系统解决的问题是什么?比如我们常见的监管要求、反欺诈、信用风险、黑产对抗、支付安全等。风控系统就是在大数据支撑下,根据风控专家经验制定规则策略、以及机器学习/深度学习/AI领域建立的模型运算,对当前的业务风险进行全面的评估,并给出决策结果的一套系统。
今天会和大家分享下融360金融风控系统从搭建到重构以及商业化的演进过程,并分享如何解决遇到的问题与挑战。主要分为三个阶段:
第一阶段:风控服务演进
第二阶段:性能可靠性保障
第三阶段:商业化演进
01
第一阶段:风控服务演进
1. 早期风控系统的问题
我们早期的的风控系统是一个大的单体系统,如图所示,包括规则决策、流程配置、模型计算、内外部数据对接和特征加工计算,最后接入到各个业务系统中。
早期风控系统面临众多的痛点:首先需求相似度高且比较零散,比如经常要调整某个阈值;上线周期长,从改代码到测试上线,最快也要一天才能完成;代码维护困难,耦合和重复严重,公司多条业务线都各自维护一套单体;频繁的上线发布导致每周都会有2-3次生产故障;越往后随着业务量的增加,则会面临越多的挑战。
总体来说,我们面临的问题主要是:
变更效率低,周期长
需求琐碎,重复单调
代码耦合严重
线上故障率高
无法满足多业务、多场景需求
2. 重构抽象
那么针对于早期风控系统问题,应该如何解决?基本思路是对系统做重构。那么如何保障重构后系统的合理性,有效拆分限界上下文?经过业务分析和抽象建模,我们将风控系统归纳为六个要素依次是:规则、决策、流程、模型、特征、数据。
下面针对这些抽象依次展开分析:
① 规则抽象
首先我们举个例子说下什么是规则?
规则1:
如果年龄小于18,输出“未成年人”
如果年龄大于等于18,输出“成年人”
写过代码的都知道这个很简单,加个if/else 可以很快去满足这个需求,这就是硬编码的方式:
但是当我需要调整时候,比如将18岁调整到23岁,就需要修改代码上线。有没有办法让规则逻辑与代码做分离,并且可视化的进行配置呢?这里就需要对规则进行抽象,将其中元素模版数据化,如下图:
这里左侧的特征、运算符、阈值构成基本的规则表达式,也就是模式;右侧的输出即为我们的决策结果;最后将其抽象成一个可执行的文本,可以用程序执行。如下图所示:
可执行文本就是我们风控领域的 DSL(领域特定语言),以后编写规则就可以像写 SQL 一样写一条 DSL 文本,这样就做到了规则编写与程序代码分离。
如何解析这个 DSL 文本,基本思路可以通过抽象语法树来做,当然可以借助一些开源组件来执行,比如:Drools/Groovy/QlExpress/eval/goevaluate等。
② 组合决策
有了基本的规则抽象解析后,我们后续可以做更多的组合决策,比如规则集(决策集),决策树,决策矩阵,决策表,运算表达式等。
多规则组合起来就是规则集,规则集额外做的工作就是解决决策的冲突,不同的决策结果可以分不同等级,规则集的结果就等于触发规则中优先级最高的决策结果。
决策树是一种树形结构,拆分来看也是多个规则的执行,它与规则集的差别在于,它的上一次模式匹配后会选择路径,从而影响下一次模式匹配,进行决策出不同的结果。
决策矩阵就是横轴和竖轴分别进行模式匹配,并由二者的结果取交集来输出决策结果。
③ 流程编排
有了不同的规则组合,进一步我们希望进行更复杂的流程编排,并引入分支流程。总体编排形式分为顺序编排和分支编排,以及他们的组合编排。顺序编排就是把规则和决策串联起来,并加入开始和结束节点。而分支编排又可以分为按流量编排和按条件编排。按流量进行分支,就是我们常说的 Abtest,在风控决策引擎中也叫冠军挑战者。通过编排后就构成了我们的决策流。
那么决策流如何进行解析执行呢?通常有 pipeline 和 rete 两类模式。
pipeline基本思想,所有特征和每一步执行结果(衍生特征)会存储到全局对象,下游可以依赖使用,整体流程呈现管道形式,决策流执行路径可以拉成一条直线。它的优点是实现简单方便,缺点是效率并不高,需要一个节点一个节点去依次匹配。
所以会出现rete算法来实现更高效的匹配,它的核心思想是根据规则库构建有效的模式匹配网络并记录匹配过程中节点的状态,从而得到有效的规则解析和较高的性能,是一种空间换时间的思路。它的优点是执行效率高,缺点是实现复杂,执行过程中消耗较多的系统资源,需要提前衍生特征(有些情况下是不能提前计算的,比如有些数据成本不希望提前发生)。
不同的模式会有不同的适用场景,要根据自己的生产情况来定,我们的生产就是采用 pipeline的模式。
④ 可视化
规则,决策,流程组合在一起就构成了风控领域的核心系统——风控决策引擎系统。那么我们希望给风控专家提供一个可视化的操作界面,可以自由调整决策流和规则决策,而不用每次依赖工程团队开发代码实现。
这里我们划分了自然语言、关系型数据库和领域特定语言(DSL)。自然语言提供给风控专家更易解读的可视化界面和自然语言描述,其相应的数据存储使用了关系型数据库来落地,最后通过发布时将数据转换为领域特定语言(DSL),由系统识别执行 DSL。
⑤ 模型
相比于规则的局限性和可突破性,模型提供了风控决策更多元化的能力。模型主要是利用已有数据,通过机器学习、深度学习算法构建模式,并用来预测结果,为风控提供授信和反欺诈能力,整个模型是分为在线预测部分和离线训练部分组成。
在线预测部分,也叫模型引擎,通过将数据特征代入训练好的模型(特征+算法+参数)中来执行预测,并将预测结果反馈给决策引擎,用于进一步的决策输出。
离线训练部分,我们打造了一个机器学习平台,包括特征工程(特征挖掘),样本处理,训练建模,模型回溯以及效果评估,最后通过模型部署到生产中。离线训练和回溯所依赖的数据,又是源自在线预测时所积累的数据(导入离线数据仓库),所以模型训练是需要时间来积累一定数据的。整体在线预测系统和离线训练系统完成了模型生命周期的闭环。
⑥ 数据特征
决策引擎和模型引擎都依赖于我们的数据特征(也有叫指标或变量),那么接下来我们的就来看数据如何加工成特征,并且能尽量做到系统自动化、可视化,在我们内部叫特征引擎系统。
补充说明:决策引擎和模型引擎依赖的特征还是有区别的,决策引擎依赖的特征一般具有业务含义,比如借贷次数,是否命中黑名单,而且种类有限;模型引擎依赖特征就是一个变量,不具可解释性,而且维度超多,理论上可以衍生几千、几万维特征。所以在开发这两种特征上还是有些区别,但总的来说都是通过特征引擎这个系统来实现的。
特征数据一般来自于两方面,内部客户提交的数据(二方数据),外部合作机构提供的 API 数据(三方数据)。首先我们要进行数据接入(API 或数据库对接);然后对接入的数据做数据加工计算(衍生特征),简单的计算处理逻辑比如通过 jsonpath 获取接口返回的 data 值,复杂的需要做一些聚合、过滤、填充等。
特征引擎的工作原理如图所示,先接收要获取的特征列表;分析特征列表直接和间接依赖的所有数据源(比如特征f1->f5 直接或间接依赖于数据源 d1,d2,d3);然后依次调用数据源,调用时可通过 DAG 分析先调用依赖的数据源,再将无依赖关系的数据源并发调用(这里先调用d3再并发调用d1,d2);最后按逻辑解析出所有特征。
3. 总结风控系统架构
以上就是我们从单体到微服务过程中的整体思考和服务拆分演进过程,下面给出我们的风控总体架构图:
从上到下分别是风控接入层、风控决策层和风控平台层:
业务应用场景会有不同业务线,不同决策场景,对风控系统有不同的需求,对输出结果和系统响应差别很大,所以风控接入层主要用于隔离屏蔽业务相关性的。
风控决策层就是我们的风控中台,它由决策引擎、模型引擎、特征引擎三大引擎构成,是通用的风控能力,保障通用性,与业务解耦是主要设计目标。
风控平台层支撑上游风控中台,包括可视化的决策管理后台,用于做规则流程配置以及效果监控;机器学习平台用于训练回溯模型;特征计算平台赋予多种计算能力;数据平台提供风控大数据基础。
通过最新架构调整,我们达成了重构的目标:完全由风控专家实现分钟级调整发布,前台、中台、后台职责清晰分工明确,并满足了多条业务线、多种不同场景的风控需求。
02
第二阶段:性能可靠性
1. 新问题产生
随着业务发展,新的问题逐渐产生,我们总结了我们的遇到的几类问题,当然欢迎大家在文末留言一起讨论~
首先决策调用量增加,业务沉淀的数据增多,无论是数量还是维度上,对我们系统性能和稳定性提出更高的挑战。
其次,不同场景对决策时效性和数据准确性上是有差异的。比如前筛场景要快速决策,秒级拿结果,而由于某个特征缺失造成的影响可以忽略;而用户授信场景,希望可以拿到更准的结果,如果遇到数据调用失败希望重试一次,可接受的决策时间也更久一些(分钟级);当然还有一些场景是希望既快又准的,鱼和熊掌是否能兼得?
2. 决策时效性VS准确性
① 区分时效性
从时效性,我们将决策场景分为实时决策场景和准实时决策场景。针对不同的时效性,我们在系统处理上也是差异化来做,同步 or 异步是由上文提到的风控接入层来实现的。
实时决策场景定义秒级决策,同步响应,保障性能优先;同时在处理数据调用特征失败时会进行忽略,甚至如果决策超时会有兜底的降级策略;当然决策流配置上和数据特征选择上也要考虑简单高效。
准实时场景定义为分钟级决策,一般是异步化响应结果,保障准确率优先;在数据调用失败时会重试,甚至有些关键数据接口失败要开启授信熔断等待恢复,这些都是保障准确率的有效手段。
② 性能治理
在性能治理上可以考虑决策流配置、资源配给和区分调度三个方面。决策流冗长可以做拆分精简,合并规则及节点,去除无效规则等;所有系统服务多实例分布式部署,并做好容量评估,保障系统资源充足;根据决策时效不同,将系统部署拆分,分离长短任务,避免长任务调度时间过长对短任务造成影响。
3. 特征计算
其实在整个决策流执行链路中,耗时最严重的就是特征计算部分。那么我们有哪些特征计算的方式,来满足我们更苛刻的性能需求?
① 实时计算
实时计算是我们最基础的特征加工方式,就是在决策引擎调用特征引擎时,特征引擎从数据源拉取数据并完成计算返回结果,它是一种读时计算的模式,优点是数据实时准确,工程复杂度低,缺点就是性能并不高。
② 预计算
预计算就是我们对特征预先加工计算,当决策引擎调用时,直接返回上一次计算的结果。它是一种写时计算模式,通过提前计算来削峰填谷,利用空间换时间提升性能。在性能上有更好的表现,但其也有弊端,就是数据的准确性。如果提前算好特征,但之后数据又发生了变化,那么数据就不准了,所以什么时机做预计算就是关键。
早期我们实践了触发式预计算,由业务系统在某个节点触发预计算程序完成计算,这种方式业务侵入性大,并且触发的时机并不好掌控。
最新实践是通过 CDC (change data capture)捕获数据变化,发送到 Kafka,通过流式计算引擎 (Flink / 自研)方式来完成预计算,并将结果存储到高速缓存中。当然其也有局限性,比如预计算未完成时发生了特征调用,可能将无法拿到数据,所以选择这种方式也会评估数据的变化频率。
③ 批计算
对于数据变化不敏感的数据,进行离线批计算将是更好的方式,既能保障了数据更加精准(无实时数据的噪音),又能提高决策效率,但其缺点可能会缺失最新的数据。
④ 融合计算
融合计算结合了离线计算和实时计算的优点,将t-1的离线数据计算出的特征再去和当天的实时数据做进一步的计算,从而得出完整的特征。由于 t-1 的数据使用的是特征结果,所以性能会提高,但相应数据精度会差一些,比如不能在全时间范围内进行去重。
⑤ 总结
不同的计算模式有其各自的优势和局限性,所以在使用时也是根据不同的场景,做了不同的探索和使用。
4. 可靠性--全方位监控体系
为了保障系统和决策的可靠性,我们做了全方位的监控体系,包括业务层监控、应用层监控、系统层监控和调用链监控。
下面三层监控比较常见,一般生产系统都会去做,这里重点说下业务层监控。
首先我们做了一个实时业务监控大盘(通过流式计算引擎做到实时查看),我们的风控专家,在后台进行策略调整后,可以直接观测到调整效果,如果发现问题,可以快速调整回滚。另外我们加入了报警机制,对规则命中率,特征缺失率,决策通过率等进行阈值配置报警。
同时我们将生产数据克隆下来,通过流量回放的方式辅助线下测试回归。通过模型回溯来评估模型性能,开发迭代新模型。
03
第三阶段:商业化输出
通过我们两年的生产打磨,已经打造出一套高可靠、可扩展、良好架构的风控系统,我们希望能够为商业赋能,将系统对外输出。我们商业化之路主要探索了本地化部署、SASS 服务、整体风控能力输出等方面,所以有了“魔方”这套系统。
在数字化业务落地实施中,场景、流量、风控、科技 几方面也是我们探索的方向。我们的产品也是从易用性、安全性、灵活性、易接入和普适性考虑,希望能够给大家提供更好的服务。
今天的分享就到这里,谢谢大家,欢迎大家在留言区讨论留言。
在文末分享、点赞、在看,给个3连击呗~
分享嘉宾:
社群推荐:
关于我们:
🧐分享、点赞、在看,给个3连击呗!👇