摘 要:为了提高多标签代码坏味检测的准确率,提出一种基于预训练模型与BiLSTM-CNN的多标签代码坏味检测方法DMSmell(deep multi-smell)。首先,利用静态分析工具获取源代码中的文本信息和结构度量信息,并采用2种检测规则对代码坏味实例进行标记;其次,利用CodeBERT预训练模型生成文本信息对应的词向量,并分别采用BiLSTM和CNN对词向量和结构度量信息进行深度特征提取;最后,结合注意力机制和多层感知机,完成多标签代码坏味的检测,并对DMSmell方法进行了性能评估。结果表明:DMSmell方法在一定程度上提高了多标签代码坏味检测的准确率,与基于分类器链的方法相比,精确匹配率提高了1.36个百分点,微查全率提高了2.45个百分点,微F1提高了1.1个百分点。这表明,将文本信息与结构度量信息相结合,并利用深度学习技术进行特征提取和分类,可以有效提高代码坏味检测的准确性,为多标签代码坏味检测的研究和应用提供重要的参考。
关键词:软件工程;代码坏味;预训练模型;多标签分类;深度学习
中图分类号:TP311 文献标识码:A
Multi-label code smell detection method based on
pre-trained model and BiLSTM-CNN
Abstract:
To improve the accuracy of multi-label code smell detection, a multi-label code smell detection method DMSmell (Deep Multi-Smell) based on pre-trained model and BiLSTM-CNN was proposed. Firstly, the static analysis tool was used to obtain the text information and structural metric information in the source code, and two detection rules were adopted to label the code smell instances; Secondly, the pre-training model of CodeBERT was used to generate the word vectors corresponding to the textut8pWeUEszebtBMQSf9uClT5IrYWpkQsyfW+EY/k9NlI=al information, and the deep feature extraction of the word vectors and the structural metric features were performed by using BiLSTM and CNN, respectively; Finally, the detection of multi-label code smell was accomplished by combining the attention mechanism and multi-layer perceptron, and the performance of the DMSmell method was evaluated. The results show that the DMSmell method improves the accuracy of multi-label code smell detection to a certain extent. Compared with the classifier chain-based method, the accurate match ratio has improved by 1.36 percentage points, the micro-recall rate has improved by 2.45 percentage points, and the micro-F1 has improved by 1.1 percentage points. The results show that the combination of textual information with structural metric information and the use of deep learning techniques for feature extraction and classification can effectively improve the accuracy of code smell detection, which provides an important reference for the research and application of multi-label code smell detection.
Keywords:
software engineering; code smell; pre-trained model; multi-label classification; deep learning
代码坏味(code smell)是指低质量的代码片段,它们可能不会直接导致代码功能上的错误,但若未能及时发现并解决,可能会影响后期代码的可读性,导致代码质量下降,增加软件后期的维护成本。代码坏味的检测是确定软件重构位置的前提条件,因此,代码坏味检测一直是软件工程领域的研究热点之一。
目前具有代表性的代码坏味检测工具有PMD,iPlasma[1]和JDeodorant[2]。这些检测工具采用启发式规则的方法,具备简单、便捷的特点,并得到了广泛的应用,但是仅依靠工具开发人员预先定义的启发式规则难以覆盖所有代码坏味。此外,不同工具的开发人员对同一代码坏味的定义有不同的理解,这会导致最终的检测结果缺乏一致性和可靠性。为了解决上述问题,研究人员尝试使用机器学习算法来完成代码坏味检测。SANDOUKA等[3]构建了一个用于检测上帝类和长方法的Python代码坏味数据集,并在该数据集上用6种机器学习模型进行实验以检测其性能,得出了不同的机器学习模型对不同代码坏味类型具有不同性能表现的结论。此外,BRDAR等[4]提出基于半监督学习的检测方法,将手动标记的代码坏味数据集与未标记的代码片段相结合来训练半监督模型,并在2种代码坏味上进行了方法性能评估。结果表明,该方法略优于基于监督学习的检测方法,证明了半监督学习方法在代码坏味检测方面的巨大潜力。随着深度学习技术在图像识别、自然语言处理等领域的广泛应用,研究人员将深度学习代替机器学习用于代码坏味检测。如YU等[5]提出一种基于图神经网络的特征依恋检测方法,将代码结构度量信息和调用关系转换为图的形式,并利用图神经网络模型进行训练和检测,结果表明,该方法的平均微F1值达到了78.90%,比基准方法高出37.98%,提高了特征依恋代码坏味的检测水平。
在软件开发过程中,同一代码片段往往存在多种代码坏味问题。上述的单标签检测方法无法做到准确识别和标记多种代码坏味,从而导致开发人员难以有效进行重构。因此,研究者提出运用多标签代码坏味检测来解决此问题。GUGGULOTHU等[6]提出使用多标签分类方法来检测给定代码片段的多种代码坏味,该研究中将NUCCI等[7]工作中的数据集合并成多标签数据集,并比较了分类器链方法和标签组合方法在多标签代码坏味检测上的性能表现。结果表明,分类器链方法的性能优于标签组合方法,且平均准确率为91%。KIYAK等[8]提出使用机器学习算法来检测多标签代码坏味,并验证了5种不同基分类器的性能。结果表明,随机森林分类器在2个多标签数据集上的性能明显优于其他分类器。王继娜等[9]提出一种基于排序损失的集成分类器链ECC(ensemble of classifier chains)多标签代码坏味检测方法,该方法以排序损失最小为目标,并选取随机森林算法作为基分类器,通过多次迭代ECC方法来优化代码坏味检测的顺序问题,进而提高检测准确率。结果表明,ECC方法优于现有的多标签代码坏味检测方法。
虽然现有的方法在多标签代码坏味检测上已经取得一定的成效,但仍存在以下2个方面的问题:1) 目前存在的多标签代码坏味检测方法都是基于机器学习算法,缺乏基于深度学习的多标签代码坏味检测方法的研究;2) 现有的多标签数据集[10]仅包含源代码的结构度量信息,缺乏源代码的文本信息,且数据量较小,不足以支撑深度学习模型的训练。
针对上述多标签代码坏味检测存在的问题,本文构建了一个将源代码度量信息和文本信息相结合的多标签数据集,并提出一种基于预训练模型与BiLSTM-CNN的多标签代码坏味检测方法,该方法采用多个深度学习模型相结合的方式,提高了多标签代码坏味检测的准确率。
1 方法提出
本文提出一种基于预训练模型与BiLSTM-CNN的多标签代码坏味检测方法DMSmell,基本框架如图1所示。首先,从GitHub上选择了多个领域的Java实际应用程序作为语料库;其次,遍历抽象语法树获得源代码的文本信息,并采用iPlasma静态分析工具获取结构度量信息;然后,应用2种规则对每个代码坏味实例标记多个标签,并将文本信息、结构度量信息以及标签信息相结合生成多标签数据集,以此作为DMSmell模型的输入,该模型中的BiLSTM负责文本信息的全局特征提取,CNN负责结构度量信息的深层次特征提取;最后,将BiLSTM与CNN提取的重要特征进行融合,并以多层感知机(multilayer perceptron)作为多标签分类器,从而实现多标签代码坏味检测。
2 方法实现
2.1 数据集生成
为了使数据集多样化,本文从GitHub上选取了单元测试、文本编辑、数据库系统等多个领域的开源项目作为语料库,所选取的项目总代码行数有150多万行,包含18 544个类和144 964个方法。数据集形式如图2所示。
为了获取文本信息,本文使用了一个自动提取工具[11],该工具可自动将源程序进行抽象语法树解析,再通过一个具体的访问者类遍历所有抽象语法树节点,进而获取包名称、类名称以及方法名称。
结构度量信息是代码坏味检测研究中常用的判断依据,在检测不同代码坏味时结构度量信息往往扮演着不同的角色,不同结构度量信息通常被赋予不同的权重。本文使用静态分析工具iPlasma获取了结构度量信息,并选取了20种结构度量信息,这些结构度量信息涵盖了代码规模、复杂度、内聚度以及耦合度4个方面的代码结构特征,其详细介绍如表1所示。
因为在软件开发中特征依恋和长方法是较为常见且被广泛研究和探讨的代码坏味[12],所以本文选用这2种代码坏味作为研究对象。
为了对数据集中的代码坏味实例进行标记,本文尽可能选择多种被广泛应用的检测规则。表2给出了2种代码坏味的描述以及判定规则。本文通过编写一段程序自动完成对于多种检测规则识别的代码坏味进行标记,只有当样本符合所有检测规则时
才会被标记为1(表示有坏味),其他情况下该样本均被标记为0(表示无坏味)。得到的多标签代码坏味形式类似于One-Hot编码[6],如(1, 0)表示当前样本中有特征依恋、无长方法坏味。最终,通过多名实验室人员运行编写的自动检测程序,对生成的多标签数据集进行了检测,包括重复样本和异常值的识别,以保证数据标签的准确性。例如,对于数据集中可能存在的重复样本,通过自动检测程序进行精准定位,然后由实验人员进行确认和删除。
2.2 特征提取
本文依据驼峰式命名法(CamelCase)和下划线命名法(UnderScoreCase)对文本信息进行分词,对切分后的每个单词序列进行数据清洗,以去除文本信息中的特殊符号和无用字符等无关信息,并将处理后的单词序列进行token化处理生成token序列。
在将token序列转化成词向量时,不同于大多数多标签坏味检测方法采用Glove和Word2Vec等词嵌入模型,本文使用CodeBERT预训练模型。该模型是针对源代码的预训练模型,它通过在大规模代码库上进行训练,能够更好地理解代码的语法和结构[15]。
使用BiLSTM模型对词向量进行全局特征提取[16],通过对文本信息进行上下文建模,全面捕捉其中的语义关系。此过程不仅将原始的高维词向量信息整合为更紧凑的低维向量,而且这个向量包含了代码中标识符的语义和上下文特征。这将为后续模型提供更为全面的信息,以便更有效地进行代码坏味的分析和检测。
通过静态分析工具提取的结构度量信息只包含一些代码的基本信息,其表达能力有限,无法提供代码的细粒度特征和潜在问题,因此本文使用CNN模型来提取结构度量信息中的深层次特征。本文将提取到的结构度量信息作为输入,Conv1d层可以在每个时刻上应用一组卷积核,学习提取不同的特征,再将输入数据的特征表示扩展到更丰富的空间中,增加输出的维度,这可以帮助捕获输入数据中更丰富的特征,提高模型的表达能力。卷积操作具有权重共享的特性,可以减少模型需要计算的参数量,降低CNN模型的复杂度[17]。此外,引入激活函数增加各层之间的非线性关系,并通过归一化处理,避免梯度消失,从而提高模型的训练速度。最后,CNN模型输出自动特征提取结果。
2.3 多标签代码坏味检测
多标签代码坏味检测流程如图3所示。
首先,将BiLSTM提取的文本特征信息与CNN提取的度量特征信息在合并层进行特征融合。这一融合操作旨在结合文本和代码结构的丰富信息,以更全面地捕捉代码坏味的特征。然后,利用注意力机制[18]对特征信息和预期标签进行映射,以计算每个特征信息对检测代码坏味的重要程度。通过这种方式,DMSmell能够更加精准地聚焦于对预测结果至关重要的特征,同时有效抑制无关特征的干扰,并对信息进行加权求和计算,进而为每个特征重新分配权重系数。最后,利用一个多层感知机实现多标签分类,采用sigmoid作为激活函数,将输出结果与阈值函数ft=0.5(X)比较得到每个标签的0/1的检测值。
3 方法评估
3.1 实验环境
所有实验均在同一台主机上进行,该主机在硬件配置上采用了主频为2.8 GHz的Intel Core处理器、Nvidia GTX 1060 GPU,以及16 GB内存。在软件方面,运行64位Windows 10操作系统,并使用Python 3.7和PyTorch 1.10作为深度学习的支持环境。为了保证实验的可复现性,所有模型和数据集均可在https://github.com/HyLiu-cn/DMSmell/中获取。
在实验参数配置中,迭代次数为30,选择Adam作为优化器,学习率设置为0.000 1,批处理大小为128行。多标签数据集采用随机划分操作,比例为7∶3。表 3给出了实验模型及其配置信息。
3.2 性能评估指标
为了验证DMSmell方法的有效性,本文参考了文献[19],并选取了5个多标签分类方法的评估指标:汉明损失、精确匹配率、微查准率、微查全率和微F1。
1)汉明损失 评估错误分类的标签个数比率,即预测错误的标签数在整个样本标签总数中的占比,见式(1)。
式中:t为样本数;y′i为第i个实例的预测标签值;yi为第i个实例的真实标签值;△表示异或运算。
2)精确匹配率 计算预测标签与真实标签完全相同的比率,见式(2)。
式中:[[·]]只有·成立时为1,否则为0。
3)微查准率 计算公式见式(3)。
式中:p为标签个数;TP为真阳性;FP为假阳性。
4)微查全率 计算公式见式(4)。
式中:FN为假阴性。
5)微F1 计算公式见式(5)。
3.3 DMSmell方法检测结果分析
采用DMSmell方法在本文构建的多标签数据集上进行了训练与检测。表4为DMSmell方法检测结果。由表4可知:DMSmell方法的汉明损失为0.026 9,这意味着平均每个样本只有很少的标签预测错误;精确匹配率达到了94.76%;微查准率为93.46%;微查全率为98.00%,这意味着DMSmell方法在预测不同类别的标签时具有较高的识别准确率,并能够捕捉到更多的真正例,漏检率较低;在同时考虑了查准率和查全率的微F1指标上,DMSmell方法取得了95.68%的结果,表明模型在综合性能方面表现出色。
以上数据表明,DMSmell方法在本文的多标签数据集上能有效检测出多个坏味类型,并展现出了优异的性能。
3.4 与分类器链方法的比较
由于先前多标签代码坏味检测工作均采用分类器的方法,故本文将DMSmell方法与基于分类器链的检测方法[20]进行比较。为了使比较更加公平,2种方法均在同一数据集上进行训练,并使用Random Forest作为基分类器。
表5展示了在相同数据集下DMSmell方法与分类器链方法的检测结果的比较。其中,DMSmell方法的汉明损失值较分类器链法0.033 5低,为0.026 9,意味着其能够更准确地检测出代码中的多种坏味。同时,DMSmell的精确匹配率较分类器链法提高了1.36个百分点,对于微查全率,DMSmell方法则较分类器链法的95.55%提高到98.00%,提高了2.45个百分点,这进一步表明DMSmell方法在多标签代码坏味检测方面的有效性。此外,本文也观察到分类器链方法的微查准率(93.62%)略高于DMSmell方法的微查准率(93.46%)。但通过观察综合指标微F1发现,DMSmell方法提升了1.1个百分点,这一结果表明本文的方法存在很小的误报,但在整体性能上要优于分类器链方法。
实验结果表明,DMSmell方法在检测多标签代码坏味方面优于现有的多标签代码坏味检测方法,更适用于多标签代码坏味的检测。
4 结 语
本文提出了一种基于预训练模型与BiLSTM-CNN的多标签代码坏味检测方法DMSmell,将源代码的结构度量信息和文本信息相结合,并且采用基于深度学习的方法进行代码坏味检测,提高了多标签代码坏味检测的准确率。
1)DMSmell方法在处理文本信息方面利用预训练模型代替了传统的Work2vec方式,并利用传统的BiLSTM和CNN分别获取了文本信息和结构度量信息中深层次的特征,实现了更高效的特征表示学习。
2)本研究构建了一个公开的可进行多标签代码坏味检测的数据集,其中包含源代码的文本信息和结构度量信息,为后续研究人员在代码坏味检测领域的进一步研究提供了丰富的数据支持。
3)DMSmell方法与基于分类器链的检测方法相比,在精确匹配率、微查全率和微F1上分别提高了1.36个百分点,2.45个百分点和1.1个百分点,表明DMSmell方法优于现有的基于分类器链的多标签代码坏味检测方法。
本文提出的DMSmell方法可以有效地对多标签代码坏味进行检测,但本文所构建的数据集并不能代表所有领域,且仅选取了2种方法级代码坏味,并未考虑其他类型的代码坏味。因此,在未来工作中,将尽可能选择更多来自不同领域的开源项目,以确保数据的多样性,同时也要考虑其他高共现性的代码坏味进行检测,以进一步提高DMSmell方法的检测性能。
参考文献/References:
[1] FOKAEFS M,TSANTALIS N,STROULIA E,et al.JDeodorant: Identification and application of extract class refactorings[C]//2011 33rd International Conference on Software Engineering (ICSE).Honolulu:IEEE,2011:1037-1039.
[2] CRISTINA M,RADU M,MIHANCEA P F.iPlasma:An integrated platform for quality assessment of object-oriented design[C]//Proceedings of the 21st IEEE International Conference on Software Maintenance.Budapest:IEEE,2005:77-80.
[3] SANDOUKA R,ALJAMAAN H.Python code smells detection using conventional machine learning models[J].PeerJ Computer Science,2023,9:e1370.
[4] BRDAR I,VLAJKOV J,SLIVKA J,et al.Semi-supervised detection of long method and god class code smells[C]//2022 IEEE 20th Jubilee International Symposium on Intelligent Systems and Informatics (SISY).Subotica:IEEE,2022:403-408.
[5] YU Dongjin,XU Yihang,WENG Lehui,et al.Detecting and refactoring feature envy based on graph neural network[C]//2022 IEEE 33rd International Symposium on Software Reliability Engineering (ISSRE).Charlotte:IEEE,2022:458-469.
[6] GUGGULOTHU T,MOIZ S A.Code smell detection using multi-label classification approach[J].Software Quality Journal,2020,28(3):1063-1086.
[7] NUCCI D D,PALOMBA F,TAMBURRI D A,et al.Detecting code smells using machine learning techniques: Are we there yet?[C]//2018 IEEE 25th International Conference on Software Analysis,Evolution and Reengineering (SANER).Campobasso:IEEE,2018:612-621.
[8] KIYAK E O,BIRANT D,BIRANT K U.Comparison of Multi-Label classification algorithms for code smell detection[C]//2019 3rd International Symposium on Multidisciplinary Studies and Innovative Technologies (ISMSIT).Ankara:IEEE,2019:1-6.
[9] 王继娜,陈军华,高建华.基于排序损失的ECC多标签代码异味检测方法[J].计算机研究与发展,2021,58(1):178-188.
WANG Jina,CHEN Junhua,GAO Jianhua.ECC Multi-Label code smell detection method based on ranking loss[J].Journal of Computer Research and Development,2021,58(1):178-188.
[10]AMORIM L,COSTA E,ANTUNES N,et al.Experience report:Evaluating the effectiveness of decision trees for detecting code smells[C]//2015 IEEE 26th International Symposium on Software Reliability Engineering (ISSRE).Gaithersbury:IEEE,2015:261-269.
[11]ZHANG Yang,GE Chuyan,HONG Shuai,et al.DeleSmell:Code smell detection based on deep learning and latent semantic analysis[J].Knowledge-Based Systems,2022,255:109737.
[12]ZHANG Yang,GE Chuyan,LIU Haiyang,et al.Code smell detection based on supervised learning models:A survey[J].Neurocomputing,2024,565:127014.
[13]TRIFU A,MARINESCU R.Diagnosing design problems in object oriented systems[C]//12th Working Conference on Reverse Engineering (WCRE′05).Pittsburgh:IEEE,2005:10.
[14]MARINESCU R.Measurement and quality in object-oriented design[C]//Proceedings of the 21st IEEE International Conference on Software Maintenance.Budapes:IEEE,2005:701-704.
[15]FENG Zhangyin,GUO Daya,TANG Duyu,et al.Codebert:A pre-trained model for programming and natural languages[C]//Findings of the Association for Computational Linguistics:EMNLP 2020.Online:ACL,2020:1536-1547.
[16]郝超,裘杭萍,孙毅.融合BERT和图注意力网络的多标签文本分类[J].计算机系统应用,2022,31(6):167-174.
HAO Chao,QIU Hangping,SUN Yi.Incorporating BERT and graph attention network for multi-label text classification[J].Computer Systems & Applications,2022,31(6):167-174.
[17]GUO Shanshan,CHEN Shiyu,LI Yanjie.Face recognition based on convolutional neural network and support vector machine[C]//2016 IEEE International Conference on Information and Automation (ICIA).Ningbo:IEEE,2016:1787-1792.
[18]VASWANI A,SHAZEER N,PARMAR N,et al.Attention is all you need[C]//Advances in Neural Information Processing Systems 30.Long Beach:NIPS,2017:5998-6008.
[19]GIBAJA E,VENTURA S.A tutorial on multilabel learning[J].ACM Computing Surveys,2015,47(3):1-38.
[20]READ J,PFAHRINGER B,HOLMES G,et al.Classifier chains for multi-label classification[J].Machine Learning,2011,85(3):333-359.