Page 209 - 《软件学报》2021年第7期
P. 209

陈翔  等:代码注释自动生成方法综述                                                              2127


                 NNGen 首先使用词袋模型(bag of words),将训练集中的代码变更和新的代码变更转换成向量表示.他们在该阶
                 段使用的词袋模型忽略了单词间的次序,且仅考虑了单词在代码变更中的出现频率.随后,基于余弦相似度,从
                 训练集中选出与新的代码变更最为相似的 k 个代码变更.接着,再计算出新的代码变更与这 k 个代码变更间的
                 BLUE-4 评分.最后,将 BLUE-4 评分最高的代码变更的提交消息视为新的代码变更的提交消息.最终的实验结
                 果表明,与 Jiang 等人提出的方法相比,NNGen 方法可以提速 2 600 倍,并且在 BLEU 指标上可以提升 21%.
                 3.3   已有工作的对比和评点
                    我们通过表 3,对所有基于信息检索的方法进行了全面对比,包括代码模块的粒度、考虑的编程语言、方法
                 的类型和主要特征.不难看出,这类方法的早期以基于代码关键词抽取的方法为主,重点是从目标代码中抽取关
                 键词,在抽取时主要基于 VSM、LSI 和主题模型等信息检索技术.近些年来,更多的研究人员将关注点从代码模
                 块本身转移到软件仓库挖掘上.最早考虑的对象包括缺陷跟踪系统、版本控制系统、开发人员间的电子邮件.
                 最近研究人员更多关注 Github 和 Stack Overflow 这类基于众包协作的平台.这类方法的性能取决于是否能够找
                 到语义相似的代码.其难点在于衡量不同方法或者不同代码变更间的语义相似度,因此可以考虑借鉴目前最新
                 的代码嵌入方法,例如针对方法间的语义相似性,可以考虑 Alon 等人提出的 code2vec 和 code2seq                    [47,48] .针对代
                 码变更间的语义相似性,可以考虑 Lozoya 等人提出的 commit2vec             [49] 和 Hoang 等人提出的 cc2vec [50] .

                                 Table 3    Comparison of information retrieval-based generation methods
                                              表 3   基于信息检索生成方法的对比
                         相关文献       模块粒度  编程语言        方法类型                     主要特征
                       Haiduc 等人  [7,8]    方法   Java   基于代码关键词抽取           基于 LSI 和 VSM 模型
                        Eddy 等人 [35]    方法   Java   基于代码关键词抽取                基于 hPAM 模型
                      McBurney 等人  [36]    方法   Java   基于代码关键词抽取       考虑了主题模型,并将主题分层组织
                     Rodeghero 等人 [11,37]    方法   Java   基于代码关键词抽取          借助眼动追踪技术
                       Fowkes 等人 [38]    折叠代码   Java   基于代码关键词抽取           基于 VSM 和主题模型
                      Panichella 等人 [39]    方法   Java   基于软件仓库挖掘        综合考虑了缺陷报告和邮件清单
                       Rahman 等人 [40]    方法   Java   基于软件仓库挖掘            利用 Stack Overflow 的帖子
                        Wong 等人 [41]    方法   Java   基于软件仓库挖掘             利用 Stack Overflow 的帖子
                       Vassallo 等人 [42]    类   Java   基于软件仓库挖掘           利用 Stack Overflow 的帖子
                        Wong 等人 [43]    方法   Java   基于软件仓库挖掘           利用 Github,基于代码克隆检测方法
                       Badihi 等人 [44]    方法   Java   基于软件仓库挖掘     基于众包方式,通过设计游戏机制来提高注释质量
                       Huang 等人 [45]    代码变更   Java   基于软件仓库挖掘       基于修改前后代码的语法和语义相似度
                        Liu 等人 [14]    代码变更   Java   基于软件仓库挖掘       基于 k 近邻算法,通过查找相似的代码变更
                                                                             来生成提交消息
                 4    基于深度学习的生成方法


                 4.1   简   述
                    这类方法主要基于代码的 naturalness 假设        [51,52] ,该假设由 Hindle 等人在 2012 年首次提出,他们认为软件的
                 代码是由开发人员编写的,因此与自然语言一样,具有一些可预测的统计特征,并且这些统计特征是可以被语言
                 模型所捕获的.该假设构成利用深度学习进行代码语义学习的重要基石.通过对比代码与自然语言,我们发现代
                 码与自然语言存在诸多相似之处,例如:均由词素构成,可以建模为语法树,具有重复性和可预测性等.但代码自
                 身也具有一些特性:(1)  强结构性,代码按照特定编程语言的语法规则,因此只能被解析为唯一的抽象语法树.
                 (2)  代码对应的词典规模要远大于自然语言对应的词典规模.因为开发人员在代码中会定义不同的变量名、方
                 法名和类名等,这些名字在自然语言里并不一定能找到.
                    基于深度学习的方法目前主要将代码注释自动生成问题建模为神经机器翻译(neural machine  translation,
                 简称 NMT)问题   [53] .在自然语言处理领域,机器翻译问题是指将基于某种自然语言(例如英语)的句子翻译成基于
                 另一种自然语言(例如中文)的句子.因此需要搜集大量英文与中文对应的语料库,并训练出正确的单词映射,甚
                 至语法结构映射.但与机器翻译问题不同,基于深度学习的代码注释生成问题在研究时面临如下挑战:(1) OOV
   204   205   206   207   208   209   210   211   212   213   214