一种基于局部和全局特征的特征依恋代码味道检测方法技术

技术编号:28212349 阅读:19 留言:0更新日期:2021-04-24 14:50
本发明专利技术涉及一种基于局部和全局特征的特征依恋代码味道检测方法,属于计算机软件重构技术领域。本方法能够自动地提取代码中的特征信息,消除了人工提取特征的步骤,降低了人力成本,能够将提取出的特征信息与检测结果自动匹配,减少了人工设计规则的时间和人力成本。除加入已有代码度量中的结构化信息,还加入了源代码中局部特性信息和全局特征信息,可以辅助已有的度量值检测方式,对代码味道进行更深入的检测。本方法与基于传统机器学习的代码味道检测方法相比,提高了检测的精准率和查全率。率。率。

【技术实现步骤摘要】
一种基于局部和全局特征的特征依恋代码味道检测方法


[0001]本专利技术涉及一种特征依恋代码味道检测方法,具体涉及一种基于局部和全局特征的特征依恋代码味道检测方法,属于计算机软件重构


技术介绍

[0002]软件系统中的源代码质量问题,一直是现代软件工程领域面临的一个关键性问题。在互联网的软件开发工作中,当对一个大型软件系统进行长时间的维护时,开发人员编写的代码虽然可以很好的完成业务需求,但是长期的软件工程活动中会导致当前代码工程偏离原来的代码架构,使得代码的可维护性变差,最终往往会导致严重的软件质量问题和软件维护问题。在软件工程中,使得让软件质量下降的代码片段被称为坏味代码,坏味代码的存在直接影响着软件系统的可维护性和可重用性。为了去避免代码的可维护性等出现问题,需要工作人员定期对软件系统进行分析,将潜在的坏味代码识别出来,并将该代码片段进行重构,所以坏味代码的检测在软件工程领域起着至关重要的作用。
[0003]在软件开发的过程中,开发人员发现相同方法编写在不同的类中会对代码产生不同影响,有时会项目产生较大的质量隐患。为了更好的识别代码中的坏味,研究者们对产生问题的代码片段进行了大量的分析,Fowler等人总共引入了22种代码味道,包括Feature Envy,Long Method以及God Class等。由于不同坏味代码之间的特点差别很大,对后续针对不同的坏味代码检测的研究提供了坚实有力的基础。
[0004]最初坏味代码的检测是人工检测,但是人工检测方法掺杂着很强的主观性因素,为了解决这问题,研究者们提出了一种基于度量值的检测方法,一比如圈复杂度、代码行数、类耦合等。然而对于相同的坏味代码,不同的检测方法具有不同的规则,因此结果往往会产生很大的偏差。
[0005]为了避免人工设计规则而导致的系统性误差,研究人员提出了基于传统机器学习的代码味道检测方法,比如如SVM、J

48和朴素贝叶斯。这些方法能够额外的提供主观性,从而避免人们对代码味道的认识不同的问题,同时,这些方法能够自动地从代码度量中提取相应的特征完成对代码味道的识别。但是,当同时检测两种或者更多种代码味道时,这些基于传统的机器学习的方法并没有很好地表现。
[0006]近年来,深度学习在自然语言处理、计算机视觉、推荐系统等领域中大放光彩。深度学习等技术的架构是基于多层神经网络的,其目的主要贡献在于可以对高维数据进行有效的建模。与基于传统的机器学习技术不同,深度学习技术提供了从低到高的多层次的数据抽象,并在深度特征提取上取得了更好的表现。目前,深度学习技术已经成功应用于代码味道检测当中。例如,刘辉等人提出了一种基于深度学习的方法来检测坏味代码,这种方法利用了文本信息和代码度量值,但是在当前的检测方法中,模型考虑代码文本的角度过于单一,没有充分利用代码文本中局部信息,并且忽视了代码文本中的局部信息和全局信息之间的关系。
[0007]因此,如何克服现有技术的缺陷,寻找更为有效的检测方法,成为本领域的重要研
究方向。

