写点什么

开源决策树工具 xDecision 简介

用户头像
赫杰辉
关注
发布于: 2020 年 09 月 15 日
开源决策树工具xDecision简介

赫杰辉

前言

最近公司在搞技术创新,老板把一群程序员拉到山上,锁在酒店会议室里憋了一晚总结出来几条意见,其中之一就是之所以每次产品改需求我们都会苦哈哈的加班写bug,主要不是因为产品今天提的需求,昨天就该上线,而是因为我们没有一种无需硬编码就能修改系统逻辑的方法。大家一致同意改变命运的关键在于开发一个可视化的规则编辑和执行引擎。我一听这不就是我N年前搞过的决策树吗,虽然具体需求拔高了许多,但现成的代码改吧,改吧就能用啊。于是把代码拉出来,一通操作猛如虎之后,搞定。

 

本文将简单介绍一下决策树,以及如何利用可视化编辑器创建决策树模型并在应用中加以使用。想要升职加薪,又想减少秀发流失率的程序员,和希望在工具的逼格上PK掉隔壁开发小组的dev leader适合阅读本文。

决策树定义

决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。它是一种简单但是广泛使用的分类器。可以高效的对未知的数据进行分类。例如:



决策树有两大优点:

  1. 决策树模型可以读性好,具有描述性,有助于人工分析

  2. 效率高,决策树只需要一次构建,反复使用,每一次预测的最大计算次数不超过决策树的深度。

决策树适用场景

决策树主要用于核心的判断和分类逻辑。是否用决策树代替硬编码的if-else或者switch语句,可以参考以下几个判断标准:

1.     判断逻辑是否相对独立,在判断中是否主要是分类判断,不大涉及到计算过程

2.     判断逻辑是否会经常调整,比如是否依赖于节假日,市场或政策的变动,例如优惠规则等。如果是常识,或者基本固定的技术层面的判断或校验,则无需使用决策树

3.     影响判断的因素是否较多,比如大于等于3个因素,每个因素有2个或以上的分类判断

4.     判断逻辑是否是重要的业务需求,比如业务需求描述了明确的分类算法等

 

如果上述问题的答案中是的较多,建议使用决策树。



如果没有趁手的工具,光知道决策树的概念并没有什么用。接下来我就为大家介绍一款与IDE集成的,非常方便好用的可视化决策树编辑器xDecision。

XDecision简介

xDecision是一套包括编辑器和引擎在内的开源决策树工具。其中编辑器可以以插件形式安装到流行的IDE中,目前支持Eclipse和IDEA。引擎是个独立jar包,可以内嵌到应用系统中使用。使用流程基本上就是先通过编辑器创建决策树模型,再使用引擎对事实做判断以获取决策。



相比drools等商业化工具,xDecision的使用非常简单直接,其良好的图形化界面不但研发人员可以使用,业务人员也可以很快上手。它即可以用于业务领域,代替drools覆盖80%的场景,又可以用于技术领域,用于代替基于if-else的复杂的逻辑判断。同时因为不依赖任何后台或者数据库,所以运行起来也很轻量级。当然将引擎简单的包装为服务也是一种常见的操作。这也正是我们创新项目的做法。

 

项目地址

https://github.com/hejiehui/xDecision

整个项目包括引擎,eclipse编辑器,IDEA编辑器和一个样例工程。

安装编辑器插件

Eclipse编辑器插件

如果要安装Eclipse版本,请下载xDecision Eclipse插件

在Eclipse里面按照时记得选型按照下图勾选,否则会花很长时间搜索外网服务器:





IDEA编辑器插件

如果安装IDEA版本,请下载xDecision IDEA插件



在File->Settings->Plugins->Install plugin from disk里面选择下载好的插件,安装重启即可

获取xDecision引擎依赖

可以在xDecison releases页面查找最新发布。

也可以自己在 xDecision 下载源码编译打包

快速体验

如果希望快速体验决策树的魅力,可以直接下载样例工程:

xdecision sample



在IDE里面双击src/main/resources下的

