论文部分内容阅读
随着程序代码库(例如Codeplex,Github,Sourceforge)中的源代码资源越来越丰富,代码搜索已经成为软件开发中的一种常见活动。其搜索性能依赖于查询语句和查询结果之间的词汇匹配度。为提高二者匹配的概率,本文专注于研究查询扩展方法(Query Expansion,QE)。该方法首先根据指定的查询语句从扩展源中搜索一定数量的相关文档,然后从这些文档中提取有用的扩展项,接着使用这些扩展项重构原始的查询语句,最后使用重构后的查询语句搜索出最终的查询结果。然而,现有的查询扩展方法均未考虑源代码的本质(即语法结构和程序语义),而是将源代码和扩展源视为纯文本,依旧照搬自然语言处理的方法。最常见的做法是仅凭对词项的统计信息判断扩展项的可用性。例如使用TFIDF衡量词项的重要度或使用共存关系衡量查询结果与查询语句中词项之间的相关度。这便导致了三个亟待解决的问题,分别是“查询扩展单一”、“查询扩展过度”和“语义理解肤浅”。问题一,现有查询扩展方法每次只考虑一种文本扩展源;问题二,现有查询扩展方法使用许多与查询结果无关的扩展项重构原始的查询语句,进而对搜索性能造成负面影响,致使这些查询结果无法直接满足用户的搜索需求,唯有等待用户对其进行后续修改;问题三,现有查询扩展方法无法区分具有不同顺序的代码序列,进而无法深刻理解隐藏于代码序列背后的程序语义。为了克服上述三个问题,本文提取出三个全新的扩展源。基于此,又提出三种全新的查询扩展方法,如下所述。为了解决“查询扩展单一”的问题,从Github代码库的“Pull请求”中提取出一种能够综合多种扩展源特点的文本扩展源(Github Knowledge,GK)。该扩展源既包含与request相关的描述、与commits相关的描述、参与者的评论等众智知识(Crowd Knowledge,CK),又包含被修改文件的API信息。基于此,提出一种全新的查询扩展方法(Query Expansion based on GK,QEGK)。除此之外,本文还提出一种基于SVM的查询扩展集成方法(Query Expansion based on SVM Ranking,QESR),有效实现多元化扩展的目标。从实验评测可知,与最新的查询扩展方法CodeHow和QECK相比,当只关注第一个查询结果是否满足用户的搜索需求时,QESR在准确率方面提高了 8-15%。为了解决“查询扩展过度”的问题,提取出一种全新的非文本扩展源(演化上下文)。这是一种考虑源代码的本质且与代码直接相关的扩展源。它包含代码演化过程中所有被修改的代码项(例如新增的代码项和删除的代码项)及其依赖项。基于此,提出一种全新的查询扩展方法(Query Expansion based on Evolving Contexts,QEEC)。该方法首先从大量代码修改记录获取足量的演化上下文,然后使用十大机器学习算法之一的最大期望算法(Expectation Maximization,EM)训练这些演化上下文,进而获得推理模型。利用模型推测用户在搜索到源代码之后还会对源代码做哪些后续修改,并将这些修改操作中新增的代码项视为与查询结果相关的相关项,将删除的代码项视为与查询结果无关的无关项。最后在原始查询语句中扩展相关项,排除无关项,实现对原始查询语句的适度扩展。从实验评测可知,与最新的查询扩展方法CodeHow和QECK相比,当只关注第一个查询结果是否满足用户的搜索需求时,QEEC在准确率方面提高了 11-18%。与此同时,QEEC还在准确度方面帮助代码搜索算法IR、Portfolio和VF提高了37-52%。为了解决“语义理解肤浅”的问题,在演化上下文的基础上进一步提取出一种全新的非文本扩展源(代码修改序列的语义信息)。基于此,提出一种全新的查询扩展方法(Query Expansion based on the semantics of change sequences,QESC)。该方法首先获取足量的代码修改序列,然后使用深度学习算法之一的深度信念网络(Deep Belief Network,DBN)学习代码修改序列的语义。根据语义相似度,推测用户在搜索到源代码之后还会对源代码做哪些后续修改,并用修改操作中新增的代码项和删除的代码项重构原始的查询语句。从实验评测可知,与最新的查询扩展方法CodeHow和QECK相比,当只关注第一个查询结果是否满足用户的搜索需求时,QESR在准确率方面提高了 14-21%。