技术实现思路

[0008]本专利技术的目的是为了解决软件重构领域现有代码味道检测方法存在考虑代码文本的角度过于单一,没有充分利用代码文本中局部信息,并且忽视代码文本中的局部信息和全局信息之间的关系等技术问题,创造性地提出一种基于局部和全局特征的特征依恋代码味道检测方法。
[0009]本专利技术是通过以下技术方案实现的。
[0010]一种基于局部和全局特征的特征依恋代码味道检测方法。
[0011]包括模型训练部分和模型测试部分。
[0012]模型训练包括代码函数表示A、局部特征提取B、全局特征提取C和代码分类味道D。
[0013]模型测试包括代码函数表示E,局部特征提取F,全局特征提取G和代码味道分类H。
[0014]其中,代码函数表示A和代码函数表示E是基于Self

Attention神经网络代码函数表示。
[0015]局部特征提取B和局部特征提取F是基于孪生网络结构的特征提取。
[0016]全局特征提取C和全局特征提取G是基于卷积神经网络的结构化特征提取。
[0017]代码味道分类D和代码味道分类H是基于多层感知机的代码味道分类。
[0018]代码函数A表示和代码函数表示E的操作为:基于Self

Attention神经网络,对被检测的代码函数进行特征表示并进行特征提取,具体方法为:
[0019]步骤1:将被检测的代码函数所在的类名、目标类名和函数名作为一个元组拼接在一起,输出代码标识符,作为深度语义提取的文本输入,用公式(1)中的符号textual
input
表示:
[0020]textual
input
=<name
ec
,name
tc
,name
m
>
ꢀꢀ
(1)
[0021]其中,name
ec
代表代码函数所在的类名;name
tc
代表代码函数要重构的目标类名;name
m
代表代码函数所在的函数名。name
ec
,name
tc
和name
m
统称代码标识符。
[0022]步骤2:结合大小写字母、数字、下划线、斜杠以及英文句号标志,对步骤1输出的各代码标识符进行分词,再对分词后的长度进行统一并拼接表示。
[0023]其中,经分词后,每一个代码标识符得到一个单词序列,每个单词序列的长度设置为q。q的取值为5。
[0024]对分词后的长度进行统一并拼接表示,具体方法为:
[0025]步骤2.1:若代码标识符所包含的单词数超过了q,则将多出的单词删除;若代码标识符所包含的单词数少于q,则将空余部分用*补齐。
[0026]步骤2.2:将得到的<name
ec
,name
tc
,name
m
>这3个单词序列拼接起来,得到一个长单词序列。该长单词序列所包含的单词数为3个级别的代码标识符所分单词数的和:
[0027]m
input
=concat(name
ec
,name
tc
,name
m
)
ꢀꢀ
(2)
[0028]=concat(w1,w2,

,w
n
),
ꢀꢀ
(3)其中,name
ec
、name
tc
和name
m
分别表示代码函数所在的类名、代码函数可能要重构的目标类名、待检测代码的函数名;w
i
为相对应的代码标识符分解出的单词,下标i的取值范围为1到n,n代表w
i...

【技术保护点】

【技术特征摘要】
1.一种基于局部和全局特征的特征依恋代码味道检测方法,包括模型训练部分和模型测试部分:模型训练包括代码函数表示A、局部特征提取B、全局特征提取C和代码分类味道D;模型测试包括代码函数表示E,局部特征提取F,全局特征提取G和代码味道分类H;其中,代码函数表示A和代码函数表示E是基于Self

Attention神经网络代码函数表示;局部特征提取B和局部特征提取F是基于孪生网络结构的特征提取;全局特征提取C和全局特征提取G是基于卷积神经网络的结构化特征提取;代码味道分类D和代码味道分类H是基于多层感知机的代码味道分类;其特征在于:代码函数A表示和代码函数表示E的操作为:基于Self

