首页> 中国专利> 一种基于对象类型的API补全方法

一种基于对象类型的API补全方法

摘要

本发明公开了一种基于对象类型的API补全方法,包括以下步骤:基于Github代码托管平台生成Java代码数据集;基于Java代码数据集,使用eclipseAST的API解析抽象语法树,再遍历抽象语法树,生成GROUM,构建一个Java JDK的API调用序列数据集;基于LSTM和注意力机制搭建深度学习训练模型;开发一个基于本发明模型的IDEA插件;借助插件客户端对当前代码分析后获取API序列和空缺位置,传给服务器,服务器中模型解析结果并返回API补全推荐列表。本发明旨在为程序开发者在实际编程过程中,提供切实可用的API补全方案,实现了一个基于对象类型的深度学习模型以及IDEA插件用于API补全推荐,提高了API补全的准确性与易用性。

著录项

  • 公开/公告号CN113076089A

    专利类型发明专利

  • 公开/公告日2021-07-06

    原文格式PDF

  • 申请/专利权人 南京大学;

    申请/专利号CN202110404660.6

  • 发明设计人 葛季栋;李传艺;唐泽;陈恒;

    申请日2021-04-15

  • 分类号G06F8/30(20180101);G06F8/70(20180101);G06N3/04(20060101);G06N3/08(20060101);

  • 代理机构

  • 代理人

  • 地址 210023 江苏省南京市鼓楼区仙林大道163号

  • 入库时间 2023-06-19 11:44:10

说明书

技术领域

本发明涉及一种API补全方法,具体涉及一种基于对象类型的API补全方法,属于软件工程和深度学习领域。

背景技术

在软件开发过程中,为了避免重复工作,提高软件开发效率,软件开发者通常会使用一些第三方的API,即应用编程接口,来协助完成软件的功能。这些第三方库的API通过提供对象、方法以及变量来让软件开发者调用,借以实现一系列特定需求或功能。通过调用这些API,软件开发者可以实现某种功能而无需关注其内部的复杂细节;减少代码出错的概率;提高软件开发效率以及更加便捷地复用代码。

然而,学会正确地使用这些API需要耗费软件开发者大量地时间。由于这些第三方库也在不断地迭代更新,其中相当一部分缺少API说明文档。有些即使提供API说明文档的,也有可能存在一些错误。在这种情况下,软件开发者不得不去技术论坛、博客或者Github上寻求帮助,有时甚至需要阅读源代码来寻找这些API的正确使用方法。由于第三方库的庞大数量,即使是使用过的API,比如JDK,最新版本中类已经达到3000多个,一段时间后,软件开发者也很难清晰记住对应API的名称和用法。微软的一项研究表明,67.6%的受访者提到在学习API的过程中受到了资源不足的困扰。软件开发者往往需要多次重复学习过程,极大地影响软件开发的效率。

为了帮助软件开发者正确且快捷地使用这些第三方API,一系列API方法补全工具应运而生。API方法补全是指当程序员已经拼写出一个对象名之后,通过查询这个对象所属类别列出所有的方法供程序员选择。一个在IDEA中智能提示API方法的例子,在集成开发环境中这些智能提示只是将所有可能的API按照使用频率从高到低排列。通过这种方式推荐的API许多是与当前方法块毫不相关的,开发者仍需要在众多的候选API中挑选出正确的API。为解决这种问题,有研究者提出使用数据挖掘算法挖掘API使用模式进行推荐。这些算法通常是从大量的源代码中抽取出API调用序列,以模式识别或者传统序列模型的方法来研究API的使用模式,进而实现API自动补全。

还有一些工作使用深度学习模型来实现API补全任务。长短期记忆模型LSTM是一种时间循环神经网络,被广泛应用于文本处理。它是为了解决传统时间循环网络中存在的长期依赖问题而被专门设计出来的。传统循环网络在利用BP反向传播时,误差会逐级减少。这导致计算过程中,梯度会随着时间序列的增长而指数下降,导致网络权重更新缓慢,LSTM采用门控机制来解决这个问题。注意力机制是由Chorowski等人为机器翻译提出的,其动机来源于人类阅读文本时,会对某些重要的词信息给予额外的关注。它首先被应用于Encoder-Decoder模型,即当需要翻译某个词时,对源语言中的某些词进行特殊关注。在API补全任务中,通过使用注意力机制,模型可以动态地关注有助于执行当前任务的输入的某些部分,将这种相关性概念结合起来。除了可以帮助任务提升性能外,注意力机制还可以提高模型的可解释性,在一定程度上克服循环神经网络中的一些挑战,例如随着输入长度的增加造成的性能下降,以及输入顺序不合理导致的计算效率低下。

