一种基于深度学习的软件代码质量度量方法转让专利

申请号 : CN202110775549.8

文献号 : CN113448857B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 刘辉胡亚敏

申请人 : 北京理工大学

摘要 :

本发明涉及一种基于深度学习的软件代码质量度量方法,属于软件开发与维护技术领域。本方法利用深度学习来学习源代码中标识符的词法语义,并用产生的词法语义以及源代码的结构特征和统计特征来度量代码质量。在相同数据集下,本方法分类不同质量代码的效果和对代码质量的排序,明显优于现有基于代码度量的方法。

权利要求 :

1.一种基于深度学习的软件代码质量度量方法,其特征在于,包括以下步骤:步骤1:构建数据集;

从开源社区下载高质量和低质量的Java项目,从高质量项目和低质量项目中,分别获取高质量代码和低质量代码,这些代码构成了数据集;

其中,所述高质量项目要同时满足以下条件:星数大于500,贡献者数大于30,Pull Request的数量大于300,被评审的Pull Request的比例大于8%;

所述低质量项目要同时满足以下条件:星数为0,贡献者数小于5,Pull Request的数量小于5,被评审的Pull Request数为0;

步骤2:提取特征;

从步骤1获取的高质量代码和低质量代码中提取特征,这些特征被用来训练和评估深度学习模型;

具体地,从Java类中提取以下三类特征:词法特征,即标识符、字段声明和方法头;

结构特征,即抽象语法树和结构格式;

代码度量;

包括以下步骤:

步骤2.1:提取标识符的特征;

首先,从给定的Java类中检索所有标识符;这些标识符根据其在源文件中的位置被表示为序列:

然后,每个标识符被分割成一组软词softWord;该标识符被进一步表示为:;其中,k为软词的数量,idenType为标识符类型,containingNumbers、containingUnderscores、containingDollars分别指示该标识符是否包含数字、下划线和美元符;

最后,每一个软词被表示为:;其中,text为该软词的文本,position为该软词在该标识符中的位置,isInDic指示该软词是否是字典中的词,format指示该软词的格式;

步骤2.2:提取字段声明的特征;

首先,从给定的Java类中检索所有的字段声明:,fieldDeclaration表示字段声明;

然后,每个字段声明被表示为:;其中,k为该字段声明中字段的数量,modifier为该字段声明的权限修饰符,isStatic指示该字段是否是静态的,hasComment指示该字段声明是否有注释;

步骤2.3:提取方法头的特征;

具体实现方法,与步骤2.2提取字段声明特征的方法相同;

步骤2.4:提取抽象语法树的特征;

解析给定Java类中的每个方法的抽象语法树,并将树中每个节点用其类型表示;

步骤2.5:提取结构格式的特征;

从源代码中解析出所有标记,并保留所有特殊标记;然后,用标记的类型替换每个标记;

步骤2.6:提取代码度量的特征;

步骤3:训练模型;

将提取的特征输入到深度学习模型中进行训练,最终得到一个基于深度学习的代码质量度量模型,包括以下步骤:

步骤3.1:设计神经网络;

对每一类输入特征,设计一个深度神经网络,其中:对于文本类型的输入,使用词嵌入技术,将文本标记转换为固定长度的向量;

对于结构格式特征这种变长输入,利用LSTM将其转换为固定长度的向量;

对于元素顺序可忽略的变长输入,利用带注意力机制的全连接网络将其转换为固定长度的向量;

对于抽象语法树,使用LSTM的一种变体,即child‑sum tree‑LSTM,将其转换为固定长度的向量;

步骤3.2:将步骤2提取的特征设定为步骤3.1网络的输入,将对应的质量指数作为输出;

步骤3.3:训练网络,得到一个代码质量度量模型;

步骤4:评估代码质量度量模型;

首先,再次执行步骤2,提取新的Java类的特征;