Attention神经网络,对被检测的代码函数进行特征表示并进行特征提取,具体方法为:步骤1:将被检测的代码函数所在的类名、目标类名和函数名作为一个元组拼接在一起,输出代码标识符,作为深度语义提取的文本输入,用公式(1)中的符号textual
input
表示:textual
input
=<name
ec
,name
tc
,name
m
>
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(1)其中,name
ec
代表代码函数所在的类名;name
tc
代表代码函数要重构的目标类名;name
m
代表代码函数所在的函数名;name
ec
,name
tc
和name
m
统称代码标识符;步骤2:结合大小写字母、数字、下划线、斜杠以及英文句号标志,对步骤1输出的各代码标识符进行分词,再对分词后的长度进行统一并拼接表示;其中,经分词后,每一个代码标识符得到一个单词序列,每个单词序列的长度设置为q;步骤3:结合大小写字母、数字、下划线、斜杠以及英文句号标志,对步骤1输出的各代码标识符不进行分词;每一个代码标识符仍然得到一个单词序列,每个单词序列的长度设置为q,但接下来不进行拼接;步骤3.1:若代码标识符所包含的单词数超过了q,则将多出的单词删除;若代码标识符所包含的单词数少于q,则将空余部分用*补齐;步骤3.2:将得到的<name
ec
,name
tc
,name
m
>这3个单词序列单独表示起来:mec
input
=concat(name
ec
)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(4)=concat(ecw1,ecw2,

,ecw
n
)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(5)mtc
input
=concat(name
tc
)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(6)=concat(tcw1,tcw2,

,tcw
n
)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(7)mn
input
=concat(name
m
)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(8)=concat(mw1,mw2,

,mw
n
)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(9)其中,mec
input
,mtc
input
,mn
input
分别表示所在类名、目标类名、方法名;步骤4:根据步骤2输出的m
input
,将m
input
长单词序列转换为一个包含有n个单词的长句子,将句子中的每一个单词输入到单词嵌入层将句子中每个单词转换为单词向量;其中,单词嵌入层将输入的每一个单词转换为一个数字向量,称为单词向量;单词嵌入层将每一个单词转换为单词向量,表示如公式(10):V(m
input
)=V(concat(w1,w2,

,w
n
))
=concat(V(w1),V(w2),

,V(w
n
))
ꢀꢀꢀꢀꢀꢀꢀ
(10)其中,V(
·
)表示单词嵌入函数,即将输入的(
·
)转换为相对应的单词向量;V(w
i
)表示将w
i
转换为一个单词向量,下标i的取值范围为1到n;公式(10)表明,将m
input
转换为单词向量等价于将m
input
所包含的每一个w
i
转换为对应的单词向量V(w
i
),再将n个单词向量经concat(
·
)函数连接起来;步骤5:根据步骤3输出的mec
input
,mtc
input
,mn
input
的单个单词序列,不同于步骤4,而是对单个的单词序列mec
input
,mtc
input
,mn
input
变为3个长度为5长句子,将3个句子中的每一个单词输入到单词嵌入层将句子中每个单词转换为单词向量;其中,单词嵌入层将输入的每一个单词转换为一个数字向量,称为单词向量;单词嵌入层将每一个单词转换为单词向量,表示如公式(11)(12)(13):V(mec
input
)=V(concat(ecw1,ecw2,

,ecw
n
))=concat(V(ecw1),V(ecw2),

,V(ecw
n
))
ꢀꢀꢀꢀꢀꢀꢀ
(11)V(mtc
input
)=V(concat(tcw1,tcw2,

,tcw
n
))=concat(V(tcw1),V(tcw2),

,V(tcw
n
))
ꢀꢀꢀꢀꢀꢀꢀ
(12)V(mn
input
)=V(concat(mw1,mw2,

,mw
n
))=concat(V(mw1),V(mw2),

,V(mw
n
))
ꢀꢀꢀꢀꢀꢀꢀ
(13)其中,V(
·
)表示单词嵌入函数,即将输入的(
·
)转换为相对应的单词向量;V(w
i
)表示将w
i
转换为一个单词向量,下标i的取值范围为1到n;公式(11)(12)(13)表明,将mec
input
,mtc
input
,mn
input
转换为单词向量等价于将mec
input
,mtc
input
,mn
input
所包含的每一个w
i
转换为对应的单词向量V(w
i
),再将n个单词向量经concat(
·
)函数连接起来;步骤6:将步骤5输出的单词向量,输入到一个自注意力机制层,输出上下文语义特征m;选用自注意力机制层的原因为:不是所有的隐藏层状态都能平等的反应隐藏在代码中的语义特征,利用自注意力机制层可以自动选择出对代码味道检测有着重要影响的上下文语义特征;其中,上下文语义特征m由步骤5中的单词向量组成:其中,n对应单词序列中的单词数量;h
t
是句子序列中的第t个单词对应的隐藏层状态,即表示时间状态t对应的隐藏层状态;a
t
是h
t
的注意力权重,表示第t个隐藏层状态对代码味道检测的重要程度;对应的每一个隐藏层状态的注意力权重a
t
定义如公式(15)