为了满足开发人员实际编程需要,提供切实可用的API方法补全,主要研究目标在于设计和实现一个考虑对象特征的API补全方法,同时实现一个支持离线和在线的集成开发环境插件,提供API方法补全服务。

发明内容

本发明是一种基于对象类型的API补全方法,提供一种API调用序列提取方法,包括静态分析源代码,获取对应抽象语法树,以及以方法块为单位构建每个方法块对应的控制流图的技术,从提取出控制流图的数据依赖路径,并针对代码实际结构表征训练深度学习模型,通过LSTM与注意力机制构建为分类任务,结合数据集训练模型进行API补全推荐。该方法能有效锁定API补全候选集,让模型在使用较低内存占用的同时,获得了最快的预测速度。基于对象的API补全模型受到补全位置和对象个数的影响比较小,模型较好适应用户实际使用场景。基于对象类型的API补全模型使用的是深度学习模型来学习代码库中的API用法,因此与基于搜索查询的方法不同,预测时不需要依赖代码库来给出判断。这使得模型可以在用户本地给出推荐,更适合嵌入到集成开发环境中。

本发明所述的一种基于对象类型的API补全方法,其特征在于包含以下步骤:

步骤1:基于Github代码托管平台生成Java代码数据集。

步骤2:基于Java代码数据集构建一个Javva JDK的API调用序列数据集。

步骤3:构建一个基于对象类型的API补全模型。

步骤4:基于API补全模型与数据集训练一个可供用户使用的模型。

步骤5:输出推荐的API补全。

2.根据权利要求1所述的一种基于对象类型的API补全方法,其特征在于步骤1:中基于Github代码托管平台生成Java代码数据集,具体子步骤包括:

步骤1.1:调用Github提供的接口,搜索按star数排序的前15000个使用Java项目地址。

步骤1.2:使用生产者消费者模型下载代码数据集。

3.根据权利要求1所述的一种基于对象类型的API补全方法,其特征在于步骤2:中基于Java代码数据集构建一个Java JDK的API调用序列数据集,具体子步骤包括:

步骤2.1:利用eclipse AST的API将每个源代码文件解析成抽象语法树。

步骤2.2:遍历抽象语法树,生成Groum有向无环图。

步骤2.3:基于源代码对应的控制流图,设计一个算法获取API调用序列。首先初始化一个栈,遍历一遍控制流图,将入度为0的节点存入栈中。然后依次取出栈中的节点,将节点放入输出列表中。接着判断该节点的所有子节点入度在减去1之后是否为0,如果为0,将子节点放入栈。循环该过程,直到栈为空为止。接着对输出列表中的节点依次判断是否是方法调用节点,如果是,判断是否是属于JDK包中的API调用。对输出列表中的节点过滤出同时满足这两个条件的节点,最后输出得到API调用序列。

4.根据权利要求1所述的一种基于对象类型的API补全方法,其特征在于步骤3:中构建一个基于对象类型的API补全模型,具体子步骤包括:

步骤3.1:对每个API调用进行编码。使用了两个词嵌入矩阵

步骤3.2:设计了一个层次型的网络来对API序列进行编码。根据空缺位置将API调用序列划分为三部分:空缺位置之前的API调用,空缺位以及空缺位置之后的API调用。对于空缺位置之前的API调用,先按照对象类型抽取出同属于一个对象的API调用子序列,并将每个调用子序列使用LSTM来编码对象状态。对于空缺位置及空缺位置之后的API序列,使用相同的方法得到对应的对象状态。接着,将对象状态按照其子序列中最后一个API调用在整体序列中的位置进行排序,得到最终的对象状态序列。对于空缺位置和空缺位置之前的对象状态序列,将它输入到一个正向的LSTM模型中,得到空缺位置之前的方法状态

步骤3.3:利用序列编码进行空缺位置补全。利用模型计算得到的每个API对应的补全概率,按照大小排序,推荐概率值较大的前几位API给用户,用于补全空缺位置的API调用。

5.根据权利要求1所述的一种基于对象类型的API补全方法,其特征在于步骤4:中基于API补全模型与数据集得到可供用户使用的模型。具体子步骤包括:

