风控逻辑利器---规则引擎

  • 前言

  • 规则引擎的定义

  • 规则引擎的执行

  • 转转风控规则引擎

  • 总结

前言

风控的职责是控制业务的风险。在识别风险过程中,要根据大量的用户行为和用户信息去做逻辑判断,最终给出决策结果。在决策过程中,大量的逻辑判断需要开发和维护,如果以传统的方式去开发和维护,需要付出巨大的时间成本并且隐藏着毁灭性的事故风险。所以将业务代码和复杂的逻辑代码剥离显得迫在眉睫。

规则引擎的定义

规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。

下图是规则引擎的组成部分:

1)特征集合:表示当前传入的数据(例如:用户对象zzuser)

2)条件:逻辑判断

3)规则:对特征进行逻辑判断,得出结论

4)规则集:多条规则组合成规则集

规则引擎推理方式分为两种:

正向链接推理:这是一种基于“数据驱动”的形式,基于用户的行为信息和基本信息,得出结论。

反向链接推理:这是一种基于“目标驱动”的推理形式,与正向链接相反,以假设的结论出发,推断用户的哪些行为信息和基本信息符合假设的结论。

规则引擎的执行

规则引擎的执行方式分为解释执行、编译执行和自定义执行。

  • 解释执行

    表达式逐条转换成目标代码,逐条运行。

  • 编译执行

    表达式一次性动态的编译成字节码并执行。

  • 自定义执行

    早期在没有引入表达式引擎的时候,就是通过自定义实现的表达式解析。

    举个例子:

    特征a、特征b、特征c => 求特征d

    d = (a+b)/ c 这是一个简单的四则运算表达式。

    这个表达式对于人的思维方式来说非常的简单,但是计算机识别起来就非常的困难。所以要将常规的表达式转换成计算机方便计算的表达式(逆波兰表达式)。

    上面的表达式转换成逆波兰表达式为:ab+c/

这样计算机就可以比较简单的求出表达式的值。

逆波兰表达式的转换算法感兴趣的可以自行百度。

转转风控规则引擎

转转风控规则引擎是一种正向链接推理的规则引擎,以数据为驱动,去推断相应的结论。比如说,业务要识别违禁品,可以根据图片模型分数大于0.9来推断出用户违规。

特 征: 模型分数

操作符号: 大于

阈 值: 0.9

这三部分构成了一个规则。

