决策树和规则引擎研究
当今复杂的互联网环境下,我们的系统时时刻刻都暴露在风险(刷单党、羊毛党)的攻击之中,如果我们不采取有效防御措施,那么这些风险就会对业务造成很大的损失。
用公式可以表达出风控规则和风险数据的系统关系:z=f(x, y),f 为系统风控规则,x 为系统实时输入风险数据,y 为系统的事实数据。
而风控系统最底层和重要的业务核心就是规则引擎和大数据计算引擎。今天主要研究下规则引擎。
什么是规则引擎
对于研发同学来说
在没有规则引擎的时代,有些逻辑比较复杂的业务,只有不断的增添if-else去满足我们这个复杂的业务场景,对于当时的开发者来说还好,自己做的理解起来比较快,对于后面接手的同学一看到处都是if-else,简直是痛不欲生,令人崩溃。虽然if-else的写法上可以通过一些模式去优化,比如使用策略模式,或者使用一些注解进行扩展点优化,这样的确可以解决一部分代码不清晰的问题,但是依然无法解决开发缓慢、后期升级拓展困难等问题。 在风控系统中,因为风控的逻辑在不断的发生一个改变,如果我们在代码中去写死,那么发生一个改变就改一下代码,测试一遍,再发布上线一次,这明显是不能接受的。所以我们需要规则引擎去改变这个现状,通过高效可靠的方式去做这些业务规则的改变。
对于运营同学来说
以前的开发模式是运营人员提出规则,然后让开发人员做出相对应的业务开发,到底这个最后开发出来的业务规则是否和运营人员所提出来的是否一致,需要通过大量的测试去进行验证。调整后,每条线路都要保证测试到位。而开发人员理解业务很容易和运营人员的提出的业务有偏差,就会导致开发成本上升。有了规则引擎之后,就可以有下面几点提升:
- 运营人员独立配置业务规则,开发人员无需理解,让运营人员的规则和真正的实际情况一致。
- 增加业务的透明程度,运营人员配置了之后其他运营人员也能够知道。
- 规则高效改动和上线,一般运营人员提出需求之后都是希望能尽快上线,但是之前都需要有代码开发,项目上线等环节,现在运营人员配置好了之后即配即用。
- 减少运营人员和开发人员的依赖。
概念
规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。
很多的规则形成规则集,规则集组成一颗决策树,决策树是规则引擎核心的判断逻辑。
决策树
决策树(decision tree)是一种的分类和回归方法。
决策树学习包括三个步骤:特征选择、决策树的生成和决策树的剪枝。
决策树由节点和有向边组成。节点有两种类型:内部节点(圆)和叶节点(正方形)。内部节点表示一个特征或者属性。叶节点表示特征或者属性的一个类别。
1.png
决策树与if-then规则
决策树其实就是if-then规则的集合,if-then的程序一般具有较好的可解释性。
从根节点到叶节点的每一条路径都可以看做是一个规则,每一个内部节点对应着一个条件,叶节点对应着规则的结论。这样的规则具有互斥和完备性,从根节点到叶节点的每一条路径代表了一个实例,并且这个实例只能在这条路径上。
举个简单的例子说明:
“如果年龄小于18岁,那么就拒绝处理”
对这条规则进行抽象建模成条件表达式:特征 (年龄) 运算符(小于) 阈值(18) ---> 触发结果(拒绝)
这里产生几个概念:特征feature、运算符operator、阈值value,这三要素构成条件表达式condition,加上触发结果decision,组成了规则rule的基础元素。
进一步举例:
“如果年龄小于18岁或年龄大于60岁,那么就拒绝处理”
条件表达式1:特征 (年龄) 运算符(小于) 阈值(18)
条件表达式2:特征 (年龄) 运算符(大于) 阈值(60)
逻辑关系:(或)
触发结果:(拒绝) 任何一个为false即为拒绝
这里多了逻辑关系,规则可由多个条件表达式组成,对表达式结果再进行逻辑运算。
再举个例子:
“如果职业是学生,那么就拒绝处理”
条件表达式:特征(职业) 运算符(等于) 阈值(学生)触发结果(拒绝)
其他可选阈值:老师、打工人、老板
“如果一分钟内订单数量大于五,那么就拒绝创建订单“
条件表达式:特征(一分钟内订单数量)运算符(大于) 阈值(5)触发结果 (拒绝)
这里有了不同的特征类型,一般特征类型总结如下
数值型,对应运算符可以有 >、<、=、>=、<=、==、!=,值必须为数字。
枚举型,对应运算符只有==,值为字符串数组[...]{"学生","老师","打工人","老板"}
字符串型,对应运算符有= 、 != 、like 、in 、contain, 值为字符串或字符串数组。
触发结果:可以为“通过”、“拒绝”、“记录”、“告警”、“异常”等,任意自定义结果。
对于一些名单类特征,比如规则是“命中黑名单则触发拒绝”,将命中结果抽象为枚举型特征,对应条件表达式就是:命中黑名单 等于 true/false。
这里做个总结:一条规则的执行,先通过数据(身份证号)计算出特征(年龄),然后带入条件表达式(年龄<18)计算,并对多个表达式结果做逻辑运算,最终根据逻辑运算决定是否触发结果。
决策树的局限性有哪些?
决策树的主要问题是容易形成过拟合. 如果我们通过各种剪枝和条件限制, 虽然可以避免过拟合, 但是会牺牲特征的有效性.
决策树发展
第一个决策树算法: CLS (Concept Learning System)
使决策树受到关注、成为机器学习主流技术的算法: ID3
最常用的决策树算法: C4.5
可以用于回归任务的决策树算法: CART (Classification and Regression Tree
基于决策树的最强大算法: RF (Random Forest)
构建决策树的三个步骤
(1)特征选择:选取有较强分类能力的特征。
(2)决策树生成:典型的算法有 ID3 和 C4.5, 它们生成决策树过程相似, ID3 是采用信息增益作为特征选择度量, 而 C4.5 采用信息增益比率
(3)决策树剪枝:剪枝原因是决策树生成算法生成的树对训练数据的预测很准确, 但是对于未知数据分类很差, 这就产生了过拟合(分类不准)的现象。涉及算法有CART算法
决策树的基本概念和算法
熵和信息熵
熵:物理意义是体系混乱程度的度量
信息熵:表示事物不确定性的度量标准, 可以根据数学中的概率计算, 出现的概率就大, 出现的机会就多, 不确定性就小(信息熵小)
信息熵的计算:
image.png
类似n次独立重复是实验概率求和
总结:变量的不确定性越大, 熵也就越大。 熵越小, 信息的纯度越高。
决策树归纳算法 - ID3算法
目的:选择属性判断节点
'信息增益':整个数据集信息熵与当前节点信息熵的差
imageID3算法的案例:
以下是一份关于购买电脑的统计信息
image.png
1)首先计算出整个数据集的信息熵:一共14条数据,最终买电脑数据9条,不买5条
image.png
(2)然后计算年龄的信息熵:一共14条数据,youth5条(yes:2 no:3),middle_aged4条(yes:4),senior5条(yes:3 no:2)
image.png
(3)然后计算age信息增益:
image.png
(4)通过类似计算的方法,分别计算出income,student,credit_rating的信息增益
Gain(income) = 0.029, Gain(student) = 0.151, Gain(credit_rating)=0.048
选择信息增益最大的作为第一个节点,这里选择age作为第一个节点
然后按age进行分割后,再对分割后的数据进行递归(1)(2)(3)(4)步即可完成整个决策树的建立
划分结束标志为: 子集中只有一个类别标签, 停止划分
例如:对age=youth的数据进行递归(1)~(4)步骤
Info(D) = -2/5log2(2/5) + -3/5log2(3/5),
age=youth :Info(income(age=youth))=2/5(-2/2log2(2/4) - 0)+ 1/5(-1/1log2(1/1)-0) +2/5(-1/2log2(1/2)-1/2log2(1/2))
age=youth :Info(student(age=youth))=...
age=youth :Info(credit(age=youth))=...
依次递归即可
id3算法的缺陷:
1.ID3没有考虑连续特征
2.ID3采用信息增益大的特征优先建立决策树的节点。在相同条件下,取值比较多的特征比取值少的特征信息增益大。
3.ID3算法对于缺失值的情况没有做考虑
4.没有考虑过拟合的问题
决策树归纳算法 - C4.5算法
C4.5算法属于ID3算法的延伸,使用信息增益率来选则属性
特征 A 对数据集 D 的信息增益: Gain(A) = Info(D)-Info_A(D)
信息增益率: Gainr(A) =Gain(A) /H(A) : 其中 H(A)为 A 的熵
H(A)的计算公式:
image.png
理解:
由于在分类问题困难时候, 也就是在训练数据集经验熵(总体的 Info(D)值)
大的时候, 信息增益值会偏大(Info(D)值偏大), 如果训练数据集经验熵小的时候,
信息增益会偏小, 这时候也可以通过信息增益率来矫正这一问题。
规则引擎
一句话描述:即输入的数据匹配对应的规则、规则引擎处理、最终输出等。
因为所谓的规则引擎框架核心即两点:
1.规则与数据分离;
2.输入、处理、输出。
常用规则引擎的选型
目前的规则引擎系统中,使用较多的开源规则引擎是Drools,另外还有商用的规则管理系统BRMS是ILOG JRules。
Drools
Drools是一个基于Java的开源规则引擎,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。
目前版本是5.0.1,Drools从5.0后分为四个模块:
- Drools Guvnor (BRMS/BPMS)
- Drools Expert (rule engine)
- Drools Flow (process/workflow)
- Drools Fusion (cep/temporal reasoning)
Ilog JRules
Ilog Jrules是完整的业务规则管理系统(BRMS),它提供了对整个企业业务规则进行建模、编写、测试、部署和维护所必需的所有工具。
Ilog Jrules主要包括以下4个组件:
- Rule Studio(RS) 面向开发人员使用的开发环境,用于规则的建模和编写
- Rule Scenario Manager 规则测试工具
- Rule Team Server(RTS) 基于Web的管理环境,面向业务人员使用,用于规则发布、管理、存储
- Rule Execution Server(RES) 面向运维人员使用,用于规则执行、监控
这两款规则引擎设计和实现都比较复杂,学习成本高,适用于大型应用系统。
Easy Rules
Easy Rules是我偶然间看到的一个规则引擎实现,相比Drools等企业级规则引擎,Easy Rules的应用非常简单,学习成本低,容易上手。
下面重点介绍这款轻量级的规则引擎 Easy Rules。
轻量级规则引擎Easy Rules
GitHub easy rules官方文档 https://github.com/j-easy/easy-rules
Easy Rules提供以下功能:
- 轻量级框架和易于学习的API
- 基于POJO的开发
- 通过高效的抽象来定义业务规则并轻松应用它们
- 支持创建复合规则
我们可以通过扩展Easy Rules提供的Rule interface来定义规则,或者通过注解,定义自己的规则类。
QLExpress
由阿里的电商业务规则、表达式(布尔组合)、特殊数学公式计算(高精度)、语法分析、脚本二次定制等强需求而设计的一门动态脚本引擎解析工具。
java语言实现,不依赖任何外部脚本引擎解析
支持宏定义、支持扩展点、轻量级、高性能和可靠性
本质是脚本解释引擎,需要有个后台配合进行配置,成为规则引擎。
github地址:https://github.com/alibaba/QLExpress
推荐博文:https://blog.csdn.net/YuYunTan/article/details/101436910
URule
官方地址:http://www.bstek.com/products/urule
git地址:https://github.com/youseries/urule.git
URule是一款纯Java规则引擎,它以RETE算法为基础,提供了向导式规则集、脚本式规则集、决策表、交叉决策表(PRO版提供)、决策树、评分卡及决策流共六种类型的规则定义方式,配合基于WEB的设计器,可快速实现规则的定义、维护与发布。
URule提供了两个版本:一个是基于Apache-2.0协议开源免费版本,URule开源版本第一款基于Apache-2.0协议开源的中式规则引擎;另一个是商用PRO版本
优点:
可视化操作完善、功能强大
缺点:
不支持回溯:当前分支没有符合条件的之后不支持回溯
不支持动态加载数据:例如门店有等级、店龄、区域等若干属性,业务规则具体是根据店龄不同给出结果还是根据等级,属于规则的业务范畴,调用方并不关心。要是每次需要将所有可能用于规则判断的数据全部由调用方传入,无疑降低了规则的灵活性。
参考资料:
https://zhuanlan.zhihu.com/p/552289273
https://blog.csdn.net/qq_30615201/article/details/111318623
http://t.zoukankan.com/jpfss-p-10869920.html
https://www.ngui.cc/el/951629.html?action=onClick