步骤4.1:将第二步得到的数据集分为训练集和测试集,使用训练集进行深度学习模型的训练,使用测试集进行深度学习模型效果的评估。训练集为498569条API调用序列,测试集为Galaxy、Log4j、JGit、Itext、FroyoEmail和Grid-Sphere六个Github项目;

步骤4.2:使用上一步骤的训练集进行深度学习模型的训练,训练目标是最大化模型推荐准确度;

步骤4.3:使用两个验证维度来验证模型效果:Top-k ACC和MRR。TOP-k ACC表示如下,如果真实标签在推荐结果中的次序小于k,就标记为一个命中,统计测试集中的命中次数,再除以测试集的大小|Q|,得到真实标签在前k个推荐结果中就可以找到的概率。TOP-kACC的值越高,表示该推荐算法推荐效果越好。MRR表示如果真实标签在推荐列表中的第一个匹配,分数为1,第二个匹配的分数为0.5,第n个匹配的分数为1/n。计算整个测试集中的匹配得分之和,再除以测试集大小,得到真实概率在整个测试集中的平均得分情况。

6.根据权利要求1所述的一种基于对象类型的API补全方法,其特征在于步骤5:中输出推荐的API补全。具体子步骤包括:

步骤5.1:通过IDEA插件客户端对当前代码块分析后获取API序列和空缺位置,将其传给服务器;

步骤5.2:通过服务器中部署的已训练完备的模型输出推荐的API补全。

本发明与现有技术相比,其显著优点是:基于对象的API补全模型有着最高的Top-1准确率和MRR值。通过使用API候选集来缩小推荐API范围的机制,让模型在使用较低内存占用的同时,获得了最快的预测速度。与其他基线模型相比,基于对象的API补全模型受到补全位置和对象个数的影响比较小。由于基于对象类型的API补全模型使用的是深度学习模型来学习代码库中的API用法,因此与基于搜索查询的方法不同,预测时不需要依赖代码库来给出判断。这使得模型可以在用户本地给出推荐,更适合嵌入到集成开发环境中。

附图说明

图1 API补全方法流程图

图2基于Github的数据集生成流程图

图3源代码转化为GROUM示例图

图4 API补全方法整体结构图

图5基于API调用序列生成训练样本

图6 API补全系统框架图

图7不同模型在测试集上的Top-k准确率

图8不同模型在6个测试项目上的MRR对比

具体实施方式

为使本发明的目的、技术方案和优点更加清晰,下面将结合附图及具体实施例对本发明进行详细描述。

本发明的目的在于解决API补全问题,提出一种基于对象类型的API补全方法。受对象状态图的启发,使用对象类型作为特征,从API调用序列中先抽取同一对象类型的子序列,利用深度学习模型编码出每个对象的状态。再利用对象状态生成整个方法块的状态表示。利用该方法状态来对空缺位置进行补全。本发明概括来说主要包括以下步骤:

步骤1:基于Github代码托管平台生成Java代码数据集;

步骤2:基于Java代码数据集构建一个Java JDK的API调用序列数据集;

步骤3:构建一个基于对象类型的API补全模型;

步骤4:基于API补全模型与数据集训练一个可供用户使用的模型;

步骤5:输出推荐的API补全。

上述一种基于对象类型的API补全方法的详细工作流程如图1所示。这里将对上述步骤进行详细描述。

1.基于Github代码托管平台上的开源项目生成数据集,数据获取的总体流程如图2所示。

步骤1.1:调用Github提供的接口,搜索按star数排序的前15000个使用Java项目地址。

步骤1.2:爬虫模块使用了生产者和消费者模型来实现数据集下载的功能。生产者负责调用Github接口分页下载Github项目地址,消费者负责从未下载的项目地址中选择项目进行下载。使用该模型的主要原因有两点:一方面是可以将两个任务并行处理,加快处理速度;另一方面是可以解决可能出现的API访问限制问题,因为Github接口的调用频率存在上限:每小时只能请求60次,超出后会返回403错误。也就是说,按照每次请求最多返回100个项目地址来计,生产者每小时最多只能生产6000个项目地址。考虑到消费者要负责下载整个项目,速度会比生产者慢很多。因此,当生产者接收到403错误时,会暂时挂起,让消费者继续下载。等待消费者将待下载项目全部下载完成后继续唤醒生产者,重新开始新一轮的下载任务。

2.为了完整适配模型思路,需要对步骤一中生成的代码数据集进一步处理,在步骤2中基于Java代码数据集构建一个Java JDK的API调用序列数据集。具体步骤是:

步骤2.1:利用eclipse AST的API将每个源代码文件解析成抽象语法树。