Sample.xdecision

expression.xdecision

即可在编辑器中打开对应模型



 

创建决策树

在Eclipse中安装插件后,在New菜单里面可以看到New Decision Tree Wizard创建向导。





在IDEA插件安装好后可以看到Xross Decision Model菜单 



点击后输入文件名即可创建一个空白的决策树模型。Eclipse版本的编辑器需要配合Properties View,既属性窗口,可以在windows菜单找到并打开。IDEA版本的编辑器会自动显示,无需用户处理。 

缺省模型

xDecision相关概念

点击编辑器的空白处,即可选中决策树模型本身,在对应的Properties里面,你可以看到有Configure,Decisions和Factor。





这些就是构建决策树的基本元素。我们先不管Configure里面的内容,先来看看Decisions和Factor。

Decisions

以字符串表示的所有可以通过决策树的路径到达的decision。在编辑器中如果选择的话,会以暗绿色显示在节点上。

Factor

用于决策判断的事实依据,可以看做是变量或属性。每个Factor按照创建顺序自动赋予一个递增的id。每个事实包括name属性和其取值范围的枚举集合 Factor X value [0,N]。Name会显示在节点的顶端,代表本节点基于那个事实进行判断。Value会作为连接该节点和子节点的边的选项,代表当事实为何值的时候,选择这条路径。

预定义值

为了方便大家使用,新决策树模型预先创建了3个factor,每个两个取值,和6个decision作为初始数据。你可以在Properties窗口对这些预定义的数据做修改并里面反映到图上。

创建节点

下面的操作以IDEA作为代表,Eclipse的操作基本相同

点击



按钮,再点击编辑器空白处,即可创建一个新节点。点击节点,在属性窗口的Factor栏可以选择该节点判断所需的事实。如果该节点同时对应一个可以到达的决策,则可在Decision栏选择对应decision



关联节点

决策树是由父节点和子节点构成的,创建父子关联有两种做法:

做法1:

传统做法是点击





进入关联节点模式,依次点击父节点和子节点,将在两节点之间产生一个连线代表关联关系,点击该连接可以选择父节点factor中的一个取值作为判断依据。注意由于IDEA编辑器的限制,点击父节点后,在父节点和鼠标之间并不会显示随鼠标移动而改变方向的连线作为操作反馈,请不要误会为点击失败。Eclipse编辑器无此问题。





做法2:

为了简化上述步骤,可以直接双击父节点,系统会自动为该节点创建一个子节点,并将该factor尚未使用的第一个判断取值作为关联的值。如果该factor所有判断取值都已经用光,则不会自动赋值。此时可以双击关联,在弹出窗口输入表达式,该表达式会自动添加到父节点的factor取值列表并赋予当前关联。

修改节点属性

用鼠标选中节点后,右键调出上下文菜单。在菜单中会显示所有factor和decision列表,如果当前节点已经有factor,则在该factor前面会显示选中标记。同理已选中的decision也会有相同标记。可以直接在上下文菜单中选择你想要的factor或decision,或者创建新的factor或decision并赋予到当前节点

修改关联属性

用鼠标选中节点间的关联后,右键调出上下文菜单。在菜单中会显示父节点factor所有的判断取值的列表,如果当前链接已经有指定的判断取值,则在该值前面会显示选中标记。可以直接在上下文菜单中选择你想要的取值,或者创建新的取值并赋予到当前链接



重复上面的步骤,创建所需节点并建立连接,从而最终形成一个决策树。 

增加事实和决策

如果情况复杂,缺省的factor和decision不够用,可以随时增加新的。右键调出弹出菜单或者点击





这两个工具按钮(Eclipse只有菜单,没有这两个工具按钮),输入factor或decision的名字即可创建。





自动布局

如果觉得决策树布局不美观,编辑器上方提供了自动布局的工具按钮,横竖,间隔都可以随意调整,即使是我等手残党也可以一键搞定



注意:

因为布局与模型的实际含义无关,也不影响实际使用效果,所以决策树编辑器不会保留布局信息。每次关掉编辑器后重新打开模型,都是按照缺省居中对齐的方式重新布局。