转转规则引擎分三个发展阶段:

  • 第一阶段:硬编码阶段,此阶段所有的规则都是通过代码写死的,维护性和扩展性极差。

  • 第二阶段:规则引擎阶段,通过抽象业务,开发规则配置平台,可以非常方便的运营规则,增加了规则的机动性。

    下图是规则运行的一个用例图:

  • 特征(按类型划分)

    用户特征 : 用户的昵称、年龄、注册时间等

    商品特征 : 商品内容、标题等

    订单特征 : 订单金额、订单的品类等

  • 操作符号

    规则引擎操作符:大于、小于、等于、敏感词匹配、用户标记等

  • 结果

    命中规则 或者 不命中规则

    下图是实际的一个规则配置(商品的当前价格是否小于等于30000,价格单位:分):

  • 第三阶段:完善特征工程阶段,减少特征的开发上线。

  • 表达式引擎的引入

    1) 表达式引擎的选择

    Aviator Fel
    执行速度
    jar包的大小 70kB 200kB
    社区活跃度 非常活跃 一般
    执行方式 动态编译/解释执行 动态编译/解释执行

    两者性能差不多,最终选择了aviator,因为aviator社区活跃度和jar包大小要优于Fel。

    2) aviator表达式功能简介

    (1) 支持绝大多数运算操作符,包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(=~)、三元表达式(?:)

    (2) 支持操作符优先级和括号强制设定优先级。

    (3) 支持赋值。

    (4) 逻辑运算符支持短路运算。

    (5) 支持丰富类型,例如nil、整数和浮点数、字符串、正则表达式、日期、变量等,支持自动类型转换。

    (6) 支持 lambda 匿名函数和闭包。

    (7) 内置一套强大的常用函数库。

    (8) 可自定义函数,易于扩展。

    (9) 可重载操作符。

    (10) 支持大数运算(BigInteger)和高精度运算(BigDecimal)。

    (11) 小巧并性能优秀

    3) aviator表达式引擎在特征工程的实践

    (1) 基本特征取值

    比如说,订单价格特征(orderFeture.price)、商品标题特征(infoFeature.title)、用户昵称特征(userFeature.nickname)。(注:orderFeture,infoFeature,userFeature是系统中的一个实体对象)

    (2) 特征的基本运算

    比如说,已有手机分类商品数特征(infoFeature.phoneTotalCount)、全部商品总数特征(infoFeature.totalInfoCount),想要一个手机商品数在商品总数中的占比特征,就可以直接通过四则运算获取到:long(infoFeature.phoneTotalCount)*100/long(infoFeature.totalInfoCount)

    (3) 内置函数

    aviator提供了大量的内置函数,可以通过它的内置函数获取想要的配置结果。比如说,商品标题长度特征string.length(infoFeature.title),应用了求字符串长度的函数string.length。

    (4) 自定义函数

    aviator除了内置的函数,还支持自定义函数,可以根据需求自定义函数。比如说,想通过配置获取redis里的值,就可以开发一个获取redis的函数(函数名字是jodisFeature)。

    jodisFeature('price_median', infoFeature.cateChildId)。这个特征配置就是为了获取redis key为price_median的值。特征的代表的含义是:分类价格的中位数,当然这些数据已经提前计算好存储在redis里面了。

    (5) Lambda表达式

    个人感觉Lambda表达式的引入是一个质的飞跃,这样就可以操作集合,只要有源数据,就可以转换出任何想要的特征。比如说,已有订单流水list(orderFeature.orderFlow),通过lambda表达式就可以转换成特征(发货时间到确认收货时间):seq.get(map(filter(orderFeature.orderFlow,lambda(x)->(x.status==5)end),lambda(y)->y.latestOpTime end),0)- order.deliverTime。总之,表达式引擎还有各种各样的玩法,感兴趣的可以自行尝试。

  • 特征数据源

    引入表达式引擎之后,可以通过各种函数转换获取想要的特征,特征的转换依赖数据源。由于数据源的获取需要开发上线,给特征配置化带来极大的不便。因此,数据源的获取成了特征配置的瓶颈。数据源哪里来呢?两种方式:一种是业务请求携带的参数数据,另一种是调用服务方获取的数据。第一种对应的解决方案是特征映射,第二种对应的解决方案是接口调用配置化。

    1) 特征映射

    特征映射是为了将业务方的参数转换成需要的特征。业务方通过两种方式调用,一种是同步调用,另一种是异步调用(异步调用采用的是消息队列的形式)。为了将业务的数据源统一收拢,跟业务约定将参数放到map里面,规则需要什么数据就可以通过map去获取。为了方便特征配置,开发了一个获取业务参数的自定义函数(函数名:paramget)。例子:paramget('uid')代表的意思就是获取用户的uid。

    在实际开发过程中,MQ异步调用的方式遇到了一些困难。由于各个业务系统的MQ消息体字段名称不一致,导致配置兼容比较多。比如说,同样都是uid的特征,有的业务MQ中用uid字段表示,有的用userId字段表示。为了控制字段兼容对规则的侵入性,在MQ消息和风控特征数据源之间做了一层映射,这层映射解决了字段对应偏差的问题。

#### 2) 接口调用配置化

接口调用配置化是为了解决风控调用业务获取数据源的问题,每个接口只要传入相应的参数,就会返回相应的结果。这个问题可以抽象概括,只需要根据不同的业务方配置不同的参数,就可以获取相应的数据源。比如说,我们新接入一个zzuser的接口,通过配置表就可以获取用户unionid(微信id)关联的账户数。下图是配置表的信息:

![](https://upload-images.jianshu.io/upload_images/28339355-49e5ac9a428790b0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


配置表里包含:服务名、类的全限定名、接口名、接口参数、接口参数值

返回结果:{"code":0,"body":3}

图中表达式中,13代表了配置表的id=13,commonfeature函数获取getCountByUnionId接口的返回信息({"code":0,"body":3}),jsongain函数获取json数据中key是“body“的信息 3。

由于服务间的通信是rpc调用的,要实现服务间通用的规则调用需要底层的支持。正好,架构部提供了服务的泛化调用,完美地解决了通用的调用问题。

总结

本文介绍了规则引擎的定义和执行方式,并且详细介绍了规则引擎在风控的落地。利用规则引擎辅助风控控制业务风险,实现业务数据源可配置、风控逻辑可配置,极大的降低了开发规则和维护规则的成本。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容