论文笔记-Deep Learning Based Code Smell Detection (3)
COSPA: Identifying Key Classes in Object-Oriented Software Using Preference Aggregation
使用偏好聚合识别面向对象软件中的关键类 2021 IEEE
XIN DU, TIAN WANG, WEIFENG PAN
摘要
在软件维护过程中,开发人员经常使用文案和相互通信来理解软件,但是开发人员文档的不完善和缺失加大了理解难度。
找到关键类作为软件理解的起点,大多数有效的关键类识别方法都是使用有监督学习和无监督学习的方法,但缺点在于可能会受到类的分布不平衡、数据量不足和缺乏准确性的影响。
本文方法COSPA:使用偏好聚合的方法识别面向对象软件中的关键类。本方法受到社会选择理论的启发,使用Kemeny-Young方法找到一种偏好,这个偏好将通过三种识别方法(a-index, InDeg, OSE)返回不同的序列,再对之间的总差异最小化。
此外,根据该偏好按照降序对类进行排名,少数排名靠前的类被视为候选类。
为了验证方法的性能,将该方法应用于6个Java软件系统,与九种先进方法进行比较,使用Friedman评估所有方法,结果表明效果最好。
1 介绍
Introductin
在软件维护的过程中,识别关键类对于软件系统的理解起着重要作用,
软件理解过程中的主要信息来源:源代码和文档;开发人员的交流;
然而在实践中大多数软件开发团队 都缺少交互和详细文档,引入关键类的概念。
有人提出从软件系统的核心开始,系统有主要的关键类组成,用于表征系统的重要属性。关键类和系统的各个部分耦合,并实现软件系统的重要功能,面向对象(OO)软件成为主流时,关键类可以作为理解软件系统的起点。
目前大多是开发人员使用的是基于有监督学习和无监督学习的方法。
有监督学习方法使用机器学习算法训练已知的样本,通过调整分类器的参数以在测试集中找到关键类。实际上存在着缺乏足够的数据以及软件中类的分布不均衡的问题。
无监督学习从软件网络的 结构,度量以及复杂性的角度,这些方法更适合大规模数据,因此应用范围更广一些。
虽然这些方法的准确性已经几乎达到了上限。但是很少有方法结合有监督学习和无监督学习。
本文发现,这种单一的方法在类的候选聚集(人工指定的确定是关键类的集合)不大的时候,表现不佳。聚合这些方法可以通过仅仅查找少量的类更有效地识别关键类,本文提出了一种不需要大量数据且可以实现高准确率识别关键类的方法。
社会选择理论:主要是分析个人偏好和集体选择之间的关系,其研究的根本问题是各种社会决策是否尊重个人偏好,能否对不同的社会状态进行公正的排序或者以其他某种方式加以评价。Kemeny函数作为一种社会选择函数,它为候选人的每一个可能的排序赋予一个函数值,并将最大的函数值所对应的排序作为群的排序。
在社会选择理论中,共识的概念对应于目标的最大化,即一致性。类似的,这可以视为发散(分歧)的最小化,这需要计算聚合的偏好排序。然后最小化个体分歧的总和。
本文受到Kemeny-Young方法思想的启发,本文提出COSPA方法:
首先通过加权有向网络表示粒度级别的软件结构,节点、有向边、权重表示软件网络的类,耦合方向和强度;
其次根据下述公式获得三级重要性排名:a-index,InDeg,OSE
再用Kemeny-Young方法找到一个最佳序列,该序列将自身与三个排名之间的差异总和最小化。
最后按照整体偏好的顺序对类进行排序,排名靠前的即为关键类。
使用6个开源的软件系统,这些系统又丰富的文档集并且广泛应用于关键类识别工作,从实验中看到本文提出的方法能够识别出大多数关键类,仅仅依赖于类集合的一小部分。
本文的先进性:
提出了一种新方法COSPA,用于识别关键类,并将其作为开发人员理解软件系统的起点。
提出一个新想法:最小化三种方法(a-index,InDeg,OSE)的每个序列和发散序列的差异总和,将三种方法聚合成单个总体偏好。
提出的方法能仅依靠类集的一小部分来识别大多数关键类
数据集、工具源码:https://github.com/SEGroupZJGSU/COSPA
2 相关工作
Related Work
有监督学习:目的是用一个分类器来预测一个类是否是关键类,如逻辑回归和KNN。再有就是扩展:
方法1:首先提出了重心中心性和中介中心性;
其次使用这些度量的值作为特征值,输入到标准分类器中进行训练,将概率分数分配到未知的数据点,
最后对这些未知的数据点给出标签,与原始的已经确定为关键类的数据统一训练,以获得乐观的分类模型来预测软件系统中的关键类。
然而这些方法需要人工标注数据集,人工成本大。为了能够自动识别关键类,提出了另一种方法:
方法2:首先使用k作为均值选择一部分数据作为训练数据,
然后使用集成学习算法来处理类不平衡问题
最后构建合适的分类器,应用到有限的数据集。
无监督学习:根据类的结构属性识别关键类
方法1:半自动方式识别关键类。构建方法调用树,压缩方法调用树,对子树进行分类,然后从这些关键子树候选集中选择关键类
方法2:PageRank测量节点重要性。度数较多的节点比度数较少的节点更重要
方法3:ElementRank方法将提取到的软件结构信息描述为类级别和包级别的多层软件网络,并引入全局加权PageRank来计算每一层的类和包的加权PageRank值。而且应用层次分析法汇总每层的加权全局页面排名,最后按照降序排列所有的全局加权页面的排名值,以识别关键类。
方法4:K核分解是图形算法中的一种经典算法,主要用于计算每个节点的核心度,最常用的值决定的节点的重要性。并提出了加权有向网络的广义K核分解,计算软件网络的广义K核结构。
方法5:将软件表示为依赖图,使用h-index和它的派生度量类的重要性
方法6:MinClass方法,使用OSE(一阶结构熵)来计算类的重要性
基于有监督学习的方法需要大量的数据,并且存在数据不足和类分布不平衡的问题,
当前主要使用无监督学习的方法来识别关键类,主要使用软件结构,测量数据和软件复杂性中包含的信息。但是现有的基于无监督学习的方法可能会达到其性能上限。
3 COSPA方法
COSPA Approach
COSPA框架:
1)提取软件结构信息:分析源代码以获得结构信息
2)构建软件网络:根据耦合方向和类之间的强度建立加权定向网络
3)使用Kemeny-Young算法汇总三种方法(a-index、InDeg、OSE)的结果,获得最小发散序列
4)使用该序列的降序作为类重要性排名
3.1 结构信息提取
首先是将软件拓扑抽象为软件网络,获得软件网络的结构。网络由节点和链接组成,表明类和包之间存在各种包含和依赖关系。
3.2软件网络定义
提取到软件结构信息之后,使用CCN(类耦合网络)的加权有向网络来描述结构,定义为CCN=(V, L)
CCN由 V 和 L 组成,V:节点集(类和接口);L:链接集(类到类的耦合)
当vi向vj提供服务,表示为vi --> vj,类之间有9种类型的耦合。
类之间的链接方向反映了类之间的依赖关系,还需要引入链接权重,以表明模块之间的耦合强度,权重取决于模块之间的依赖复杂度。客观的加权机制:
r:表示上述9种耦合关系
Wr:耦合权重
Nintra:模块内部耦合计数
Ninter:模块之间的耦合计数
Round:四舍五入
3.3发散排序策略
根据社会选择理论:将个人偏好(preference)和差异(discrepancy)聚合成一个偏好。因此本文目的是尽量减少不同偏好之间的差异,本文需要在获得不同方法的排名之后,通过计算发散最小化分数来获得序列。
发散排序策略:
目的是获得最终序列,使得每个序列和最终序列之间的发散分数之和最小。D(x, y)表示序列 x 和 y 和 Si 之间的置换距离测量数据。i ∈ {1,2}表示每种方法单独排名的结果。这时 n 表示值为3,这表示本文一共聚合了三种方法:
1)a-index
该方法应用与加权无向网络,可以用来衡量类或者包的重要性,与其他方法相比,更考虑吧软件的整体性。
首先将Java软件项目抽象为特征依赖网络 FDN = (Nf,Df),然后进一步构造一个类依赖网络CDN = (Nc,Dc,P),其中P是一个矩阵 Nc×Nc ,用来编码类之间的依赖关系。
其次通过计算 CDN 中的所有节点的权重,按照权重降序排列节点以获得列表 j,
然后找到第一个 权重小于 n+1 的节点 list[n+1],得到节点 i 的权重 h(i),用来计算cit(i)
根据计算cit(i);根据
计算每个类节点的加权 a-index ,并按照加权的a-index指数按照降序排列每个类,得到类的重要性等级。
2)InDeg
应用于有向无权网络,它表示节点的入度,在CCN种,它量化节点与节点之间的链接的数量,把这个CCN带入到图二的右边,计算每个节点的InDeg的值,得到的InDeg的值为:animal=1 AS=2 Dog=1 Cat=0,再将这些值降雪排列,得到类的重要性等级
3)OSE
提出一个新的度量标准OSE并且用来衡量类的重要性。
考虑到了CCN的四个特性:包括耦合强度、类节点和其邻居节点之间的链接的权重分配的不同、类节点的邻居节点的数量,以及类的邻居节点的重要性。
OSE被定义为:
计算方法:首先根据式7和式8计算hw的值,再计算每个类节点的OSE的值,按照降序排列,关键类位于列表之前。
4)Kemeny-Young Method
K-Y方法是投票系统中的经典算法,首先选民对其首选候选人进行排名,KY方法遵循Condorcet原则(对战原则),将有序的多个选民的偏好汇总为一个整体偏好顺序。当存在两个以上的候选人时,比较他们,挑选出一半打败其他人的人,那么这个候选人就是共同胜利者,这个Condorcet原则对M个候选人进行排名,使得赢家排在前N位
使用K-Y方法将a-index InDeg OSE三种方法聚合一起,选民对应于上述三中方法,候选则对应于CCN中的类节点。
在使用三种方法的每一种方法得到类的重要性排序之后,我们计算发散的排名分数,Kendall-T距离(KT距离)现在用于量化发散分数,也就是上述提到的D(x,y),并且这个距离用来测量两个完全有序的序列之间的成对偏好发散分数的总和。发散分数依次是指 Ci 和 Cj 两个列表序列的顺序。如果他们存在相同的顺序,则这个得分是0,否则得分为1,然后通过引用来指定计算KT距离的数学公式:
S1和S2表示两个完全有序的序列
例子:存在完全有序的序列 S1=<C3,C2,C4,C5,C1> 和 S2=<C1,C2,C3,C5,C4>. 经过推导发现在两个序列 S1 和 S2 中 有6对存在相反序列:(C1,C3),(C2,C3),(C1,C2),(C4,C5),(C1,C4),(C1,C5) 所以 KT(S1,S2) = 6
对于三种方法(a-index InDeg OSE)得到的有序序列,使用KT方法最小化所有类之间成对偏好的差异。
这是著名的NP-hard排序问题,NP指的是非确定性多项式。非确定性:可用一定数量的运算去解决多项式时间内可解决的问题。NP问题通俗来讲就是其解的正确性能被很容易检查的问题。
本文利用现有的实现,使用随机快速启发式进行KY计算。随机快速启发式对KY分数执行 N 次对立贪婪最小化并记录下每个类别的最终排名。
注意点:多个序列可能存在相同的最小发散分数,在这种情况下,最终顺序由N次迭代后每个类别的平均等级顺序决定。
在实验中,在经历N>100次迭代之后,类的平均等级序列趋向稳定,类之间的等级变化非常小,因此在实验中将N=100.
3.4ANT的一个简单示例:计算差异最小化分数
举一个例子来说明KY方法如何最小化类之间成对偏好的总差异,从而聚合多种方法的偏好。
在实例中,我们使用来自软件Ant的两种方法M={InDeg,OSE}
五个类C={MailPrintStream,ProjectHelper,Task,Target,BuildEvent},分别表示为C1,C2,C3,C4,C5
为了模拟计算过程,需要两个序列。一个是根据KY 方法获得的序列,另一个是自己假设的序列S2={C3,C4,C1,C2,C5}
五个类节点在两种方法中的排序结果如表:
S1=(C3,C4,C2,C5,C1)
S2=(C3,C4,C1,C2,C5)
InDeg=(C3,C2,C4,C5,C1)
OSE=(C3,C4,C5,C2,C1)
分别计算S1,S2与两种方法的KT值,得到发散分数:
S1与InDeg、OSE:
S2与InDeg、OSE:
S2的差异分数 > S1的差异分数,因此S2不是最佳顺序,
3.5类的重要性排序
使用KY方法汇总三种方法的结果后,获得了最佳序列,然后使用一个阈值 k 将关键类的候选集合分为两组,即Top-k和其他,如果一个类的排名值比k小,则它在top-k集合中,将其视为关键类候选人
4 实证研究
验证COSPA的可行性和有效性,在六个开源软件系统上进行测试
4.1研究问题
1.COSPA方法是否能识别出比其他方法更多的关键类,验证本方法优于其他方法
2.COSPA方法是否可扩展,验证本方法可应用于不同规模的软件项目
4.2项目系统
选用6个Java软件系统作为项目系统,
KLOC表示千行代码数 #C(#enums)表示类的数量 URLs表示下载该版本项目软件的链接
Ant
Argo UML
JEdit
JHotDraw
JMeter
Wro4j
4.3评估指标
使用 精确率 、 召回率 和 F1 作为评估指标,
召回率:表示检索到的关键类数量 / 关键类的总数。意味着所有的关键类中检索出多少个关键类
精确率:表示检索到的关键类数量 / 检索到的所有类的总数 。 意味着检索到的类中有多少关键类
F1:表示召回率和精确度的调和均值 F1越高表示方法越好
4.4基线方法
九种基线方法:
PageRank:链接数较多的节点比链接数较少的节点更重要
h-index 和 a-index:应用于加权无向网络,a-index 方法用来分别计算每个类节点的加权的 h 指数和 cit 指数
MinClass:使用OSE(一阶结构熵)计算系统中每个类的重要性,而且可通过检查少量类来挖掘关键类
InDeg (In-Degree):入度。在有向图中作为终点的端点的次数
OutDeg (Out-Degree):出度。在有向图中作为起点的顶点的次数
Coreness:核数。K核在无权无向图中,
Deg (Degree):入度+出度
ICOOK(使用广义K核分解识别面向对象软件中的关键类候选):有向加权图。使用广义K核分解方法来计算每个类节点的广义核数。
4.5结果及分析
RQ1:COSPA方法是否能够识别比其他方法更多的关键类?
选择25个类作为关键类集
对于排名值相同的类的解决办法:将最高排名和最低排名取均值,作为这些类的排名位置。
Answer:根据各种方法的比较表明,COSPA方法不是在所有软件系统中都优于其他方法。因此,我们需要引入一个客观的方法,弗里德曼测试,以帮助我们更好地比较COSPA与所有其他方法的整体性能。
根据不同方法的召回值执行Friedman测试,结果如表10所示。
在我们的弗里德曼测试中,较大的排名值表明该方法的性能较差;较小的排名值表明该方法的性能更好。
因此,弗里德曼测试将这十种方法分为以下顺序:
COSPA>MinClass>Deg>h-index>iook>InDeg>K-Core>PageRank>OutDeg>a-index,
这意味着COSPA是最好的,a-index是最差的。
RQ2:COSPA方法是否可扩展?
COSPA应具有良好的可伸缩性,可用于不同尺寸的软件系统。
为了测试各种尺寸软件系统的适用性,除了上述六个软件系统外,我们还引入了另外两个更大的可扩展软件系统Mars和Tomcat
Answer:发现所需要的CPU时间和类的数量有关,COSPA有良好的可拓展性。
4.6对有效性的威胁
第一个威胁:与关键类数据集的构建有关
关键类集构建带有主观因素,本文使用相关工作广泛使用的软件系统
第二个威胁:使用的软件系统是开源的Java软件系统,当结论应用于其他语言编程系统,可能会导致问题
第三个威胁:项目可以根据软件的KLOC的大小分为几类:小型(jMeter, wro4j, and jHotDraw),中型(Apache Ant and Argo UML)和大型(jEdit, Tomcat, and Mars)。更大的开源项目可能会导致结论失败。
5结论和未来的工作
本文提出了一种用于识别关键类的新方法COSPA。
COSPA帮助开发人员更好地理解和维护软件。
我们的方法使用Kemeny-Y oung方法来找到一种偏好,该偏好使由三种关键类别识别方法(即a-index,InDeg和OSE,返回的不同序列对之间的总差异最小化。
COSPA用于衡量系统中每个类的重要性。
弗里德曼测试的平均排名结果表明,与九个基线方法相比,我们的COSPA方法表现最佳。
未来的工作包括:
(1)用其他编程语言在软件系统中复制这项工作;
(2)在应用于类识别问题时提出更高精度的新方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报