自定义扩展

缺省情况下,factor和decision都是字符串,在大多数场景里面够用了。但有时候希望最终获取的decision是个自定义对象,比如实现了某个接口的,可以做方法调用的实例;或者希望对factor的判断可以基于表达式,这时候就是xDecision插件登场的时候了。还记得之前我们暂时放下的Configure配置吗?在这里可以设置用户自定义的扩展。具体不在这里细说,有兴趣可以参考:

1.     结构解析plugin

2.     路径选择plugin

验证决策树

生成出来的决策树到底灵不灵是大家最关心的问题。点击





可以自动帮你生成基于当前决策树的测试代码。代码包含完整的类定义,提供类名,获取决策树模型的逻辑,和对每个可到达的decision的factor构建和调用的逻辑。你可以新建一个java类文件将代码手工copy进去,为项目添加xDecision依赖后,按照标准的junit的方式去运行。



注意生成测试代码本身不是必要的步骤,决策树的运行是不依赖于该代码的。这个测试代码主要用于上线前的验证。和学习xDecision的用法。

 

例如我们为刚才创建的决策树生成的测试代码长这样:



 

其中关键代码就是:



tree =  XDecisionTreeFactory.create("D:/test/com.xrosstools.xunit.sample/src/main/resources/xdecision_demo.xdecision");
//Verify tree
MapFacts test;
test = new MapFacts();
test.set("factor0", "value1");
assertEquals("decision2", tree.get(test));



可以直观的看到使用决策树能大幅简化代码,从此和if-else say bye-bye!

 

样例工程里面的测试代码也是通过这个功能生产的,其中:

1.     SampleTest.java是原始代码没有修改,

2.     ExpressionTest.java利用了扩展,在生成的代码基础上简化了factor的赋值



注意新的决策树编辑器生成的测试代码是将每个可到达的分支单独作为一个@Test的方法,上面的样例工程里面的代码是老编辑器生成的,所有的分支测试代码放在一个@Test里面。两者没有本质区别,但在可读性方面,新的方式更好,并且增加了路径注释方便阅读。

总结

只要是做过几年开发的人都知道,软件系统在上线的那一刻,才真正开始自己的生命周期。接下来会是无尽的修改和优化。这其中最麻烦的就是理解现有逻辑并加以修改。当年我写if-else简直快写吐了,碰到生产问题时面对一大坨自己或别人写的分支简直欲哭无泪 * 3。

 

使用决策树可以大幅简化代码,因为没有代码开发工作,也就没有代码风格,严谨度等人的因素造成的各种问题。如果将模型存储在配置中心,还可以方便的做到热部署,做到实时生效,节约大量测试和发布时间。

 

这个工具安装快捷,使用直观,简单培训即可上手,作为通用的模型,产品也可以看懂并参与讨论,让甩锅更困难。非常适合公司作为研发规范推广。

 

想象一下,当产品又双叒提了一个变更的时候,你拉风的点开决策树模型,一棵精致的决策树刷的闪在大家眼前,你懒懒的抬起手,气质拿捏的死死的,随便划拉几下鼠标就搞定了变更需求,再实时部署到测试或者生产环境,立马生效。你回头看了一眼目瞪口呆的产品和旁边团队leader羡慕嫉妒恨的眼神,嘴角露出了难以察觉的微笑





参考资料

决策树

 

作者介绍

赫杰辉,信也科技基础组件部门主管、架构研究员、信也 DAS 产品负责人、布道师。图形化构建工具集 x-series 的作者。曾主持开发携程开源数据库访问框架 DAL。对应用开发效率提升和分布式数据库访问机制有多年的深入研究

 

如果对决策树或其他可视化开发工具感兴趣,可以加入QQ群获取进一步信息





用户头像

赫杰辉

关注

开源可视化系统构建工具x-series作者 2020.06.09 加入

还未添加个人简介

评论

发布
暂无评论
开源决策树工具xDecision简介