然后,将步骤2得到的Java类的特征输入到步骤3中得到的代码质量度量模型中;该模型将自动输出一个浮点数,用来指示输入给定Java类的质量。

说明书 :

一种基于深度学习的软件代码质量度量方法

技术领域

[0001] 本发明涉及一种基于深度学习的软件代码质量度量方法,属于软件开发与维护技术领域。

背景技术

[0002] 源代码是软件开发和维护中的关键对象。源代码的质量,特别是其可读性、可扩展性和可维护性,是软件开发人员和维护人员非常关心的问题。
[0003] 软件代码质量涉及多个方面。第一,源代码的功能和性能是否满足用户需求。第二,源代码对于软件开发人员和维护人员是否友好。其中,第二个方面(关注源代码的可读
性和可维护性)通常比第一个方面(关注源代码的功能和性能)更主观,因此,第二个方面更
难量化。
[0004] 现有的代码质量度量方法,严重依赖于传统的代码度量方式,例如代码行数和McCabe的圈复杂度。现有方法通常可以分为两个类别:第一类方法严格遵循软件质量标准
(例如ISO/IEC 9126‑1:2001和ISO/IEC 25010:2011),例如,Washizaki等人提出了一个度
量C语言代码质量的框架,他们选择了236个代码度量(这些度量由现有工具提高计算支
持),并根据ISO/IEC 9126‑1中定义的质量模型将它们聚合成质量子特征或质量特征级别
的的质量指数。第二类方法基于带标签数据,利用机器学习技术来学得复杂的质量模型,例
如,Müller等人训练了一个随机森林分类器,该分类器可以预测给定的代码元素(方法或
类)是否包含质量问题,如bug或测试缺失。该分类器的输入包括生物特征(例如心率变异
性)和传统的代码度量。但是,这些生物特征可能受到程序员的压力水平等因素影响。
[0005] 现有的代码质量度量方法对代码度量的严重依赖,导致这些方法产生的质量指数与人类对代码质量的感知有较大差异。源代码中的自然语言,特别是标识符蕴含丰富的语
义信息。这些语义信息是程序员理解程序业务逻辑的重要来源,因此,这些语义信息对代码
质量有重要影响。例如,用无意义的标识符替换有意义的标识符会显著降低代码质量,特别
是可读性和可维护性。然而,源代码中的自然语言很少被现有度量方法所使用。

发明内容