(16):e(h
t
)=W1tanh(W2h
t
)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(15)其中,W1和W2为权重矩阵;e(
·
)是计算隐藏层状态对代码味道检测重要程度的分数函数;tanh(
·
)是一种非线性激活函数;h
t
表示句子序列中的第t个单词对应的隐藏层状态,t的取值范围是0

n;h
k
表示第k个输入在编码器的输出;经过步骤1到步骤6,完成了代码函数表示,即对代码函数进行特征表示并进行语义特征提取;
局部特征提取B和局部特征提取F的操作为:利用基于孪生网络的深度学习框架,对通过孪生网络进行语义间的相似度计算,对局部特征进行提取;具体如下:步骤7:在步骤5中的mec
input
,mtc
input
,mn
input
的基于Self

Attention的函数表示中,它们的模型是共享参数的,即得到3个单词序列的特征向量,接着将其输入到前馈神经网络中,将mec
input
和mn
input
做余弦相似度计算,并对将mtc
input
和mn
input
做余弦相似度计算,最终得到两个相似度得分,余弦相似度表示如公式(17)所示:经过步骤7的操作,完成了局部特征提取;全局特征提取C和全局特征提取G的操作为:利用基于CNN的深度学习方法,对通过软件重构工具提取出的代码度量结构化信息和被检测的代码函数,进行相应的全局特征提取,具体如下:步骤8:对需要检测的代码进行全局结构化信息提取,得到相应的代码度量;步骤9:对步骤8输出的代码度量进行预处理操作,得到代码函数的结构化信息metric_input;将所有的代码度量分为2组,按照分别为该方法到本类的距离和该方法到目标类的距离,作为全局结构化特征提取部分的输入;其中,结构化信息由metric_input表示:metric_input=concat(dist
mec
,dist
mtc
)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(18)=concat(m1,m2,

,m
i
,

,m
x
).
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
(19)其中,dist
mec
和dist
mtc
分别表示项目、包、类和函数对应的代码度量;x表示结构化信息metric_input包含代码度量的总数;m
i
表示结构化信息中的第i个代码度量,i的取值范围为1到x;步骤10:将步骤9输出的结构化信息metric_input输入到卷积神经网络模型CNN中,得到对应的结构化特征output
l3
;其中,CNN中包括三个卷积层,记为卷积层1、卷积层2以及卷积层3;将结构化信息metric_input转换为一个二维矩阵,并将这个矩阵输入到CNN中的卷积层1;在卷积层1中,使用128个过滤器去获得结构化输入的多维特征,每个过滤器的大小设置为1*1;卷积层1中的每一个卷积操作包括一个过滤器W
l1
(),这个...

【专利技术属性】
技术研发人员:施重阳殷昕江贺
申请(专利权)人:北京理工大学
类型:发明
国别省市:

网友询问留言 已有0条评论
  • 还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。

1