步骤2.2:遍历抽象语法树,生成Groum。Groum是一个有向无环图,其中节点有两种类型:一种是控制节点,表示代码中的控制流信息;另一种是动作节点,表示代码中的方法调用和变量访问。边表示使用顺序以及数据依赖关系。比如,如果节点A和节点B之间有一条边,这表明节点A和节点B之间存在数据依赖关系,并且节点A在代码中先被调用。图3给出了从源码生成GROUM的示例图。

步骤2.3:基于源代码对应的控制流图,设计一个算法获取API调用序列。首先初始化一个栈,遍历一遍控制流图,将入度为0的节点存入栈中。然后依次取出栈中的节点,将节点放入输出列表中。接着判断该节点的所有子节点入度在减去1之后是否为0,如果为0,将子节点放入栈。循环该过程,直到栈为空为止。接着对输出列表中的节点依次判断是否是方法调用节点,如果是,判断是否是属于JDK包中的API调用。对输出列表中的节点过滤出同时满足这两个条件的节点,最后输出得到API调用序列。

3.为了避免重复工作,提高软件开发效率,软件开发者通常会使用一些第三方的API,即应用编程接口,来协助完成软件的功能。然而,学会正确地使用这些API需要耗费软件开发者大量地时间,帮助软件开发者正确且快捷地使用这些第三方API就成为一个有价值的需求。参考这一真实的工作需求,本步骤旨在获得一个基于深度学习搭建的模型,可以在使用第三方API时,提供切实可用的API方法补全方案推荐。总体模型如图4所示,具体步骤包括:

步骤3.1:对每个API调用进行编码。本发明使用了两个词嵌入矩阵

分别对对象类型和API进行编码,然后将这两个词向量表示拼接在一起,得到时间t的输入,即如公式2所示:

这样就可以在不改变输入序列长度的情况下,显式地告知模型同一个对象内API调用的联系,若两个API调用属于同一个对象,那这两个API调用对应的编码前一半是一样的。同时,因为空缺位置的API调用是未知的,本发明使用“hole”来表示空缺位置的API调用。“hole”一词在API编码时被当作一个特殊的API,它在API词汇表中的序号是1(0是UNK,表示不在词汇表的API调用)。举例来说,c

步骤3.2:本发明设计了一个层次型的网络来对API序列进行编码。首先在对象层,根据空缺位置将API调用序列划分为三部分:空缺位置之前的API调用,空缺位以及空缺位置之后的API调用。对于空缺位置之前的API调用,先按照对象类型抽取出同属于一个对象的API调用子序列,并将每个调用子序列使用LSTM来编码对象状态,编码对象状态过程如公式3所示:

其中,x

步骤3.3:利用序列编码进行空缺位置补全。本发明设计了一个基于补全位置对象类型的预测机制。

根据空缺位置对象类型确定API候选集。因为空缺位置对象类型已知,不属于该对象的API不可能被调用,因此可以根据对象类型中的全部API确定调用候选集。但是这会引起另一个问题,因为每个对象类型中的API数量不固定,这意味着不同对象类型的补全对应的概率输出维度也不相同。本发明采用了类似于word2vec中的思想,使用两个向量的余弦距离来表示两个向量之间的相似度。具体思路:首先将方法状态输入到一个全连接网络中,将方法状态向量转化成和API编码维度相同。然后将API候选集中的API通过API嵌入层查询其对应的向量表示。再计算方法状态向量与候选API向量的余弦,并将结果通过Softmax函数转化为概率表示,从而确定每个候选API对应的推荐可能性。具体过程如公式4所示:

其中W

4.基于API补全模型与数据集训练一个可供用户使用的模型。

步骤4.1:将第二步得到的数据集分为训练集和测试集,使用训练集进行深度学习模型的训练,使用测试集进行深度学习模型效果的评估。在API补全问题中,输入数据就是有空缺的API调用序列,标签是空缺位置的API调用。对于一个API调用序列,依次将其中每个API当作空缺位置,标记为hole,对应生成两条样本:一条样本是包含其后的全部API调用,另一条是不包含其后的API调用。并将该位置的API当作该样本的标签。图5展示了基于一个API调用序列生成训练样本的例子。

如果将全部生成的训练样本组成训练集,每个API序列对应可以生成2n-2个样本,n是API序列的长度。因为API序列平均长度是4,这样可以得到大小约为六百万的训练集。直接使用这个训练集无疑需要花费大量的时间,并且会产生样本重复出现和样本标签不均衡的问题。因为有些API在样本中出现的频次比较高,有些API出现的频次比较低。比如List.init方法中出现了183512次,而MessageDigest.isEqual方法在样本中仅出现了3298次。