[0006] 本发明的目的是针对现有软件代码质量度量方法未考虑文本语义,导致度量效果差的缺陷,提出一种基于深度学习的软件代码质量度量方法。
[0007] 本发明的创新点在于:利用深度学习来学习源代码中标识符的词法语义,并用产生的词法语义以及源代码的结构特征和统计特征来度量代码质量。
[0008] 标识符大约占源代码的70%(就字符而言),因此,其对于代码的可理解性至关重要。代码质量度量是非常复杂的,所以统计或启发式方法可能不能有效度量代码质量。因
此,本发明利用深度学习技术(如词嵌入、LSTM、tree‑LSTM、注意力机制和全连接网络)挖掘
标识符的词法语义,并从复杂冗长的输入中自动选择有用的特征,并构建从输入到输出(代
码质量指数)的复杂映射。
[0009] 本发明采用以下技术方案实现。
[0010] 一种基于深度学习的软件代码质量度量方法,包括以下步骤:
[0011] 步骤1:构建数据集。
[0012] 从开源社区(例如GitHub)下载高质量和低质量的Java项目。从高质量项目和低质量项目中,分别获取高质量代码(即Java类)和低质量代码。这些代码构成了数据集。
[0013] 其中,所述高质量项目要同时满足以下条件:星数大于500,贡献者数大于30,Pull Request的数量大于300,被评审的Pull Request的比例大于8%。
[0014] 所述低质量项目要同时满足以下条件:星数为0,贡献者数小于5,Pull Request的数量小于5,被评审的Pull Request数为0。
[0015] 步骤2:提取特征。
[0016] 从步骤1获取的高质量代码和低质量代码中提取特征,这些特征被用来训练和评估深度学习模型。具体地,从Java类中提取三类特征:包括词法特征(即标识符、字段声明和
方法头)、结构特征(抽象语法树和结构格式)以及传统的代码度量。
[0017] 具体地,步骤2包括以下步骤:
[0018] 步骤2.1:提取标识符的特征。
[0019] 首先,从给定的Java类中检索所有标识符。这些标识符根据其在源文件中的位置被表示为序列:
[0020] 然后,每个标识符被分割成一组软词softWord。该标识符被进一步表示为:containingUnderscores,containingDollars>。其中,k为软词的数量,idenType为标识符
类型(如类名称),containingNumbers、containingUnderscores、containingDollars分别
指示该标识符是否包含数字、下划线和美元符。
[0021] 最后,每一个软词被表示为:。其中,text为该软词的文本,position为该软词在该标识符中的位置,isInDic指示该软词是否是字典中的
词,format指示该软词的格式(全小写,只有首字母大写,全大写,或其它)。
[0022] 步骤2.2:提取字段声明的特征。
[0023] 首先,从给定的Java类中检索所有的字段声明:,fieldDeclaration表示字段声明。
[0024] 然后,每个字段声明被表示为:。其中,k为该字段声明中字段的数量,modifier为该字段声明的权
限修饰符(如private),isStatic指示该字段是否是静态的,hasComment指示该字段声明是
否有注释。
[0025] 步骤2.3:提取方法头的特征。
[0026] 具体实现方法,与步骤2.2提取字段声明特征的方法相同。
[0027] 步骤2.4:提取抽象语法树的特征。
[0028] 解析给定Java类中的每个方法的抽象语法树,并将树中每个节点用其类型表示。
[0029] 步骤2.5:提取结构格式的特征。
[0030] 从源代码中解析出所有标记(token),并保留所有特殊标记(如空格和换行符)。然后,用标记的类型替换每个标记(如各种各有的标识符被替换为)。
[0031] 步骤2.6:提取代码度量的特征。
[0032] 可以使用现有工具计算给定类的传统代码度量。
[0033] 步骤3:训练模型。
[0034] 将提取的特征输入到深度学习模型中进行训练,最终得到一个基于深度学习的代码质量度量模型。
[0035] 具体地,步骤3包括以下步骤:
[0036] 步骤3.1:设计神经网络。
[0037] 对每一类输入特征,专门设计一个深度神经网络,其中:
[0038] 对于文本类型的输入,使用词嵌入技术,将文本标记转换为固定长度的向量。
[0039] 对于结构格式特征这种变长输入,利用LSTM将其转换为固定长度的向量。
[0040] 对于元素顺序可忽略的变长输入,利用带注意力机制的全连接网络将其转换为固定长度的向量。
[0041] 对于抽象语法树,使用LSTM的一种变体,即child‑sum tree‑LSTM,将其转换为固定长度的向量。
[0042] 步骤3.2:将步骤2提取的特征设定为步骤3.1网络的输入,将对应的质量指数作为输出。
[0043] 步骤3.3:训练网络,得到一个代码质量度量模型。
[0044] 步骤4:评估代码质量度量模型。
[0045] 首先,再次执行步骤2,提取新的Java类的特征。
[0046] 然后,将步骤2得到的Java类的特征输入到步骤3中得到的代码质量度量模型中。该模型将自动输出一个浮点数,用来指示输入给定Java类的质量。
[0047] 有益效果
[0048] 本发明方法,对比现有技术,具有如下优点:
[0049] 1.在相同数据集下,本方法分类不同质量代码的效果明显优于现有基于代码度量的方法。
[0050] 2.在相同数据集下,本方法对代码质量的排序明显优于现有基于代码度量的方法。

附图说明

[0051] 图1是本发明方法的工作原理示意图;
[0052] 图2是一种用于代码质量评估的深度学习模型示意图。

