在软件诞生经由中, 诞生者最常用的复用方式即是通过检索、调用软件花样提供的API(application programming interface, 应用要领接口)来竣事所需的功能.但是跟着软件花样源代码的范围变得越来越大91porn地址, 源代码之间的依赖关系越来越复杂, API检索也变得越来越费劲[1].比如, 开源花样Lucene包含了向上5 377个类以及34 042种方法.而运筹帷幄东谈主员在运筹帷幄搜索引擎查询日记时发现, 诞生者往往花消了大齐的时代与元气心灵来查找API[2], 通用搜索引擎(如Google)在检索软件代码方面存在许多问题且遵循较低[3].由此也促生了在好多时代性问答网站(如StackOverflow)上, 可以发现大齐对于若何使用API的发问.
受天然谈话经管时代的影响, 咫尺许多软件源代码检索器用, 比如Krugle、Ohloh和Sourcerer[4]等, 齐是将源代码视为纯文本进行经管.其基本想路是:运用软件源代码中的天然谈话特征, 基于查征询题与代码的文本相通度进行匹配, 复返相通度较高的检索适度.典型的相通度匹配模子包括布尔模子(Boolean model)[5]、向量空间模子(vector space model)[5]、BM25模子[5]等.但是运筹帷幄标明, 这些器用的准确率不成让东谈主酣畅.在Lü等东谈主[6]于2015年进行的一项运筹帷幄中标明, Ohloh复返的名次前十的适度中, 唯有25.7%~38.4%是有用的.运筹帷幄者们指出, 导致现存软件源代码检索器用成果不睬想的一个主要原因是其缺少对天然谈话查征询题语义的通晓.对此, 运筹帷幄者们从深刻问题通晓的角度残暴了许多新的方法, 如彭胀语义独揽的词(semantic similar word)[7]、引入查询重构计谋(query reformulation)[8]或运用其他在线文档(如MSDN)来优化问题通晓和检索经由[6]等.天然这些时代很猛进度上提高了API定位的准确度, 但其需要积聚和运用大齐的提拔信息, 在上述信息缺少的情况下, 往往不成达到预期成果.本文则但愿仅从软件花样的源代码启程, 匡助诞生者提高API检索的遵循, 因为源代码是复用经由中概况凯旋得到的资源, 其他信息巧合则难以得到.
此外, 现存这些检索器用复返的适度往往唯有关系的代码片断信息, 缺少对关联API的阐扬与展示, 未便于用户通晓盘算API调用背后的逻辑关联和合座见解, 在一定进度上影响了软件复用的遵循.为此, 运筹帷幄者们指出, 不应单纯地将软件代码视为纯文本.比如在McMillan等东谈主和Chan等东谈主[9, 10]的使命中, 将源代码以有向图的形态组织起来, 图中的结点默示代码元素, 边默示代码元素之间的关联关系.图结构是对源代码学问的一种天然且有用的默示, 被闲居应用于软件文档检索、特征定位等问题.借助代码的结构图, 对源代码的检索就弯曲为图上的搜索经由, 这么得到的适度既能包含需要被定位的代码元素, 又能充分体当代码之间的关联关系.例如来说, 假定在使用开源软件花样ApacheLucene()的经由中, 诞生者现时使用StringField类对一个字符串的字段进行经管.当需求发生变化, 还要对含有浮点数的字段进行经管时, 这个诞生者就需要使用FloatPoint类并斟酌若何重构代码.而咱们可以从图 1所示的源代码图中发现, 这两个类齐禁受自Field类, 竣事了IndexableField接口, 同期具有tokenStream方法.因此对诞生者来说, 一种更好的计谋是使用该轮廓的父Field手脚变量类型, 并在经管不同查询时赋值为不同的子类, 从而概况较好地知足其上述需求.
Fig. 1 Code graph of Lucene project (Part) 图 1 Lucene花样的代码图示例(部分)咫尺, 在基于图结构的API检索方面, 主要接纳了最短旅途[10]、PageRank[9]等浅层语义分析时代.斟酌到在图上进行搜索是一个狡计量很大的问题, 且条款蔓延越短越好, 算法的遵循至关遑急.淌若使用在线查询最短旅途的方式, 则由于搜索经由中常常需要狡计图上两个结点之间的距离, 将会导致较长的蔓延时代.Chan等东谈主的使命[10]也提到了这个问题, 并运用了一些雷同算法进行优化.
针对这些问题, 本文残暴一种基于图镶嵌的软件花样源代码检索方法.图镶嵌是一种默示学习时代, 概况将图上的结点映射为低维空间中的实值向量, 通过向量之间的关系来抒发图上的结构信息.对于本文的问题而言, 图镶嵌时代一方面概况有用抒发软件代码图中的深层结构信息, 与最短旅途等方法比拟, 更充分地斟酌了结点的高下文和关联关系; 另一方面, 图镶嵌经由可以离线进行, 在用户在线查询阶段可以立即参与狡计, 时代复杂度仅是常数级别, 大大提高了算法遵循.
对比现存使命, 本文主要孝顺包括:
(1) 残暴了一种将软件源代码进行图镶嵌默示的方法, 该方法概况概况基于软件花样源代码, 自动构建其代码图结构, 并通过图镶嵌对源代码进行信息默示.
(2) 残暴了一种基于图镶嵌的软件花样源代码检索方法, 该方法概况基于花样源代码的图镶嵌时代默示, 将天然谈话查征询题语义匹配到代码子图, 提高了检索的准确性, 同期展示了API的关联关系;
(3) 竣事了一个基于图镶嵌的软件花样API检索器用原型, 并通过2个具体软件花样中对于源代码检索的骨子问题为例, 考证了本文方法的有用性.与Chan等东谈主残暴的方法比拟, 本文方法在调回率、F1值上有了显耀提高, 并有用减低了检索反映时代.
本文第1节先容图镶嵌时代.第2节详备描摹本文残暴的基于图镶嵌的软件花样源代码检索方法.第3节通过施行考证本文方法的有用性.第4节先容关系使命.第5节对本文使命进行回来并瞻望将来运筹帷幄使命.91porn地址
1 图镶嵌图镶嵌(graph embedding)的主要主义是将一张图上的结点映射到低维空间的向量, 通过这些向量来体现本来图上的结构信息.这里的结构信息可以是一阶、二阶甚而更高阶的结构, 一阶结构信息即保握本来相邻的结点在镶嵌空间中的距离仍然很近, 而更高阶的结构信息则可以保握本来具有相通高下文的结点在镶嵌空间中的距离仍然很近.咫尺, 图镶嵌时代在学问默示边界颇受热心, 被闲居应用于可视化、过头分类、关联预测、保举等任务.现存的图镶嵌时代主要可以分为以下几类[11].
●基于因子判辨的图镶嵌方法.该类方法将图上结点之间的关系默示成矩阵, 对该矩阵进行因子判辨从而得到镶嵌的向量.矩阵的类型包括持续矩阵、拉普拉斯矩阵(Laplacian matrix)、卡兹相通矩阵(Katz similarity matrix)等, 字据不同的矩阵类型有不同的判辨方法, 其中, Belkin等东谈主[12]残暴的Laplacian Eigenmaps即是对拉普拉斯矩阵作念特征值判辨得到的; Ahmed等东谈主[13]残暴的GF算轨则是基于对持续矩阵作念因子判辨.这种方法的时代复杂度是结点数的平方量级, 可彭胀性较差, 对于范围强大的代码图而言并不适用.
●基于速即游走的图镶嵌方法.该类方法算法概况雷同默示图的许多属性, 比如结点的中心度和相通度. Perozzi等东谈主残暴的DeepWalk[14]即是该方法的典型代表, 该算法运用了神经谈话模子SkipGram的想想, 字据周围的邻居结点来预测现时结点的镶嵌向量.该类方法时时从某一结点为中心启程进行屡次速即游走, 最大化不雅测到的前k个结点以及后k个结点的概率, 概况保握高阶的相通性.当只需要不雅测图的部分结构或者图太大而无法沿途测量时, 该类方法是一个可以的取舍.但是该类方法时时只可捕捉到一条旅途上的局部结构信息, 而况难以找到最好的采样方法, 调优费劲.
●基于深度学习的图镶嵌方法.该类方法有的运用深度自编码器(deep autoencoder)来竣事降维, 因为自编码器领有学习数据中非线性结构的智力.典型地, Wang等东谈主[15]残暴的SDNE包括无监督和有监督两部分:前一部分由自编码器学习概况重新构邻居的结点镶嵌, 后一部分则基于Laplacian Eigenmaps对那些本来相邻而映射到镶嵌空间后却相距很远的结点进行刑事包袱.还有一些算法运用卷积神经蚁集来得到镶嵌向量, 如Kipf等东谈主[16]残暴的一种半监督学习的方法, 这些算法的狡计支拨更小, 更适用于相对稀薄的图.这一类方法天然能更好地捕捉非线性的结构, 但是复杂度还是较高, 需要大齐的狡计支拨.
本文华取的是Tang等东谈主[17]残暴的LINE(large-scale information network embedding)方法, 该方法的可彭胀性很好, 概况快速地对大范围蚁集进行镶嵌, 而况概况同期保留局部和全局的结构信息.该方法严格预见上不属于上述的3种类型, 而是在模子中显式地界说了一阶和二阶的雷同函数以及放纵2个结点之间的荟萃概率散播, 通过最小化镶嵌矩阵与持续矩阵所代表的两个概率散播之间的KL(Kullback-Leibler)散度得到图镶嵌的向量.界说好盘算函数之后, LINE并莫得接纳传统的速即梯度着落算法进行优化, 而是残暴了一种新的边采样的方法(edge-sampling), 字据边的权值成比例的概率进行采样, 这么概况防护速即梯度着落中由于边的权值过大导致的梯度爆炸问题.为了进一步形象地申诉一阶雷同和二阶雷同的预见, 咱们以图 2为例进行阐扬.一阶雷同概况将凯旋有边相连的结点映射到更近的距离, 比如图 2中的结点6和结点7, 它们之间有一条权重很大的边一语气.而二阶雷同则概况将具有换取邻居的结点映射到更近的距离, 比如图 2中的结点5和结点6, 它们齐具有好多换取的邻居结点.因此, 一阶雷同概况保留更多局部的结构信息, 而二阶雷同概况保留更多全局的结构信息.同期斟酌2种雷同的适度, 即是将结点5~结点7齐映射到镶嵌空间中更近的距离.
Fig. 2 Graph embedding maps nodes with similar structure to closer distance in the embedding space[17] 图 2 图镶嵌将结构相通的结点映射到镶嵌空间中更近的距离[17] 2 本文使命本文残暴了一种基于图镶嵌的软件花样源代码检索方法, 其基本想想是:运用图镶嵌时代有用抒发软件代码图中的深层结构信息, 在检索经由中充分地斟酌了结点的高下文和关联关系.如图 3所示.
Fig. 3 Framework of searching software project's source code based on graph embedding 图 3 基于图镶嵌的软件花样源代码检索方法框架该方法主要包括4个部分.
1) 代码图的构建:获取花样的源代码并作念相应解析, 自动构建其代码图.
2) 代码图的镶嵌:使用图镶嵌时代将代码图中的结点默示为向量, 以备后续阶段使用.
3) 问题与代码图结点的匹配:对用户输入的天然谈话问题进行预经管, 然后匹配到代码图中结点手脚候选结点, 并对候选结点进行度量.
4) 代码子图的生成与保举:从第2阶段得到的候选结点中挑选适当的结点组成子图, 并彭胀为连通的子图, 将名次最好的适度复返给用户.
2.1 代码图的构建在一个软件花样(对于面向对象的函数库而言)的源代码中, 主要有两种组成因素:一种是类或接口, 另一种是方法.而类与方法之间的关联关系的类型大体上整个面向对象谈话齐共有, 天然, 部分关联关系与具体编程谈话相关.本文以Java谈话手脚施行对象, 斟酌了Java谈话中的如下6种关联关系, 别离为禁受(Inh)、竣事(Imp)、成员(Mem)、参数(Par)、复返值(Ret)和调用(Call), 用蚁集Rel={Inh, Imp, Mem, Par, Ret}默示(见表 1).在此基础上, 咱们可以运用现存器用对一个开源软件花样的源码进行解析, 构建代码图并存储于图数据库中.
Table 1 Relationship types in code graph 表 1 代码图中的关系类型代码图(code graph).代码图G=(VG, EG)是一个有向无权图, 过头集VG是整个的类和方法的结点, 边集EG中任一条边e(u, v), ∃R∈Rel, 使得uRv.其中, uRv默示u, v之间存在R类型的关联关系.
当今主流的Java源码解析器用有好多, 例如CheckStyle, JAVAssist, Yasca, JDT等.这些器用齐现成可用, 可以解析Java花样并提真金不怕火出代码元素以及它们之间的关系.本文使用的是Eclipse的JDT, 手脚一个轻量级的代码解析器用, 它可以马上将Java代码构建成一个DOM结构的轮廓语法树(AST).代码中的每个元素齐对应AST上的一个结点, 通过遍历AST就可以得到整个代码元素和它们之间的关系, 用来构建软件代码结构图.
本文使用图数据库Neo4j(https://neo4j.com/)来存储代码图.Neo4j是一个用Java竣事, 十足兼容ACID的图数据库, 其自身数据组织的结构和咱们需求的代码结构图终点相通, 亦然通过结点与结点之间的关系组成整张图.除此除外, Neo4j还提供了诸如索引(index)、遍历(traversal)等机制以及一种类SQL的查询谈话Cypher, 以通俗在图上进行更高档的操作.
本文使用图数据库Neo4j(https://neo4j.com/)来存储代码图.Neo4j是一个用Java竣事, 十足兼容ACID的图数据库, 其自身数据组织的结构和咱们需求的代码结构图终点相通, 亦然通过结点与结点之间的关系组成整张图.除此除外, Neo4j还提供了诸如索引(index)、遍历(traversal)等机制以及一种类SQL的查询谈话Cypher, 以通俗在图上进行更高档的操作.
情欲印象下载 2.2 代码图的镶嵌本文使用图镶嵌的原因是在第3阶段, 即代码子图的生成与保举时, 需要狡计图上放纵两个过头之间的距离.图镶嵌时代可以使得这一门径变得十分通俗与快速.淌若接纳在线查询两个过头的最短旅途的方式则将终点耗时, 而图镶嵌经由却是离线的, 在构建完代码图后即可完成.
本文使用了Tang等东谈主[17]残暴的名为LINE的方法, 该方法的可彭胀性很好, 时代复杂度较低, 概况快速地对大范围蚁集进行镶嵌, 而况同期保留局部和全局的结构信息, 概况适用于有向图、无向图、带权图等多种类型.LINE的源代码可以在Github上找到, 本文用Java谈话重新竣事了该算法.
结点之间的距离.代码图镶嵌以后91porn地址, 代码图中的任一过头v∈VG, 齐映射到一个向量rv∈Rd, 其中, d默示该向量的维度; 放纵2个过头u, v之间的距离界说为相应的向量之间的欧氏距离, 即dist(u, v)=