华晨彦,邹艳珍+,朱子骁,谢 冰
1.北京大学 信息科学技术学院,北京 100871
2.高可信软件技术教育部重点实验室,北京 100871
3.北京大学(天津滨海)新一代信息技术研究院,天津 300450
基于代码模式的软件问答文档检索优化方法*
华晨彦1,2,3,邹艳珍1,2,3+,朱子骁1,2,3,谢 冰1,2,3
1.北京大学 信息科学技术学院,北京 100871
2.高可信软件技术教育部重点实验室,北京 100871
3.北京大学(天津滨海)新一代信息技术研究院,天津 300450
Abstract:Developers often need to search related software Q&A documents in Q&A website.In the search results,the Q&A documents which contain good code snippets(usage examples)are preferred.However,how to metric those code snippets in document is still a big challenge.To address this issue,this paper proposes an approach for refining software Q&A document search results based on code pattern.Firstly,code snippets are extracted from each document in the search results.Then,the common code patterns are mined and used to measure the quality of those code snippets.Finally,the documents with high quality are recommended and ranked at the top of the search results.In the experiments,this paper carries out some evaluations with 10 real problems that software developers meet in practice.Compared to the search results of StackOverflow,the proposed approach has an increment of 40%atNDCG@5.
Key words:code pattern;software Q&Adocument;document search
开发人员通常通过问答网站的搜索引擎进行相关软件问答文档的搜索。在检索结果中,包含优质代码片段(使用示例)的问答文档往往更受青睐,但如何度量这些文档中代码片段的质量仍是个巨大的挑战。针对这个问题,提出了一种基于代码模式的软件问答文档检索优化方法。该方法能够基于当前检索结果,抽取文档中的代码片段,分析代码片段中的公共代码模式,并基于代码模式度量文档中代码片段的质量,从原有检索结果中向用户推荐高质量的软件问答文档。以软件开发人员在实践过程中遇到的真实问题为基础进行了实验,对比StackOverflow的搜索结果,所提方法在准确率指标NDCG@5上提升了40%。
代码模式;软件问答文档;文档检索
近年来,各类技术性问答网站(如StackOverflow等)受到了开发者们的喜爱,这些问答网站上产生了大量的软件问答文档。如何检索和利用这些软件问答文档成为软件复用领域一个非常重要的研究问题。
很多研究者针对软件问答文档检索问题进行了研究[1-2],主要关注点是对检索结果进行优化和重排序[3]。例如,Atwood[4]使用StackOverflow的基于软件问答文档元数据的检索结果排序方法。该方法通过软件问答文档的阅读量、回答数量、赞同数量等指标综合计算每篇文档的得分,按得分的高低对检索结果进行排序。Ponzanelli等人[5]设计并实现了一个Eclipse插件PROMPTER。PROMPTER以代码片段作为查询的输入,考虑了文本相似度(使用tf-idf)、代码相似度(代码克隆)、API(application programming interface)类型相似度、API方法相似度等参数,加权平均决定软件问答文档的最终得分。Williams等人[6]提出了基于递归伪相关反馈策略的相似文档检索方法。对于给定查询的结果列表R,对R的前k篇文档递归进行检索,通过递归检索的结果反馈评价原始结果,从而优化检索结果。Cha等人[7]提出了基于主题模型的文档检索优化方法,使用LDA(latent Dirichlet allocation)主题模型给每篇文档计算一个主题分布,根据查询与每个主题的相关程度确定文档在检索结果中的排名位置。Zou等人[8]提出的面向软件的文本检索方法将问题分为6种类别,依据检索问题与检索结果是否属于同一类别对检索结果进行重排序。
从这些工作可以看出,如何挑选或推荐高质量的检索结果是当前软件问答文档检索优化的主要目标。本文在调研中发现,软件问答文档中包含大量的代码示例片段,包含代码片段的问答文档质量较高,可以更好地帮助开发者了解或解决遇到的问题。但是由于不同文档讨论不同的问题,其针对的开发任务不同,并且问答文档由不同的人编写,其编码的语言、风格也大不相同,如何度量检索结果文档中代码片段的质量以及如何进行检索结果重排序仍是个巨大的挑战。
为此,本文提出了一种基于代码模式的软件问答文档检索优化方法。该方法从解决相同/相似开发任务的软件问答文档的代码片段中,抽取公共的代码模式,通过代码模式度量代码片段和软件问答文档的质量,由此通过检索结果重排序向用户推荐高质量的软件问答文档。
与现有工作相比,本文的主要贡献包括:
(1)定义了一种面向开发任务的软件代码使用模式,并提出了基于数据流图的代码模式挖掘方法。
(2)提出了一种基于代码模式的软件问答文档检索优化方法。通过代码模式度量代码片段和软件问答文档的质量,给每篇问答文档一个评分,并结合该文档在原有检索结果中的排序进行检索优化。
(3)实现并开源了一个基于代码模式的软件问答文档推荐工具。以10个软件开发人员在实践过程中遇到的真实问题为基础进行了实验,对比了Stack-Overflow的搜索结果,本文工作在准确率指标NDCG@5上提升了约40%。
本文组织结构如下:第2章介绍了代码模式的定义和作用;第3章详细讨论了基于代码模式的软件问答文档检索优化方法;第4章通过实验验证了方法的有效性;第5章对本文工作进行了总结。
一般来说,软件问答文档的来源可分为两类:软件项目官网与技术性问答网站。软件项目官网的软件问答文档由软件项目的开发人员撰写,准确度高,结构简单,通常采用一问一答的形式,但数量少,覆盖面狭窄;技术性问答网站的软件问答文档数量巨大,且为大量开发人员在实践过程中总结出的经验教训,覆盖面广,实用性高。在这两类问答文档中,为了更好地帮助提问者理解回答或解决问题,回答者一般都会在答案中附上相应的代码片段。研究表明,在StackOverflow上的软件问答文档中,包含代码片段的文档数量约占总文档数量的50%!这些代码片段可能是回答者针对这一问题给出的,或是其曾经开发过的项目中与该问题相关的代码片段。
在讨论相同/相似问题的软件问答文档中,代码片段(使用示例)往往调用相同的API方法,或包含一些共同的语句、方法调用、控制结构,本文将这些共性称为开发任务的代码模式(code pattern)。对于简单的开发任务,这些API可能为单个对象的若干方法顺序执行,然而对于复杂的任务,便会涉及多个对象互相交互,还可能包含复杂的控制结构。图1展示了两个StackOverflow文档体现的代码模式(加粗高亮表示的部分)。该模式是使用JDK的Scanner读取文件的常用模式。
在问答文档检索过程中,这些面向开发任务的代码模式将带来如下益处:(1)可以度量文档中代码片段的质量,过滤不完整或不准确的示例代码;(2)可以解决文档检索中的模糊性问题,如提问者对问题的理解存在偏差,提问者的问题过于特化等情况。在图1包含代码模式的两篇文档中,其中文档1[9]的开发任务是输出给定文件中所有符合特定条件的行,文档2[10]的开发任务是读取csv格式的文件。通过代码模式的抽取,用户在检索“Scanner read file”时也可以定位到它们。
Fig.1 Code pattern of reading file using“Scanner”图1 使用Scanner读取文件的代码模式
本文提出了一种基于代码模式的软件问答文档检索优化方法。如图2所示,该方法主要分为三部分:
Fig.2 Framework of refining software Q&Adocument search results based on code pattern图2 基于代码模式的软件问答文档检索优化方法框架
(1)检索结果的获取与解析。根据用户的查询获取与查询相关的软件问答文档,并解析出其中的代码片段。
(2)代码模式的抽取。将代码片段转换为数据流图,通过频繁子图挖掘算法,在这些数据流图中挖掘出代码模式。
(3)检索结果的优化。通过代码模式给每一篇软件问答文档一个评分,将所有的软件问答文档按评分高低重排序,推荐给用户。
本文的软件问答文档数据来源于StackOverflow,根据用户的查询,使用StackOverflow的搜索API进行在线搜索,并将结果下载至本地,便于后续的解析与处理。StackOverflow的软件问答文档为HTML格式。HTML使用标签表明文档的内容,依据嵌套关系表明文档的层次结构,通过特定的标签即可解析出文档中的代码片段。
本文使用数据流图(data flow graph)表示代码模式。使用数据流图存在以下两个优点:一是在面向对象语言开发过程中,开发者常常遇到多个对象需要互相协作的场景[11],使用数据流图可以有效地梳理这种交织关系;二是开发者对代码元素的命名有着各自的喜好,而代码元素的命名不会影响代码实现的功能。数据流图只关心每条语句的输入来源与输出去向,可以有效地过滤代码元素命名带来的干扰。
建立数据流图需要变量的定值-使用关系,该信息可以通过静态单赋值形式的控制流图获得。然而Java语法复杂,抽象语法树的结点类型较多,难以直接转换为控制流图,并且不同开发人员实现相同功能的代码可能使用了不同的语法,存在偏好差异,导致生成了不同的数据流图,最终无法抽取出代码模式。为此,需要先将Java语言的代码片段通过中间代码表示,再进行后续操作。
(1)解析代码片段。在前文中提到不同开发人员在代码编写过程中存在偏好差异,本文通过解析代码片段,并使用中间代码表示(intermediate representation,IR)的方式消除这些差异。
现有Java语言的中间代码生成工具只能应用于完整的Java项目,无法处理代码片段。因此,本文设计与实现了一个Java语言的中间代码生成工具。IR的设计主要有两点:一是能与原语法相对应;二是便于进一步处理。在本文的IR设计中,产生式主要分为块级与语句级两个层次。块级产生式对应于控制流图中的基本块,便于转换为控制流图;语句级产生式对应于一条语句,也是数据流图的结点。语句级产生式均为变量赋值的形式,便于定值-使用分析。
(2)转换数据流图。本文使用静态单赋值形式(static single form,SSA)的控制流图来获取与建立数据流图所需要的变量定值-使用关系。
从中间代码表示转换至流图只需要针对控制流语句在相应结点之间添加边即可。
将控制流图转换为SSA形式的关键就是对每个变量的定值添加版本号,在其支配边界处添加φ函数,并相应地更新所有使用的版本号。计算支配边界先使用Lengauer-Tarjan算法[12]计算出直接支配结点,再通过直接支配结点计算支配边界[13]。
将静态单赋值形式的流图转换成数据流图只需要对应每一个变量的定值结点、连边至其所有的使用即可。
(3)挖掘代码模式。本文将代码模式表示为数据流图后,该问题便可转换为频繁子图挖掘问题。
频繁子图挖掘(frequent subgraph mining)[14]是数据挖掘领域的热门问题之一,基于频繁子图挖掘可以发现大量图数据中的公共模式。简单地说,给定一个图,频繁子图挖掘的目的就是找出其中出现最频繁的子图。频繁子图挖掘的常见应用场景包括化合物结构、社交网络等。给定图的集合S={G1=(V1,E1),G2=(V2,E2),…,Gn=(Vn,En)},频繁子图挖掘的完整定义如下。
定义1(图的大小)任意给定一个图G=(V,E),称G的大小为|V|,记为size(G)。
定义2(子图)如果∃Gi=(Vi,Ei),Gj=(Vj,Ej),Vi⊆Vj,Ei⊆Ej,则称Gi包含于Gj,或Gi是Gj的子图,记为Gi⊆Gj。
定义3(支持度)任意给定一个图G,称G的支持度为|{g|g∈S且G是g的子图}|,记为support(G)。
定义4(频繁子图)图的集合S的所有频繁子图为{g|size(g)≥fsize且support(g)≥fsupport},其中fsize和fsupport是事先给定的阈值。
gSpan算法[15]是一种基于模式增长的频繁子图挖掘算法。其核心思想是对图进行dfs编码和最右扩展,通过最小dfs编码判断同构。由频繁子图的定义可知,若图G1是频繁子图,G2⊆G1,那么G2也是频繁子图。然而对于代码模式而言,G2的代表性严格劣于G1,因此本文删除了这些冗余的结果。
软件问答文档中代码片段包含的代码模式数量越多,该文档越具有代表性。然而代码片段的长度会影响其包含的代码模式数量。因此本文提出了两个评价软件问答文档质量的方法。
(1)依据每篇软件问答文档被接受的答案中的代码片段包含的代码模式数量作为评分依据。使用公式表述为:
(2)依据每篇软件问答文档被接受的答案中代码片段数据流图中属于代码模式的结点数量与总结点数量的比值作为评分依据。使用公式表述为:
其中,codes(doc)表示文档doc中的代码片段集合;ddg(c)表示代码片段c的控制流图;patterns为挖掘出的代码模式集合。
最终的推荐结果依据文档的评分,评分越高的文档,排序越靠前。
基于上述工作,本文设计并实现了一个软件问答文档推荐工具。该工具目前已经在github上进行开源(https://github.com/woooking/qa_sorting)。下面将以软件开发人员遇到的实际问题为例,说明推荐方法的实现过程和效果。
为了检验本文工作,收集了10个软件人员在开发过程中遇到的问题。表1描述了这10个问题对应的开发任务及其在StackOverflow检索时输入的查询条件。譬如,第一行描述了某软件开发人员现有一个开发任务是完成某个网络游戏的后台。经过团队协商决定使用TCP协议进行网络传输,但是他并不知道如何创建一个TCP服务器。因此,使用“create tcp server”作为查询条件在StackOverflow上进行检索,希望得到与创建TCP服务器相关的问答文档。
Table 1 Queries used in experiment表1 实验所用查询
对于每个查询,本文从StackOverflow上获取文本相关性排名前10的软件问答文档。将这些文档打乱顺序交由提出查询的软件开发人员为这些文档打分,分数范围是1~5分,评分依据为该文档是否可以解决软件开发人员的问题。
任务1在StackOverflow上的检索结果如表2(左侧)所示。可以看到,检索结果中排名第一位的文档评分只有1分;前3个检索结果中只有一个文档的评分为5分;而前5个检索结果中也只有一个文档的评分为5分。这样的检索结果将耗费用户大量的时间用于文档浏览,降低用户的检索体验。
基于上述检索结果,本文从排名前10的包含被接受答案与代码片段的文档中总共提取出20段代码片段。解析这20段代码片段,并将其转换为数据流图。在这20个数据流图中进行频繁子图挖掘,挖掘算法中的阈值fsize和fsupport均设为3,总共挖掘出3个代码模式。图3展示了其中的一个代码模式。
Fig.3 Acode pattern example of“create tcp server”图3 create tcp server的代码模式
依据代码模式,本文对每一篇问答文档中的代码片段进行评分,评分依据为文档中代码片段包含的代码模式的数量。由此对检索结果进行重排序,推荐结果如表2(右侧)所示。可以看到,检索结果中排名前4的文档都为5分,排名第5的文档也有4分。这样的检索结果可以帮助用户准确快速地定位至高质量的软件问答文档。通过对比可以发现,本文推荐方法可以有效地帮助软件开发人员解决问题。
为了更好地验证本文工作,对上述10组检验结果分别进行了分析。为了评价推荐结果的好坏,本文选取了信息检索中常用的指标之一NDCG@k[16]。该指标的计算公式如下:
其中,r(i)表示排在结果第i位的项与查询的相关程度,r(i)越高,相关程度越大。在本文中相关程度共分为5级,最高为4,最低为0;Nk是归一化参数,它使得在最佳排序(即r(i)为降序)时,NDCG@k的值为1。
本文选取NDCG@k作为评价指标的理由为:
(1)软件开发人员只有阅读高质量的文档才能解决开发问题,因此在评价指标中需要体现出高质量的文档比低质量的文档对结果的影响性更大。在NDCG@k的公式中,指数位的r(i)体现了这一点。
(2)高质量文档在推荐结果中的位置十分重要。在NDCG@k的公式中,体现了这一点,结果越靠后的文档被开发者阅读的几率越低,对排序结果的影响也就越低。
在实验过程中,本文对比了4种问答文档检索/推荐方法。
(1)StackOverflow:该站点的原始搜索结果。
(2)pattern_ratio:依据代码模式结点数与代码片段结点数的比例评价文档质量。
(3)pattern_count:依据代码片段包含的代码模式数量评价文档质量的评分。
(4)replace:仅对包含被接受答案与代码片段的文档使用pattern_count方式评分,其余文档的位置保持不变。
实验结果如图4所示。对比上述4种方法的结果可以发现:整体而言,pattern_count方法的效果最佳。相比于StackOverflow的原始结果,pattern_count方法在NDCG@1(只看第一名)上从60.8%提升至83.3%,在NDCG@5(第一名到第五名)上从52.8%提升至75.1%,提升幅度为40%左右。pattern_ratio的效果略逊色于pattern_count。经过分析发现,回答者在回答问题时给出的代码片段往往来源于其曾经写过的某个项目,因此会包含一些冗余代码,这些代码无法构成代码模式,但也不会影响文档的质量。而pattern_ratio依据代码模式结点数与代码片段结点数的比例评价文档质量,因此会降低此类文档的评分。
Fig.4 Result of experiment图4 实验结果
因为本文提出的软件问答文档检索优化方法基于软件问答文档中的代码片段,所以最终的推荐结果只包含代码片段。为了验证本文方法获得的效果提升不仅仅是因为推荐了包含代码片段的文档,可以对比replace和StackOverflow两种方法。replace与StackOverflow的文档排序区别仅在于包含代码片段的文档,在结果中,replace比StackOverflow在k=1至5时均有提升,因此可以证明本文方法获得的效果提升不仅仅是因为推荐了包含代码片段的文档,而是基于代码模式的软件问答文档度量方法的确有效。
为了在检索过程中帮助用户更快地找到包含优质示例代码的相关文档,本文提出了一种基于代码模式的软件问答文档推荐方法,并以10个开发人员实际遇到的问题为基础进行了实验,验证了本文方法的有效性。在未来工作中,将考虑加入更多来源、类型的软件文档数据,以提升本文方法的适用性;进一步改进代码模式挖掘方法,使得检索系统能更快、更准确地理解软件问答文档中的代码片段。
[1]Wang Xiaoling,Wen Jirong,Luan Jinfeng,et al.A method to query document database by content and structure[J].Journal of Software,2003,14(5):976-983.
[2]Ye Ting,Xie Bing,Zou Yanzhen,et al.Interrogative-guided re-ranking for question-oriented software text retrieval[C]//Proceedings of the 29th ACM/IEEE International Conference on Automated Software Engineering,Vasteras,Sweden,Sep 15-19,2014.New York:ACM,2014:215-220.
[3]Huang Zhenhua,Zhang Jiawen,Tian Chunqi,et al.Survey on learning-to-rank based recommendation algorithms[J].Journal of Software,2016,27(3):691-713.
[4]Atwood J.What formula should be used to determine“hot”questions?[EB/OL].(2008)[2016-07-18].http://meta.stackexchange.com/questions/11602/what-formula-should-beused-to-determine-hot-questions.
[5]Ponzanelli L,Bavota G,Di Penta M,et al.Mining Stack-Overflow to turn the IDE into a self-confident programming prompter[C]//Proceedings of the 11th Working Conference on Mining Software Repositories,Hyderabad,India,May 31-Jun 1,2014.New York:ACM,2014:102-111.
[6]Williams K,Giles C L.Improving similar document retrieval using a recursive pseudo relevance feedback strategy[C]//Proceedings of the 16th ACM/IEEE-CS on Joint Conference on Digital Libraries,Newark,USA,Jun 19-23,2016.New York:ACM,2016:275-276.
[7]Cha M S,Kim S Y,Ha J H,et al.Topic model based approach for improved indexing in content based document retrieval[J].International Journal of Networked and Distributed Computing,2016,4(1):55-64.
[8]Zou Yanzhen,Ye Ting,Lu Yangyang,et al.Learning to rank for question oriented software text retrieval(T)[C]//Proceedings of the 30th IEEE/ACM International Conference on Automated Software Engineering,Lincoln,USA,Nov 9-13,2015.Washington:IEEE Computer Society,2015:1-11.
[9]Java scanner class help[EB/OL].(2011)[2016-07-18].http://stackoverflow.com/questions/3947761/java-scanner-class-help.
[10]Why does scanner read every other line of CSV file?Java[EB/OL].[2016-07-18].http://stackoverflow.com/questions/36564422/why-does-scanner-read-every-other-line-of-csvfile-java.
[11]Nguyen T T,Nguyen H A,Pham N H,et al.Graph-based mining of multiple object usage patterns[C]//Proceedings of the 7th Joint Meeting of the European Software Engineering Conference and the ACM SIGSOFT Symposium on the Foundations of Software Engineering,Amsterdam,Aug 24-28,2009.New York:ACM,2009:383-392.
[12]Lengauer T,Tarjan R E.A fast algorithm for finding dominators in a flowgraph[J].ACM Transactions on Programming Languages and Systems,1979,1(1):121-141.
[13]Cytron R,Ferrante J,Rosen B K,et al.Efficiently computing static single assignment form and the control dependence graph[J].ACM Transactions on Programming Languages and Systems,1991,13(4):451-490.
[14]Inokuchi A,Washio T,Motoda H.An Apriori-based algorithm for mining frequent substructures from graph data[C]//LNCS 1910:Proceedings of the 4th European Conference on Principles of Data Mining and Knowledge Discovery,Lyon,France,Sep 13-16,2000.Berlin,Heidelberg:Springer,2000:13-23.
[15]Yan Xifeng,Han Jiawei.gSpan:graph-based substructure pattern mining[C]//Proceedings of the 2002 IEEE International Conference on Data Mining,Maebashi City,Japan,Dec 9-12,2002.Washington:IEEE Computer Society,2002:721-724.
[16]Järvelin K,Kekäläinen J.Cumulated gain-based evaluation of IR techniques[J].ACM Transactions on Information Systems,2002,20(4):422-446.
附中文参考文献:
[1]王晓玲,文继荣,栾金锋,等.一种通过内容和结构查询文档数据库的方法[J].软件学报,2003,14(5):976-983.
[3]黄震华,张佳雯,田春岐,等.基于排序学习的推荐算法研究综述[J].软件学报,2016,27(3):691-713.
Refine Software Q&ADocument Search Results Based on Code Pattern*
HUAChenyan1,2,3,ZOU Yanzhen1,2,3+,ZHU Zixiao1,2,3,XIE Bing1,2,3
1.School of Electronics Engineering and Computer Science,Peking University,Beijing 100871,China
2.Key Laboratory of High Confidence Software Technologies,Ministry of Education,Beijing 100871,China
3.Peking University Information Technology Institute(Tianjin Binhai),Tianjin 300450,China
A
TP301
+Corresponding author:E-mail:zouyz@pku.edu.cn
HUA Chenyan,ZOU Yanzhen,ZHU Zixiao,et al.Refine software Q&A document search results based on code pattern.Journal of Frontiers of Computer Science and Technology,2017,11(10):1591-1598.
ISSN 1673-9418 CODEN JKYTA8
Journal of Frontiers of Computer Science and Technology
1673-9418/2017/11(10)-1591-08
10.3778/j.issn.1673-9418.1609028
E-mail:fcst@vip.163.com
http://www.ceaj.org
Tel:+86-10-89056056
*The National Key Research and Development Program of China under Grant No.2016YFB1000804(国家重点研发计划);the National Science Fund for Distinguished Young Scholars of China under Grant No.61525201(国家杰出青年科学基金).
Received 2016-08,Accepted 2016-10.
CNKI网络优先出版:2016-10-31,http://www.cnki.net/kcms/detail/11.5602.TP.20161031.1652.024.html
HUA Chenyan was born in 1994.He is an M.S.candidate at Peking University.His research interest is software engineering.
华晨彦(1994—),男,上海人,北京大学硕士研究生,主要研究领域为软件工程。
ZOU Yanzhen was born in 1976.She received the Ph.D.degree in software and software theory from Peking University in 2010.Now she is an associate professor at Peking University,and the member of CCF.Her research interests include software engineering,software reuse and information retrieval,etc.
邹艳珍(1976—),女,辽宁盖州人,2010年于北京大学软件与理论专业获得博士学位,现为北京大学信息科学技术学院副教授,CCF会员,主要研究领域为软件工程,软件复用,信息检索等。
ZHU Zixiao was born in 1990.He is a Ph.D.candidate at Peking University.His research interests include software engineering,software comprehension and reuse,etc.
朱子骁(1990—),男,湖南郴州人,北京大学博士研究生,主要研究领域为软件工程,软件资源理解与复用等。
XIE Bing was born in 1970.He received the Ph.D.degree from School of Computer,National University of Defense Technology in 1998.Now he is a professor and Ph.D.supervisor at Peking University,and the senior member of CCF.His research interests include software engineering and formal methods,etc.
谢冰(1970—),男,湖南湘潭人,1998年于国防科技大学计算机学院获得博士学位,现为北京大学信息科学技术学院软件所教授、博士生导师,CCF高级会员,主要研究领域为软件工程,形式化方法等。发表学术论文40余篇,主持国家863重点项目多项,获国家科技进步二等奖。