• 论文中文翻译——A deep tree-based model for software defect prediction


    本论文相关内容

    1. 论文下载地址——Web Of Science
    2. 论文中文翻译——A deep tree-based model for software defect prediction
    3. 论文阅读笔记——A deep tree-based model for software defect prediction


    前言

      此博客为A deep tree-based model for software defect prediction论文的中文翻译,其中有些专业名词的翻译还是不够准确,感觉怎么翻译都翻译不出作者本意来,所以干脆就没翻译某些专业名词,但是不影响文章的阅读,本论文也是非常有水平的一篇论文,提出了非常新颖的漏洞检测的方法,非常值得一读!


    基于DeepTree的软件缺陷预测模型

    作者信息

    Hoa Khanh Dam, University of Wollongong, Australia, hoa@uow.edu.au
    Trang Pham, Deakin University, Australia, phtra@deakin.edu.au
    Shien Wee Ng, University of Wollongong, Australia, swn881@uowmail.edu.au
    Truyen Tran, Deakin University, Australia, truyen.tran@deakin.edu.au
    John Grundy, Deakin University, Australia, j.grundy@deakin.edu.au
    Aditya Ghose, University of Wollongong, Australia, aditya@uow.edu.au
    Taeksu Kim, Samsung Electronics, Republic of Korea, taeksu.kim@samsung.com
    Chul-Joo Kim, Samsung Electronics, Republic of Korea, chuljoo1.kim@samsung.com

    摘要

      缺陷在软件系统中很常见,可能会给软件用户带来各种问题。已经开发了不同的方法来快速预测大型代码库中最可能的缺陷位置。他们大多专注于设计与潜在缺陷代码相关的特性(例如复杂性度量)。然而,这些方法不能充分捕捉源代码的语法和不同层次的语义,这是构建准确预测模型的重要能力。在本文中,我们开发了一种新的预测模型,该模型能够自动学习表示源代码的特征并将其用于缺陷预测。我们的预测系统建立在强大的深度学习的树-结构长短期记忆网络上,该网络与源代码的抽象语法树表示直接匹配。对两个数据集的评估,一个来自Samsung贡献的开源项目,另一个来自公共PROMISE存储库,证明了我们的方法对项目内和跨项目预测的有效性。

    CCS概念

       软件及其工程→软件创建和管理;

    关键词

       软件工程,软件分析,缺陷预测

    ACM参考格式

      Hoa Khanh Dam,Trang Pham,Shien Wee Ng,Truyen Tran,John Grundy,Aditya Ghose,Taeksu Kim和Chul Joo Kim。 2018 2018 2018.基于DeepTree的软件缺陷预测模型。在《XXX、XXX、XXX议事录》中,共 10 10 10页。

    1 引言

      随着软件系统在我们社会的各个领域继续发挥着关键作用,这些软件产生的缺陷对企业和人们的生活产生了重大影响。然而,由于软件代码库在大小和复杂性上的显著增长,识别软件代码中的缺陷变得越来越困难。缺陷预测的重要性和挑战使其成为软件工程中一个活跃的研究领域。大量研究已经开始开发预测模型和工具,帮助软件工程师和测试人员快速缩小软件代码库中最可能存在缺陷的部分。早期缺陷预测有助于确定和优化检查和测试的工作量和成本,尤其是在面临成本和期限压力时。

      机器学习技术已被广泛用于构建缺陷预测模型。这些技术从软件代码中衍生出许多特征(即预测因子),并将它们提供给常见的分类器,如朴素贝叶斯、支持向量机和随机森林。大量研究已经深入到精心设计的特征中,这些特征能够将缺陷代码与非缺陷代码区分开来,例如代码大小、代码复杂度(例如Halstead特征、McAbe、CK特征、MOOD特征)、代码流失度量(例如代码行数变化)、过程度量。然而,这些特性并不能真正反映代码的语法和语义。此外,软件度量特性通常不能很好地概括:在某个软件项目中工作良好的特性在其他项目中可能表现不佳。

      自然语言处理技术也被用来从源文件中的代码标记中提取缺陷预测器。一种常见的技术是使用单词包(BoW),它将代码标记视为术语,并将源文件表示为术语频率。然而,由于代码顺序或句法结构(例如 x ≥ y x≥ y xy y ≥ x y≥ x yx)BoW方法无法检测源代码语义的差异。因此,最近的趋势开始关注在表示源代码时保持代码结构信息。然而,最近的工作并没有对代码的句法结构和代码标记的语义进行完全编码,例如。无法识别“for”和“while”之间的语义关系。

      本文提出了一种新的基于DeepTree的缺陷预测模型。我们利用长短期记忆(LSTM),这是一种强大的深度学习架构,用于捕获源代码中的长期上下文关系,其中依赖的代码元素分散得很远。源代码中的语法和不同层次的语义通常由基于树的结构表示,如抽象语法树(AST)。因此,我们采用了树状结构的LSTM网络,其中我们的预测系统中的LSTM树与输入源文件的AST完全匹配,即每个AST节点对应于基于树的网络中的一个LSTM单元。我们论文的贡献如下。

      (1)源代码的基于DeepTree的LSTM模型,有效地保留了程序的语法和结构信息(就AST而言)。通过AST节点嵌入机制,我们的代码标记表示也保留了它们的语义关系。

      (2)一种预测系统,将表示源文件的“原始”抽象语法树作为输入,并预测该文件是否有缺陷或无缺陷。通过LSTM模型自动学习特征,从而消除了传统方法中占用大部分精力的手动特征工程的需要。

      (3)使用Samsung和PROMISE存储库提供的真实开源项目进行的广泛评估证明了我们的缺陷预测模型的经验优势。

      本文概述如下。在下一节中,我们提供了一个动机示例,然后在第 3 3 3节中概述了我们的方法。第 4 4 4节描述了如何构建预测模型。然后,我们在第 5 5 5节中描述了如何训练和实施模型。我们在第 6 6 6节中报告了一些实验来评估我们的方法。在第 7 7 7节中,我们在总结论文贡献之前讨论了相关工作,并在第 8 8 8节中概述了未来的工作。

    2 动机示例

       我们从一个示例开始,说明了在使用现有方法进行软件预测时所面临的挑战。图 1 1 1显示了两个用Java编写的简单代码列表(Listings)。两者都包含一个 w h i l e while while循环,在该循环中,通过 p o p pop pop操作重复删除给定 s t a c k stack stack顶部的整数。列表 1 1 1(Listing 1 1 1)有一个缺陷:如果给定 s t a c k stack stack的大小小于 10 10 10,当 s t a c k stack stack为空并执行 p o p pop pop操作时,可能会发生下溢异常。列表 2 2 2(Listing 2 2 2)通过在调用 p o p pop pop操作之前检查 s t a c k stack stack是否不是空的来纠正这个问题。

    请添加图片描述

    图1:动机示例

       在上述示例中,现有的缺陷预测技术将面临以下挑战:

      (1)类似的软件度量:两个代码列表在代码行、条件、变量、循环和分支的数量方面是相同的。因此,如果将软件度量(如现有方法中广泛使用的)用作特征,则它们将无法区分。在其他情况下,两段代码可能具有相同的度量,但它们的行为不同,因此有不同的缺陷可能性。

      (2)类似的代码标记和频率:最近的方法研究了实际的代码内容,并将源代码文件表示为与频率相关的代码标记(例如 i n t int int x x x i f if if等)的集合(例如列表 1 1 1中的第 2 2 2 i n t int int)。然后将术语-频率用作缺陷预测的预测因子。然而,这不一定是代码的最佳表示。事实上,两个代码列表中的代码标记及其频率也是相同的。因此,仅依靠术语-频率特性将无法识别列表 1 1 1有缺陷,而列表 2 2 2没有。

      (3)句法和语义结构:这两个代码列表的结构不同,因此行为也不同。 i f if if语句的位置在导致或消除缺陷方面有很大的不同。语法结构还要求成对的代码元素出现在一起(例如,Java中的 t r y try try c a t c h catch catch,或$file \quad open $和 c l o s e close close)。 n − g r a m s n-grams ngrams模型通常用于捕获代码中的重复序列模式。然而, n − g r a m n-gram ngram模型通常仅限于少数代码元素,因此不适用于相关代码元素分散得很远的情况。此外,代码元素并不总是需要遵循特定的顺序,例如,在代码列表 1 1 1中,可以在不改变代码行为的情况下交换第 5 5 5行和第 6 6 6行。

      (4)语义代码标记:代码元素有自己的语义。例如,在Java中,“ f o r for for”和“ w h i l e while while”在语义上是相似的,例如,上述代码列表中的 w h i l e while while循环可以替换为 f o r for for循环,而不改变代码行为。现有的方法经常忽略代码标记的那些语义。

      源代码中的语法和不同层次的语义通常由基于树的结构表示,如抽象语法树(ASTs)。因此,为了解决上述挑战,我们开发了一种基于DeepTree的LSTM神经网络,以对源代码的抽象语法树进行建模。这种表示有效地保留了代码的语法和结构信息,因此用于缺陷预测。

    3 方法

       现有的缺陷预测工作大多集中在确定源文件是否可能有缺陷。这种粒度级别已成为软件缺陷预测文献中的标准。确定源文件是否有缺陷可以被视为函数 p r e d i c t ( f ) predict(f) predict(f),该函数将文件 f f f作为输入,并返回 1 1 1表示有缺陷,返回 0 0 0表示无缺陷。我们通过从训练集中提供的许多示例(即已知有缺陷或无缺陷的文件)中学习来近似该分类函数 p r e d i c t ( x ) predict(x) predict(x)(或也称为模型)。

      我们的预测模型基于长短期记忆,一种强大的深度学习架构。与现有的工作不同,我们的模型被构建为LSTM单元的树状结构网络,以更好地反映源代码中的语法和多层次语义。训练后,学习的函数用于自动确定同一项目(项目内预测)或不同项目(跨项目预测)中新文件的缺陷。通过在基于树的LSTM网络中采用一种新的注意机制,我们的模型还能够定位源文件中可能导致缺陷的部分(例如代码行)。这有助于准确理解和诊断模型所考虑的内容以及特定缺陷的程度。我们方法的关键步骤(见图 2 2 2)如下。

    请添加图片描述

    图2:如何获得代码序列的矢量表示的示例

      (1)将源代码文件解析为抽象语法树(详见第 4.1 4.1 4.1节)。

      (2)将AST节点映射到称为嵌入的连续值向量(第 4.2 4.2 4.2节)。

      (3)将AST嵌入输入到基于树的LSTM网络,以获得整个AST的矢量表示。将该向量输入到传统分类器(如Logistic回归或随机森林),以预测缺陷结果(第 4.3 4.3 4.3节)

       在下一节中,我们将详细描述每个步骤。

    4 模型构建

    4.1 解析源代码

      我们将每个源代码文件解析为抽象语法树(AST)。此过程忽略注释、空行、标点和分隔符(例如大括号、分号和括号)。AST的每个节点表示源代码中出现的一个构造。例如,AST的根表示一个完整的源文件,其子级都是文件的顶部元素,如导入和类声明。每个类声明节点(即 C l a s s O r I n t e r f a c e D e c l a r a t i o n ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration)都有多个子节点,这些子节点表示类的字段( F i e l d D e c l a r a t i o n FieldDeclaration FieldDeclaration)或方法( M e t h o d D e c l a t i o n MethodDeclation MethodDeclation)。方法声明节点还有多个子节点,这些子节点表示其名称、参数、返回类型和主体。

       对于SimpleName节点,我们用其AST类型(例如 F i e l d D e c l a r a t i o n FieldDeclaration FieldDeclaration M e t h o d D e c l a r a t i o n MethodDeclaration MethodDeclaration B l o c k S t m t 和 W h i l e S t m t BlockStmt和WhileStmt BlockStmtWhileStmt)或AST名称(例如变量名、类名和方法名)标记每个树节点(参见图 3 3 3)。常量整数、实数、指数表示法、十六进制数和字符串表示为其类型的AST节点(而不是实际数字或字符串),因为它们特定于方法或类。例如,整数 10 10 10表示为 I n t e g e r L i t e r a l E x p r IntegerLiteralExpr IntegerLiteralExpr节点(见图 3 3 3),而字符串“Hello World”表示为 S t r i n g L i t e r a l E x p r StringLiteralExpr StringLiteralExpr

    请添加图片描述

    图3: Java程序的抽象语法树(AST)示例

       从整个语料库中的所有AST树节点收集的唯一标签名称用于形成词汇表。遵循标准实践,我们还将不太流行的标记(例如,在语料库中只出现一次)和存在于测试集中但不存在于训练集中的标记替换为特殊标记 ⟨ u n k ⟩ ⟨unk⟩ unk。固定大小的词汇表 V \mathscr{V} V基于前 N N N个流行标记构建,罕见标记被分配给 ⟨ u n k ⟩ ⟨unk⟩ unk。这样做可以使我们的语料库紧凑,但仍然提供部分语义信息。

    4.2 嵌入AST节点

       每个AST节点被输入到LSTM单元。由于LSTM单元只接受矢量形式的输入,我们需要将每个AST节点的标签名称映射为固定长度的连续值矢量。我们将此AST节点嵌入过程称为 a s t 2 v e c ast2vec ast2vec

      该过程使用嵌入矩阵 M ∈ R d × ∣ V ∣ \mathcal{M} \in \mathbb{R}^{d \times|\mathscr{V}|} MRd×V,其中 d d d是AST节点嵌入向量的大小, ∣ V ∣ |\mathscr{V}| V是词汇表 V \mathscr{V} V的大小。每个AST节点标签在词汇表中都有一个索引(即编码为一个热向量)。嵌入矩阵用作查找表:AST节点标签 i t h i^{t h} ith被映射到矩阵 M \mathcal{M} M中的列向量 i t h i^{t h} ith。例如,在图 2 2 2中, W h i l e S t m t WhileStmt WhileStmt节点被嵌入到向量 [ − 0.3 , − 0.6 , 0.7 ] [−0.3, −0.6,0.7] [0.3,0.60.7]中,而 I n t e g e r L i t e r a l E x p r IntegerLiteralExpr IntegerLiteralExpr映射到向量 [ 0.2 , 0.1 , 0.2 ] [0.2,0.1,0.2] [0.20.10.2]中。嵌入过程有两个好处。首先,嵌入向量的维数低于一个热向量(即 d < ∣ V ∣ d<|\mathscr{V}| d<V)。其次,在嵌入空间中,频繁出现在相似上下文中的AST节点彼此接近。这通常导致具有相似语义的代码元素成为邻居。例如, W h i l e S t m t WhileStmt WhileStmt F o r S t m t ForStmt ForStmt的嵌入将在嵌入空间中彼此接近。

      嵌入矩阵被随机初始化,然后作为训练过程的一部分进行调整,我们将在第 5 5 5节中讨论。

    4.3 缺陷预测模型

       我们的预测模型表示为函数 p r e d i c t ( ) predict() predict(),它将源文件作为输入,如果文件有缺陷,则返回 1 1 1,否则返回 0 0 0(参见算法 1 1 1)。它首先将源文件解析为抽象语法树(算法 1 1 1中的第 2 2 2行)。AST的根被馈入树-LSTM单元以获得向量表示 h root  \boldsymbol{h}_{\text {root }} hroot (第 3 3 3行)。该向量被输入到传统分类器中,以计算文件有缺陷的概率。如果此概率不小于 0.5 0.5 0.5,则函数返回 1 1 1。否则,它返回 0 0 0(第 4 − 6 4-6 46行)。

      树-LSTM单元(见图 4 4 4)被建模为函数 t − l s t m ( ) t-lstm() tlstm(),该函数将AST节点 t t t作为输入,并输出两个向量: h \boldsymbol{h} h(表示隐藏的输出状态)和 c \boldsymbol{c} c(表示它在AST中记忆的上下文)。这是通过聚合子节点的输出来完成的,即在子节点上递归调用 t − l s t m ( ) t-lstm() tlstm()(第 11 – 26 11–26 11–26行)。该函数首先获得输入AST节点 t t t的嵌入 w t \boldsymbol{w}_{t} wt(使用第 4.2 4.2 4.2节中讨论的 a s t 2 v e c ast2vec ast2vec)。然后,它获得节点 t t t的所有子节点 C ( t ) C(t) C(t),以及每个子节点 k ∈ C ( t ) k∈ C(t) kCt被馈入LSTM单元以获得每个子节点的一对隐藏输出状态和上下文向量 ( h k , c k ) \left(\boldsymbol{h}_{k}, \boldsymbol{c}_{k}\right) (hk,ck)。然后,它们用于计算父节点的一对隐藏输出状态和上下文向量 ( h k , c k ) \left(\boldsymbol{h}_{k}, \boldsymbol{c}_{k}\right) (hk,ck),如下所示。

    请添加图片描述

    图4:树-LSTM单元的内部结构

       如何将信息嵌入 w t \boldsymbol{w}_{t} wt ( h k , c k ) \left(\boldsymbol{h}_{k}, \boldsymbol{c}_{k}\right) (hk,ck)(对于所有 k ∈ C ( t ) k∈ C(t) kC(t))流通过树-LSTM单元由三个重要组件控制:输入门(表示为 i t \boldsymbol{i}_{t} it)、输出门( o t \boldsymbol{o}_{t} ot)和多个遗忘门(每个子节点 k k k的一个 f t k \boldsymbol{f}_{tk} ftk)。这些分量取决于子节点的输入 w t \boldsymbol{w}_{t} wt和输出状态 h k \boldsymbol{h}_{k} hk。这些相关性以参数矩阵组编码:( W f o r W_{for} Wfor U f o r U_{for} Ufor b f o r b_{for} bfor)用于遗忘门,( W i n W_{in} Win U i n U_{in} Uin b i n b_{in} bin)用于输入门,( W o u t W_{out} Wout U o u t U_{out} Uout b o u t b_{out} bout)用于输出门。

      一个树-LSTM单元具有多个遗忘门 f t k \boldsymbol{f}_{tk} ftk,每个子节点 k k k有一个遗忘门,并计算为 w t \boldsymbol{w}_{t} wt h k \boldsymbol{h}_{k} hk上的 s i g m o i d sigmoid sigmoid函数(第 17 17 17行)。遗忘门 f t k \boldsymbol{f}_{tk} ftk的值介于 0 0 0 1 1 1之间,这使得树-LSTM单元能够选择性地包括来自每个子级的信息。来自子节点的输出被组合起来作为父-LSTM单元的输入(第 19 19 19行)。这些新信息在存储单元中的存储量由两种机制控制(第 20 – 22 20–22 20–22行)。首先,表示为 s i g m o i d sigmoid sigmoid函数的输入门 i k \boldsymbol{i}_{k} ik控制将更新哪些值。其次,使用 t a n h tanh tanh函数创建一个新的候选值 c t ~ \tilde{\boldsymbol{c}_{t}} ct~的向量,该向量将添加到存储单元中。

      通过将每个孩子的旧记忆乘以 f t k \boldsymbol{f}_{tk} ftk来更新新记忆,而不考虑我们早先决定忘记的事情。 我们对所有子节点求和,然后将其与 c t ~ \tilde{\boldsymbol{c}_{t}} ct~相加。最后,输出是存储器的过滤版本,由输出门 o t \boldsymbol{o}_{t} ot(第 23 23 23行)控制。我们将 t a n h tanh tanh函数应用于存储器(以将值缩放到 − 1 -1 1 1 1 1之间),并将其乘以 s i g m o i d sigmoid sigmoid门的输出,从而仅输出一些选定的部分(第 24 24 24行)。

    请添加图片描述

    5 模型训练

    5.1 训练树-LSTM

       我们以无监督的方式训练树-LSTM单元,即不使用真实缺陷标签。我们利用AST的强预测性,即如果我们知道所有子代的标签名称,我们就可以预测其父代的标签名。使用大量的AST分支,我们通过进行这样的预测来训练树-LSTM单元。例如,“<”和“VariableDeclarator”的父级是“WhileStmt”,而“x”和“IntegerLiteralExpr”的父亲是“<”(见图 5 5 5)。

    请添加图片描述

    图5:通过从父节点的子节点预测父节点的标签名称来训练树-LSTM

       具体地说,每个AST节点 w t \boldsymbol{w}_{t} wt具有一组子节点 C ( t ) C(t) Ct,每个节点 c k ∈ C ( t ) c_{k}∈ C(t) ckCt具有输出状态 h k h_{k} hk。我们可以通过softmax函数使用父节点的所有子隐藏状态来预测父节点的标签名称:
    P ( w t = w ∣ w c 1.. c k ) = exp ⁡ ( U t h ~ t ) ∑ w ′ exp ⁡ ( U w ′ h ~ t ) P\left(w_{t}=w \mid w_{c 1 . . c k}\right)=\frac{\exp \left(U_{t} \tilde{h}_{t}\right)}{\sum_{w^{\prime}} \exp \left(U_{w^{\prime}} \tilde{h}_{t}\right)} P(wt=wwc1..ck)=wexp(Uwh~t)exp(Uth~t)

       其中 U k U_k Uk是一个自由参数并且 h ~ t = 1 ∣ C ( t ) ∣ ∑ k = 1 ∣ C ( t ) ∣ h k \tilde{h}_{t}=\frac{1}{|C(t)|} \sum_{k=1}^{|C(t)|} h_{k} h~t=C(t)1k=1C(t)hk

       设 θ θ θ为LSTM单元中所有参数的集合,包括嵌入矩阵 M \mathcal{M} M和权重矩阵( W f o r W_{for} Wfor U f o r U_{for} Ufor b f o r b_{for} bfor)、( W i n W_{in} Win U i n U_{in} Uin b i n b_{in} bin)、( W c e W_{ce} Wce U c e U_{ce} Uce b c e b_{ce} bce)和( W o u t W_{out} Wout U o u t U_{out} Uout b o u t b_{out} bout)。这些参数被随机初始化,然后通过训练过程学习。训练包括三个主要步骤:(i)将训练数据中的AST分支输入到LSTM单元,以获得该分支中父节点的标签名称的预测;(ii)比较预测结果和实际结果之间的差值 δ δ δ;(iii)调整模型参数的值,使得差值 δ δ δ最小化。此过程对训练数据中的所有文件进行迭代。

      为了测量模型参数的一组特定值的质量,我们定义了一个损失函数 L ( θ ) L(θ) Lθ,它基于预测结果和实际结果之间的差值 δ δ δ。产生正确预测的模型参数 θ θ θ的设置(例如,父节点的标签名称被正确预测)将具有非常低的损失 L L L。因此,通过找到最小化损失函数的参数 θ θ θ集的优化过程来实现学习。

       由于模型中的每个分量都是可微的,所以我们使用广泛使用的随机梯度下降来执行优化。优化过程通过反向传播完成:模型参数 θ θ θ沿损失函数 L ( θ ) L(θ) Lθ梯度的相反方向更新。学习速率 η η η用于控制我们朝着最佳参数前进的快慢。大的学习速率可能会错过最优解,而小的学习速率将需要太多的迭代才能收敛到最优解。我们使用RMSprop,一种自适应随机梯度方法(Geoffrey Hinton未发表的内容),已知它对递归模型最有效。我们通过将数据划分为互斥的训练、验证和测试集并运行多个训练阶段来调整RMSprop。具体来说,训练集用于学习有用的模型。在每个训练时期之后,在验证集上评估学习模型,并使用其性能来评估超参数(例如梯度搜索中的学习率)。请注意,验证集未用于学习模型的任何参数。选择验证集中性能最佳的模型在测试集上进行评估。我们还采用了提前停止策略,即在验证阶段监控模型的性能,当性能变差时停止。

       我们还在我们的模型中实现了dropout ,这是一种防止神经网络过度拟合的有效机制。这里,输入和输出状态的元素在训练期间被随机设置为零。在测试期间,使用参数平均值。实际上,dropout隐式地并行训练许多模型,并且所有模型共享相同的参数集。最终模型参数表示这些模型中参数的平均值。通常,dropout率设置为 0.5 0.5 0.5。我们在Theano和Keras框架中实现了该模型,并在Python中运行。Theano支持损失函数的自动微分和一系列强大的自适应梯度下降方法。Keras是一个使模型构建更容易的包装器。我们使用噪声对比估计来计算softmax函数。我们还针对一个验证集运行多个epoch以选择最佳模型。我们使用困惑度,一种基于对数损失的常见内在评估指标,作为选择最佳模型和提前停止的标准。

    5.2 训练缺陷预测模型

      上述过程使我们能够自动为训练集中的所有源文件生成特征。然后,通过从训练集中提供的多个示例(即已知有缺陷或无缺陷的文件)学习,使用这些文件及其特征和标签(即有缺陷或无缺陷的文件)来训练机器学习分类器。我们尝试了两种备选分类器:Logistic回归和随机森林。Logistic回归使用Logistic函数(也称为sigmoid函数)来近似给定AST特征向量表示的源文件有缺陷的概率。随机森林(RFs)是一种随机集成方法,它结合了许多决策树的估计来进行预测。

    6 评估

    6.1 数据集

       Samsung贡献的开源项目:Samsung电子贡献了多种开源项目,如开源操作系统Tizen。Tizen在Samsung的各种设备上运行,包括智能手机、平板电脑、车载信息娱乐设备、智能电视、智能相机、可穿戴计算(如Gear等智能手表)、智能家电(如冰箱、洗衣机、空调和烤箱/微波炉)。我们从这些开源项目中收集了潜在的缺陷。为了识别有缺陷的文件,我们使用了Samsung使用的静态分析工具,该工具对目标项目具有特定支持。该工具扫描这些项目的源代码,并生成一份报告,描述它可以发现的所有潜在缺陷(即警告)。警告有不同的类型和严重级别。在这项研究中,我们重点关注关键资源泄漏警告(例如,创建了句柄,但没有释放句柄就丢失了)。 我们使用这些信息将文件标记为有缺陷或无缺陷:如果工具报告了至少一个与该文件相关的资源泄漏警告,则认为该文件有缺陷。我们建立了一个由 8118 8118 8118个用C语言编写的文件组成的数据集,其中 2887 2887 2887个( 35.6 % 35.6\% 35.6%)文件被标记为有缺陷, 5231 5231 5231个( 64.4 % 64.4\% 64.4%)被标记为无缺陷。

      PROMISE数据集:我们还使用了一个可从PROMISE数据库公开获取的缺陷预测数据集。为了便于比较,我们从这个数据集中选择了与[28]中相同的 10 10 10个Java项目和发布版本。这些项目涵盖了多种应用程序领域,如XML解析器、文本编辑器、企业集成框架和文本搜索引擎库(见表 1 1 1)。所提供的数据集仅包含项目名称、其发布版本、文件名及其缺陷标签。它没有我们研究所需的文件源代码。使用提供的文件名和版本号,然后我们从每个应用程序的代码库中检索相关的源文件。

    表1:数据集统计

    请添加图片描述

      当处理PROMISE数据集提供的CSV电子表格时,我们发现存在内部类的条目。由于内部类包含在其父类的AST中,所以我们从数据集中删除了这些条目。我们还删除了用Scalar编写的源文件条目,以及无法检索相应源文件的条目。总共从CSV电子表格中删除了 264 264 264个条目。表 1 1 1提供了数据集中的一些描述性统计数据。

    6.2 性能测试

       报告两个类(有缺陷和无缺陷)的平均准确度/召回率可能会高估真实性能,因为我们的数据集是不平衡的(即有缺陷的文件数量很少)。更重要的是,预测有缺陷的文件比预测无缺陷的文件更有意义。因此,我们的评估重点是缺陷类。

       混淆矩阵用于存储预测模型做出的正确和错误决策。例如,如果一个文件在确实有缺陷时被分类为有缺陷,那么该分类就是真阳性( t p tp tp)。如果文件在实际无缺陷时被分类为有缺陷,则该分类为假阳性( f p fp fp)。如果文件在实际存在缺陷时被分类为无缺陷,则该分类为假阴性( f n fn fn)。最后,如果问题被归类为“无缺陷”,并且事实上是“无缺陷”的,那么该分类是真阴性( t n tn tn)。存储在混淆矩阵中的值用于计算广泛使用的准确度、召回率和F-度量。

    • 准确度:正确预测的缺陷文件与所有预测为缺陷的文件的比率。计算如下:

    p r = t p t p + f p p r=\frac{t p}{t p+f p} pr=tp+fptp

    • 召回率:正确预测的缺陷文件与所有真实缺陷文件的比率。计算如下:

    r e = t p t p + f n r e=\frac{t p}{t p+f n} re=tp+fntp

    • F-度量:测量准确度和召回率的加权调和平均值。计算如下:

    F −  measure  = 2 ∗ p r ∗ r e p r + r e F-\text { measure }=\frac{2 * p r * r e}{p r+r e} F measure =pr+re2prre

    • ROC曲线下面积(AUC)用于评估模型实现的辨别程度。AUC的值范围从 0 0 0 1 1 1,随机预测的AUC为 0.5 0.5 0.5。AUC的优点是它对决策阈值(如准确度和召回率)不敏感。AUC越高表示预测越好。

    6.3 结果

    6.3.1 项目内预测

      这个实验使用了来自同一项目的数据进行训练和测试。对于Samsung数据集,我们无法追溯源文件属于哪个项目,因此我们将数据集中的所有源文件视为属于单个项目。我们采用了交叉验证,并将该数据集中的文件分为十个部分,每个部分在缺陷文件和无缺陷文件之间的比例大致相同。每个折叠用作测试集,其余折叠用于训练。因此,我们构建了十个不同的预测模型,并将性能指标从十个倍数中取平均值。我们还用两种不同的分类器进行了测试:随机森林和Logistic回归。

       图 6 6 6显示了我们的方法对Samsung数据集的预测性能。使用随机森林(RF)作为分类器的预测模型产生了令人印象深刻的结果,所有四个性能指标(F-度量、准确度、召回率和AUC)都远高于 0.9 0.9 0.9。使用Logistic回归(LR)实现了非常高的召回率,但同时它似乎产生了许多误报,因此其准确度远低于RF产生的精度。两种分类器的AUC均远高于 0.5 0.5 0.5阈值(RF为 0.98 0.98 0.98,RF为 0.60 0.60 0.60),这表明我们的方法明显优于随机预测。

    请添加图片描述

    图6:我们的方法对Samsung数据集的预测性能

      对于PROMISE数据集,由于它包含相同应用程序的不同版本,我们遵循Wang等人[28]中的设置,并使用每个项目的两个连续版本进行训练和测试。具体来说,旧版本的源代码用于训练模型,而新版本用于测试模型。我们总共进行了 16 16 16组实验,与Wang等人的实验完全相同。我们还使用随机森林和Logistic回归作为分类器进行了测试,并观察到了不同的结果(与Samsung数据集的结果相比):使用LR比使用RF产生了更好的预测性能。这可以解释为PROMISE数据集具有少量数据点,这更适合LR。

      由于篇幅限制,我们这里只报告了使用LR作为分类器的结果(见图 7 7 7)。我们的预测模型产生的平均AUC为 0.6 0.6 0.6,远高于随机预测阈值。更重要的是,它实现了非常好的召回率 0.86 0.86 0.86(平均 16 16 16例),比Wang等人的方法提高了 23 % 23\% 23%。然而,与Wang等人的方法相比,我们的方法具有更低的准确度,导致F-度量( 17 % 17\% 17%)的减少。我们注意到,在预测缺陷时,高召回率通常是优选的,因为遗漏缺陷的成本远高于误报。

    请添加图片描述

    图7:我们对Samsung数据集的方法的预测性能(项目预测内)。X轴在每个项目中都有成对的训练(较低版本)和测试数据(较新版本)。例如,在第一对中,我们的模型使用Apache Ant项目的1.5版进行了训练,并使用其1.6版进行了测试。
    6.3.2 跨项目预测

      由于缺乏培训数据,预测新项目中的缺陷通常很困难。解决这个问题的一种常见技术是使用来自(源)项目的数据训练模型,并将其应用于新的(目标)项目。我们通过从PROMISE数据集中的项目中选择一个版本作为源项目(例如ant 1.6 1.6 1.6),从另一个项目中选择另一个版本为目标项目(例如camel 1.4 1.4 1.4)来进行此实验。图 8 8 8总结了 22 22 22对源和目标Java项目的跨项目预测结果。

    请添加图片描述

    图8:我们对Samsung数据集的方法的预测性能(跨项目预测)。X轴有成对的训练(源项目)和测试数据(目标项目)。例如,在第一对中,我们的模型使用Apache Ant项目的1.6版进行了训练,并使用Camel项目的1.4版进行了测试。

       我们的方法再次实现了非常高的召回率,在跨项目预测中, 22 22 22个案例的平均召回率为 0.8 0.8 0.8。有 15 15 15例召回率高于 0.8 0.8 0.8。然而,由于项目内预测的精度较低,平均F-度量为 0.5 0.5 0.5。然而,平均AUC仍远高于 0.5 0.5 0.5阈值,这证明了我们方法在预测缺陷方面的总体有效性。

    6.4 有效性的威胁

       我们的研究的有效性面临许多威胁,我们将在下面讨论。我们不仅在我们的内部数据集上,而且在公开可用的数据集(PROMISE数据集)上评估我们的方法,从而减轻了构造有效性的担忧。两个数据集都包含真实的项目。不幸的是,PROMISE数据集不包含源文件。然而,我们仔细使用了数据集提供的信息(例如应用程序详细信息、版本号和日期),从这些应用程序的代码库中检索相关的源文件。我们试图通过使用缺陷预测的标准性能度量来最小化对结论有效性的威胁。然而,我们知道可以应用一些统计测试来验证我们的结论的统计意义,我们计划在未来的工作中进行这一点。

       关于内部有效性,我们使用的Samsung数据集包含有缺陷的标签,这些标签来自Samsung内部使用的静态分析工具提供的警告。我们承认这些警告可能包含误报,因此未来的工作将涉及调查这些警告并确认其有效性。此外,我们没有源代码来复制Wang等人的实验,因此必须依赖他们报告的结果与我们的方法进行比较。就外部有效性而言。我们考虑了大量的应用程序,它们在编程语言、大小、复杂性、领域、流行度和修订历史上都有很大的不同。然而,我们承认我们的数据集可能不能代表所有类型的软件应用程序。进一步调查,以确认我们对其他类型应用程序(如web应用程序和其他编程语言(如PHP和C++)编写的应用程序的发现。

    7 相关工作

    7.1 缺陷预测

       过去,缺陷预测研究面临着多重挑战(例如,数据缺乏可用性、多样性和粒度等问题)。不同研究人员最近取得的成就在为不同问题提供解决方案(如开源软件的引入)方面产生了巨大影响。

      在设计用于缺陷预测的特征方面已经进行了大量的研究,这些特征可以分为静态代码特征和过程特征。静态代码特性可以进一步细分为代码大小和代码复杂性(例如Halstead特性、McAbe特性、CK特性、MOOD特性)。过程特性测量发布开发过程中的更改活动,以便构建更准确的缺陷预测模型。使用过程度量的动机来自于软件开发中使用的不同过程如何可能导致缺陷。过程度量的使用独立于编程语言,因此可以在广泛的项目中使用。基于不同机器学习技术(如随机森林)的模型,利用前面描述的特征,在同一项目内或在不同项目间进行评估。

       项目内预测使用来自同一项目的数据来构建模型。使用这种方法需要大量数据才能有效。Zimmermann等人提出了在构建缺陷预测模型时使用网络度量,该模型已被评估为比使用复杂性度量更好。具体来说,对Windows Server 2003 2003 2003的依赖关系图进行了网络分析。最近广泛使用的另一种方法是构建跨项目缺陷预测模型。Li等人提出了一种使用深度学习(即卷积神经网络)进行缺陷预测的方法。所提出的通过卷积神经网络(DP-CNN)进行缺陷预测的框架在评估时比现有方法(例如传统的DBN)在缺陷预测方面表现更好。

      跨项目预测使用其他项目的历史数据来训练模型。Zimmermann等人使用 12 12 12种不同的应用评估了 622 622 622个跨项目缺陷预测模型。建立一个准确的跨项目预测模型是困难的,克服这一挑战对于没有足够数据建立模型的情况具有重要意义。Zhang等人在使用上下文感知秩变换对预测因子进行预处理后,从不同的项目构建了通用的缺陷预测模型。通用模型的性能与项目内预测以及与其他五个项目进行测试时的性能相似。

      缺陷预测是软件分析中非常活跃的领域。由于缺陷预测是一个广泛的领域,我们在这里强调了一些主要工作,并请读者参阅其他综合评论以了解更多细节。代码度量通常用作构建缺陷预测模型的特征。还采用了各种其他度量,如变更相关度量、开发人员相关度量、组织度量和变更过程度量。

      最近,许多方法利用称为深度信念网络(DBN)的深度学习模型来自动学习缺陷预测的特征,并证明了预测性能的改进。事实上,根据Wang等人报告的评估,他们的DBN方法优于软件度量和单词包方法。然而,DBN不能自然地捕获源代码中的顺序排列和长期依赖关系。大多数缺陷预测研究都是在文件级进行的。最近的方法在方法层面和线路层面解决了这个问题。由于我们的方法能够在代码标记级别学习特性,因此它可以在更精细的粒度级别上工作。然而,这需要开发新的数据集,这些数据集包含带有缺陷标签的方法和代码行,我们将其留给未来的工作。

    7.2 代码建模中的深度学习

      深度学习最近在软件工程中引起了越来越多的兴趣。在我们最近的愿景论文中,我们提出了DeepSoft,一种基于LSTM的通用深度学习框架,用于建模软件及其开发和进化过程。我们已经证明了如何利用LSTM来学习软件演化中发生的长期时间依赖关系,以及如何使用这种深度学习模式来解决从需求到维护的一系列具有挑战性的软件工程问题。我们目前的工作实现了其中一个愿景。

      [30]中的工作证明了使用递归神经网络(RNN)对源代码建模的有效性。他们后来的工作扩展了这些RNN模型,用于检测代码克隆。[9]中的工作使用了一种特殊的RNN编码器-解码器,该编码器包括一个用于处理输入序列的编码器RNN和一个用于生成输出序列的解码器RNN,以生成给定API相关自然语言查询的API使用序列。[10]中的工作还使用RNN编码器-解码器,但用于修复C程序中的常见错误。[16]中的工作使用卷积神经网络(CNN)进行错误定位。我们早期工作的初步结果也表明,LSTM是一种更有效的源代码语言模型。我们在本文中的工作也开发了源代码的表示,但我们使用树-LSTM来更好地匹配代码的抽象语法树表示。

    8 结论和未来工作

       我们提出了一种新的方法来预测源代码中的缺陷。我们的预测模型将表示源文件的抽象语法树(AST)作为输入,这是源代码的通用表示,并预测文件是否有缺陷或无缺陷。我们的预测系统建立在强大的深度学习长短期记忆(LSTM)架构之上,以捕获代码元素之间经常存在的长期依赖关系。我们新颖地使用了树结构LSTM网络(Tree-LSTM),自然地与AST表示相匹配,从而充分地捕获了源代码中的语法和不同级别的语义。我们的预测系统中使用的所有特征都是通过训练Tree-LSTM模型来自动学习的,从而省去了传统方法中需要人工进行特征工程的大部分工作。我们对Samsung和PROMISE存储库提供的两个不同的数据集进行了评估。我们的评估结果表明,我们的方法可以应用于实践。

       我们未来的工作涉及将这种方法应用于其他类型的应用程序(例如Web应用程序)和编程语言(例如PHP或C++)。我们还打算扩展我们的方法,以预测方法和代码更改级别的缺陷。此外,我们计划探索如何将我们的方法扩展到预测特定类型的缺陷,如代码中的安全漏洞和安全关键危害。最后,我们未来的开发还包括将我们的预测模型构建成一个工具,该工具可用于支持现实环境中的软件工程师和测试人员。

    致谢

       作者感谢Samsung通过其2016年全球研究拓展计划提供的支持。


    总结

      到此为止本篇论文的中文翻译就结束了,可以看到本篇论文的篇幅并不是特别长,共1.2万字左右,但是花费了我将近一个星期的时间翻译。总而言之,本篇论文值得一读,那我们就下篇论文中文翻译见了!

  • 相关阅读:
    出生医学证明识别易语言代码
    2023辽宁省数学建模B题数据驱动的水下导航适配区分类预测完整原创论文分享(python求解)
    【Hack The Box】windows练习-- Bankrobber
    访问控制列表配置实验
    大规模 IoT 边缘容器集群管理的几种架构-2-HashiCorp 解决方案 Nomad
    死锁Deadlock
    Charles的功能操作
    各种文件后缀的意义(持续更新中)
    编写自己的 WordPress 模板
    怎么写综述类论文? - 易智编译EaseEditing
  • 原文地址:https://blog.csdn.net/IronmanJay/article/details/127715417