这会导致训练的模型会偏向于推荐比较常见的API方法。为了解决这一问题,我们使用一个过滤算法,其核心思想是控制同一API作为标签的次数不超过200次,并且训练集中不会有两个完全相同的样本出现。经过过滤后的API训练样本总数为4985690个,我们将它们作为模型的训练集。测试集为Galaxy、Log4j、JGit、Itext、FroyoEmail和Grid-Sphere六个Github项目;

步骤4.2:使用上一步骤的训练集进行深度学习模型的训练,训练目标是最大化模型推荐准确度;

步骤4.3:使用两个验证维度来验证模型效果:Top-k ACC和MRR。本发明使用了两种验证维度来验证模型效果:Top-k ACC和MRR。Top-k和MRR是评价推荐算法的两种常用指标。Top-k ACC的计算方式如公式5所示:

其中,rank

它表示如果真实标签在推荐结果中的次序小于k,就标记为一个命中。统计测试集中的命中次数,再除以测试集的大小|Q|,得到真实标签在前k个推荐结果中就可以找到的概率。Top-k ACC的值越高,表示该推荐算法推荐效果越好。MRR是一种更加综合的评价指标,它的计算方式如公式7所示:

它表示如果真实标签在推荐列表中的第一个匹配,分数为1,第二个匹配的分数为0.5,第n个匹配的分数为1/n。计算整个测试集中的匹配得分之和,再除以测试集大小,得到真实概率在整个测试集中的平均得分情况。它同样也是越高越好。

5.输出推荐的API补全。具体子步骤包括:

步骤5.1:通过IDEA插件客户端对当前代码块分析后获取API序列和空缺位置,将其传给服务器,IDEA插件架构图如图6所示。

步骤5.2:通过服务器中部署的已训练完备的模型输出推荐的API补全。

本发明提出的模型与其余四个基线模型在补全准确率上的对比实验结果如图7所示。本发明提出的模型在top-1到top-10均优于其他基线模型。在top-1准确率上,本发明提出的模型可以达到48.8%,相较于APIHelper模型提升了约5%,相较于HAPI模型提升了8%左右。而在Top-3准确率上可以达到67.9%的准确率,也就是说有67.9%的待补全API序列可以在模型推荐的前三个API中找到正确答案。在top-10准确率上,本发明提出的模型与APIHelper和HAPI之间比较接近,分别是89.2%、87.5%和85.1%。LSTM模型和Nested-Cache N-gram相比于其他三个模型,效果都比较差,这主要是因为这两个模型在预测时,都需要对全部的API计算补全概率,由于API的数量约为三万五千个,这就意味着每次使用模型预测时,都需要对这三万五千个API分别计算补全的概率,这大大增加了模型的训练难度。而其余三个模型都使用了相应的策略来避免这一问题,本发明提出的模型使用了基于候选集的预测机制来减少需要计算的API补全概率数量。图8展示了在这6个测试项目中不同模型的MRR比较,从图中可以看出,本发明提出的模型在除Grid-Sphere外其余5个项目上的MRR值均是最高。

上面已经参考附图对根据本发明实施的一种基于对象类别的API补全方法进行了详细描述。基于对象类型的API补全模型通过依次编码对象状态和方法状态,再利用方法状态从API候选集中挑选出正确的API。它的主要优点如下所示:相比于基线模型,基于对象的API补全模型有着最高的Top-1准确率和MRR值;通过使用API候选集来缩小推荐API范围的机制,让模型在使用较低内存占用的同时,获得了最快的预测速度;与其他基线模型相比,基于对象的API补全模型受到补全位置和对象个数的影响比较小;由于基于对象类型的API补全模型使用的是深度学习模型来学习代码库中的API用法,因此与基于搜索查询的方法不同,预测时不需要依赖代码库来给出判断。这使得模型可以在用户本地给出推荐,更适合嵌入到集成开发环境中。

需要明确,本发明并不局限于上文所描述并在图中示出的特定配置和处理。并且,为了简明起见,这里省略对已知方法技术的详细描述。当前的实施例在所有方面都被看作是示例性的而非限定性的,本发明的范围由所附权利要求而非上述描述定义,并且,落入权利要求的含义和等同物的范围内的全部改变从而都被包括在本发明的范围之中。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号