要解决的问题
在风控领域图可视化场景中,由于可视化图中的节点多且关系复杂,导致用户很难看清节点之间的关联关系;通常我们会使用一些图布局算法对整张图进行布局,使整张图的关系更加清晰,便于用户分析。
常见的图布局算法有圆形布局,分层布局,正交布局和力导向布局等,通常我们都会在一张大图中应用某一种布局算法,或者提供切换整张图布局的交互方式来帮助用户分析问题,但是往往在大图中进行单一的布局很难满足业务诉求,因为每种布局算法都有一定的优势和劣势,例如圆形布局和同心圆布局便于发现图中度数最多的节点,但是不适合节点较多的情况;分层布局适合看清节点所处的层级,但是会造成空间上的浪费;力导布局可以很好避免节点重叠的情况,但是经常会造成连线错综复杂,难以分析图中节点关联关系,并且在大图场景布局计算性能比较低下。而通过切换图布局的方式则需要对整张图的节点位置进行重新计算,由于所有节点的位置都发生了变化,不仅不利于分析,而且还比较影响性能。
通常用户的迫切需求是在一张大图中能够选择其中任意的节点进行自定义布局,因此,本方法旨在解决在图可视化场景中传统单一布局方式无法很好展示图中节点关联关系的问题。
技术背景
子图
子图的概念最早来源于图论,指的是节点集和边集分别是某一图的节点集和边集的子集的图,例如:设
文章图片
,
文章图片
为两图(同无向图和有向图),若
文章图片
且
文章图片
,则称 %22%20aria-hidden%3D%22true%22%3E%0A%20%3Cuse%20xlink%3Ahref%3D%22%23E1-MJMATHI-47%22%20x%3D%220%22%20y%3D%220%22%3E%3C%2Fuse%3E%0A%20%3Cuse%20transform%3D%22scale(0.707)%22%20xlink%3Ahref%3D%22%23E1-MJMAIN-2032%22%20x%3D%221112%22%20y%3D%22583%22%3E%3C%2Fuse%3E%0A%3C%2Fg%3E%0A%3C%2Fsvg%3E) 为
文章图片
的子图
力导布局算法(Fruchterman-Reingold)
力导布局最早是由 Peter Eades 在1982 年的“启发式画图算法”一文中提出,目的是为了减少布局中边的交叉,尽量使边的长度保持一致。该方法使用弹簧模型模拟模拟布局过程,用弹簧模拟两个节点之间的关系,节点在受到弹力的作用后,过近的节点会被弹开而过远的点会被拉近,通过不断的迭代,最终使整个图布局达到动态平衡,趋于稳定。
之后Thomas Fruchterman & Edward Reingold于1991年提出了全新的力导布局算法的概念,即FR算法(Fruchterman-Reingold)。该算法改进了之前的弹簧模型,丰富了节点之间的物理模型,加入节点之间的静电力,通过计算系统的总能量并使得能量最小化,从而达到布局的目的。无论是这种改进后的能量模型,还是之前的弹簧模型,其算法的本质是能量优化问题,区别在于优化函数的组成不同,优化对象包括引力和斥力部分,不同算法对引力和斥力的表达方式不同。
例如对于一个图
文章图片
,分别有节点
文章图片
和节点
文章图片
,用表示两个点的欧式距离(即真实距离),
文章图片
表示弹簧的自然长度,
文章图片
是弹力系数,
文章图片
是两个节点之间的静电力常数,
文章图片
是两节点之间的权重。那么两种算法的公式分别如下:
弹簧模型:
能量模型:
文章图片
相似方案调研
一种基于图多阶段任务系统模块分解的可视化布局方法
该布局方法首先调用多阶段任务系统模块分解算法对图进行分解,生成模块分解树,以树的形式来表示图的内在子结构,树中节点按照链接规律划分为 Parallel、Serial 和 Neighbor 三种类型;其次,自上而下,按照节点类型对子图进行局部布局,不同类型子图采用不用的布局算法,原则是美观、无重叠以及能反映节点聚类特性;最后,按照画布大小与实际需求,设置树节点位置,然后自上而下,结合父节点的位置以及子节点相对于父节点的位移对树中所有节点进行整体布局,最后获得的叶子节点位置即为布局结果。
基于图多阶段任务系统模块分解的可视化布局方法,通过将所有节点分为三种类型的方式来进行子图布局,意味着一个图中最多只能支持三种布局,并且节点是通过模块分解算法来分解的,没有提供用户自定义选择节点来进行子图布局的交互方法,这样会导致用户无法对图中的任意子图进行分析。
例如在一个复杂的关系图中,用户通常会选择多个想要分析的节点,然后再选择相应的布局算法对子图进行布局,利用不同布局算法的优势,可以快速识别子图中每个节点的特征。
因此本方案针对以上两个缺点,提出了一种基于自定义子图的可视化布局方法,该方法可以让用户任意选取一张大图中的多个子图来进行多种布局的方式,使用户能够快速有效的分析图中的蕴含的信息。
本方案的实现流程
文章图片
本方案实现过程的详细说明:
1. 子图切分
用户可以根据自定义的需求从一张大图中筛选出想要布局的子图。如下图所示,不同颜色的节点点代表不同的子图。如下图所示
文章图片
2. 子图布局参数输入
本方法可以支持现有的任意布局算法对子图进行布局,因此需要用户设定子图布局的相关的布局参数。
3. 子图中所有节点位置计算
每个子图会根据用户设定的布局参数计算出子图中所有的节点位置。例如可以对上图中的子图分别进行同心圆布局和网格布局计算。
4. 是否有确定的子图中心位置
在对每个子图中的节点进行布局计算后,会造成子图之间存在重叠的情况,因此本方法可以让用户自定义每个子图的中心位置,在小数据量的场景下,由于图结构比较简单,用户很容易自定义这种方式通常比较有效;但是在大数据量场景下,由于图结构会变得非常复杂,用户很难自定义出每个子图的中心位置,因此本方案提供了一种力导布局算法,可以避免布局后的子图重叠,具体流程如下
文章图片
1)首先本方法会忽略所有子图中节点的实体边,因为在之后的力导布局计算中,实体边的存在会影响整体布局的位置。
2)之后每个子图会被抽象成一个超大的圆形虚拟节点。
3)每个子图之间会相互创建一个虚拟边,
4)此时子图会与其他节点一起构建成另一个大图,然后我们通过力导布局算法计算出所有节点的位置。
5)由于力导布局计算出位置无法保持原有子图的拓扑信息,因此我们会记录每个节点的相对位置,每个节点与其相邻节点之间的拉普拉斯差异可通过以下公式计算:
文章图片
6)最后批量更新所有子图以及其他节点的位置,从而达到对于子图进行自定义布局的目的。
最终效果
最后的布局效果如下图所示:
文章图片
同心圆布局+网格布局
文章图片
圆形布局+网格布局
文章图片
同心圆布局+DAG布局+网格布局
总结
子图布局一直是图可视化领域中研究的重点,本方法通过将子图抽象成虚拟节点,并创建虚拟边,然后使用力导算法计算出所有子图的位置,最后运用拉普拉斯变换的方式使整张图尽量维持原有的拓扑性质。从而可以将一个图拆分成多个自定义子图进行不同方式的布局。目前在图分析业务场景使用比较广泛。
作者:ES2049 / 谢康奎
【一种子图布局方法的实现】文章可随意转载,但请保留此原文链接。
非常欢迎有激情的你加入 ES2049 Studio,简历请发送至 caijun.hcj@alibaba-inc.com