具体实施方式

[0053] 下面结合附图和实施例对本发明做进一步说明和详细描述。
[0054] 实施例
[0055] 本实施例详细阐述了本发明基于深度学习的代码质量度量方法在具体实施时的方法和效果。
[0056] 步骤A:构建数据集。
[0057] 将构造的数据集的96%作为训练集(用于训练模型),2%作为验证集(用于调整模型的超参数),2%作为测试集(用于测试模型的效果)。在每个数据集中,高质量Java类和低
质量Java类的数量相等。数据集的详细信息如表1所示。
[0058] 表1:数据集信息
[0059]统计量 值
训练集的Java类数量 1,338,733
训练集的代码行数 85,560,826
测试集的Java类数量 27,890
测试集的代码行数 1,821,996
[0060] 步骤B:提取特征。如图1所示,基于开源工具JavaParser,使用步骤2所示的方法为训练集中的每个Java类中提取其词法特征(即标识符、字段声明和方法头)和结构特征(抽
象语法树和结构格式),并使用开源工具ck计算Java类的传统的代码度量。然后,将这些特
征表示为向量,以便输入到深度学习网络中。
[0061] 步骤C:训练模型。
[0062] 在如表2所示的硬件环境下,使用表1所示的训练集对模型进行训练。将提取的特征输入到步骤3设计的深度学习模型中进行训练,最终得到一个代码质量度量模型。
[0063] 表2:硬件环境配置信息表
[0064]
[0065] 如图2所示,模型的输入是根据步骤B从一个Java类中提取的六种特征。每种特征被输入到相应的子网络,以得到它的表示向量。这些表示向量被拼接成一个长向量并输入
到一个全连接网络。全连接网络的激活函数为sigmoid,模型的最终输出为一个0到1的浮点
数。其中,1表示最高质量,0表示最低质量。该浮点数表示输入Java类的质量指数。
[0066] 基于步骤A中的训练集训练图2所示的深度学习模型(优化器为Adam),并使用验证集调整每个子网络的超参数,以提高模型的泛化能力。最终得到了一个基于深度学习的代
码质量度量模型。
[0067] 步骤D:评估模型。
[0068] 从测试集中的每个Java类中提取输入到深度学习模型中六种特征。将步骤D得到的特征输入到步骤C得到的代码质量度量模型中,进行代码质量度量,并评估模型性能。
[0069] 具体为,如果模型的输出(即某个Java类的质量指数)大于0.5,将其分类为高质量,否则分类为低质量。如果分类结果与该Java类的标签相同,则表示该Java类分类正确,
否则分类错误。
[0070] 另外,基于测试集构造了很多Java类对(一个类为高质量,另一个为低质量)。如果模型对高质量Java类输出的质量指数高于低质量的质量指数,则认为本模型可以正确排序
该Java类对。
[0071] 本方法与基于代码度量方法的评估结果如表3所示;
[0072] 表3:本方法与基于代码度量方法的对比
[0073]
[0074] 表3中的准确率(Accuracy)=分类正确的Java类数量/待分类的Java类数量;
[0075] 表3中的精确率(Precision)=正确分类为正例(高质量Java类或低质量Java类)的Java类数量/分类为正例的Java类数量;
[0076] 表3中的召回率(Recall)=正确分类为正例的Java类数量/真实为正例的Java类数量;
[0077] 表3中的F1=1/精确率+1/召回率;
[0078] 表3中的排序准确率=排序正确的Java类对的数量/总的Java类对的数量;
[0079] 结果表明,本方法准确率为95.3%,与现有方法相比,本发明的准确率提高了17.2个百分点。本方法排序准确率为99.1%,与现有方法相比,本发明的排序准确率提高了12.8
个百分点。
[0080] 以上所述为本发明的较佳实施例而已,本发明不应该局限于该实施例和附图所公开的内容。凡是不脱离本发明所公开的精神下完成的等效或修改,都落入本发明保护的范
围。