Page 227 - 《软件学报》2021年第8期
P. 227

黄子杰  等:检测 JavaScript 类的内聚耦合 Code Smell                                          2509


                 1.3   文本分析
                    文本分析与结构分析的主要区别在于信息收集阶段,前者不依赖或较少依赖抽象语法树中的结构信息,而
                 是将源码视作文本片段,并使用文本挖掘算法计算文本相似度等度量信息.
                    Palomba 等人 [6,15,16] 运用结构分析和文本分析,对 Java 软件项目的多个历史版本进行了挖掘,研究分析了两
                 种检测方式获取的 Code Smell 强度,得出了其解决的难易程度、变化的趋向、产生的原因等性质.研究指出,基
                 于结构方式和文本方式的检测算法互补,文本方式是重要的信息源,将两种信息源结合的工作较少.
                    因为结构分析方法在检测 JS 变量的类型信息时,所能获取的信息远不如 Java 项目详实,所以文本分析和结
                 构分析的互补对 JS Code Smell 的检测更为重要.
                    文本分析方法可分为有监督和无监督两类.有监督的文本分析需要额外的人工干预来预先标注文本,以形
                 成带标签(Label)数据集,故不适用于 Code Smell 的检测.在无监督的文本分析方面,Blei 等人                 [21] 提出了潜在语义
                 分析(LDA)算法,该算法被应用于 Bavota 等人        [22] 检测 Code Smell 的方法中;Le 等人 [23] 基于 Google 开源的、运
                 用深度模型的 Word2Vec 词向量算法,提出了将文档用向量表示的算法.
                    LDA 是一种常用的文档主题生成式模型,包含词、主题和文档这 3 层结构.LDA 使用词袋模型表示一个文
                 档,并将一个文档视作隐含主题的有限混合,其中的每个单词由一个主题生成,文档之间的关联可以由主题间的
                 关联决定.LDA 具备比 LSA 等基础主题建模方法更强的拟合能力.
                    Word2Vec 算法可利用神经网络语言模型训练过程中获得的权重矩阵参数,将词语转化为向量.Skip-gram
                 是 Word2Vec 算法使用的一种语言模型,它根据当前词汇预测上下文.Skip-gram 模型共有 3 层,即输入层、隐藏
                 层(hidden layer)、输出层.神经网络通过调整隐藏层至输入层、输出层的权重矩阵进行训练,调整训练的过程可
                 概括为:假如若干词具有近似的输出,则可反推词间具有较高的相似性.基于 Skip-gram 模型,Mikolov 进一步提
                 出了 Doc2Vec,它基于词向量表示文档向量.本文采用 PV-DBOW(distributed bag of  words version of paragraph
                 vector)模型,其设计思想和 Skip-gram 相近,即:通过预测文档的内容训练一个矩阵,此矩阵即为文档矩阵.通过计
                 算文档矩阵间的余弦相似度,可获取相似度特征.
                 2    检测流程

                    检测流程包括 4 个阶段:信息抽取阶段、预处理阶段、检测阶段、判定阶段,如图 2 所示.
                    (1)  信息抽取阶段:从软件项目的开源社区获取特定 Release 版本的源码,配置类检测引擎的运行参数后
                        开始类的检测.类检测引擎基于 JSDeodorant         [13] 改进,JSDeodorant 是开源 JS 类检测工具,文献报告其平
                        均表现可达到 95%的精确率和 98%的召回率.在此基础上,本文借助 Google Closure  Compiler               [24] 分析
                        源码所得的 JS 语句类型信息,通过扩展对象类型推断                 [25] ,实现对类信息的检测.
                    (2)  预处理阶段:本阶段为检测阶段所需的输入做准备.对于结构分析,需对检测到的 JS 类信息去重和计
                        算频次,以便用于度量指标;对于文本分析,需将文本标准化.文本标准化的具体流程如下:
                        ¾    分词.对驼峰和下划线命名方式的变量名进行分词,将所有英语字符都转换为小写形式.
                        ¾    去除停用词.将与业务逻辑无关的保留关键字、英语停用词、特殊字符等内容剔除.
                        ¾    提取词干.去除单词的词缀,得到其词根.
                    (3)  检测阶段:本阶段对输入数据运行检测算法,并计算动态阈值,最终输出值域为[0,1]的强度值.其中,本
                        文对 FE 运用了 Fokaefs 等人   [20] 提出的检测算法,对 DC 运用了经改进的非严格 NSCDISP 度量,对 Blob
                        运用了 LCOM5 度量     [26] .在基于相似度的文本检测方面,本文对 FE 和 Blob 的检测使用了 Doc2Vec 算
                        法 [23] ,并以 LDA 算法的结果作为对照组.由于文本分析对 DC 的检测效果不佳,故未予采用.
                    (4)  判定阶段:对于一个代码片段,检测阶段可输出多个强度值.根据 Code Smell 之间的关联和结构和分
                        析方法的特点、优劣,本文提出了一种综合判定策略,最终得出该代码片段的 Code Smell 的种类及值
                        域为[0,1]的强度值,强度值越高,Code Smell 越严重.
   222   223   224   225   226   227   228   229   230   231   232