Advertisement

A Toolkit for Generating Code Knowledge Graphs生成代码知识图谱的工具

阅读量:

A Code Generation Suite用于构建代码知识图谱的工具

阅读量2.2k
收藏 7

点赞数
文章标签: 知识图谱 人工智能 python
版权
事实表明,知识图谱在支持语义搜索与自然语言理解的应用系统方面具有显著价值.本研究致力于开发GraphGen4Code,一种基于知识图谱构建代码工具集,旨在辅助程序搜索、代码解析、错误诊断及代码自动化优化.该工具通过提取程序中类、函数及方法的关键节点语义信息,并以边表示函数调用数据流及相关文档信息(来自代码文档或论坛讨论)的方式构建知识图谱模型.我们采用RDF命名实体建模方法对程序进行知识表示,并支持将模型以JSON格式导出.

Introduction
DBpedia、Wikidata、Freebase、YAGO以及NELL各自都是近年来建立起来的知识图谱。这些知识图谱分别在语义解析方面表现出色,在推荐系统中也提供了强大的支持,在信息检索领域具有重要价值,并且在回答问题方面展现了显著能力。

目前已有大量涉及设计代码问题的机器学习方法,并涵盖跨语言问题领域。然而,在代码表示方面仍存在两个主要挑战:(a)现有方法主要基于代码的局部表示方式(如语法树、行号编码等),缺乏对全局语义的有效捕捉能力;(b)这些方法很少包含与代码运行相关的自然语言信息(除非专门用于代码搜索这类任务)。

我们致力于开发一个工具包,并使该集合具备生成真实程序自然语言描述(增强型代码表示)的能力

我们采用了跨编程的先进程序分析技术来构建基于语言的过程间数据和控制流模型。由于要对单个API库进行语义建模的原因,将其大规模应用于数十万API变得极为困难。在本文中,我们构建了一个API上的抽象集合框架,并通过该框架使得我们可以将这种分析技术扩展到数以百万计的不同程序中。我们的目标是采用Python作为主要语言,并且尽管我们的技术易于扩展到JavaScript和Java等其他语言环境[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13], 但Python作为一种动态语言所面临的挑战依然十分严峻[14][15][16][17][18][19][20][21][22][23][24][25].为了展示该工具包(GraphGen4Code)的可扩展性, 我们在GitHub上创建了包含约130万个独立Python脚本的数据集,并对其中每一个Python脚本都进行了独立图谱化的处理.此外,我们还利用该工具包将库调用链接到了相关的文档资料以及网络论坛讨论内容.具体而言,我们通过信息检索技术识别代码中最常用的模块,并将这些模块与其所属类、方法或函数连接起来,并进一步尝试将其与相关文档资料或网络论坛讨论内容连接起来.对于网络论坛讨论内容,我们则通过信息检索技术将其与相关的方法或类进行了关联.

总之,我们的贡献如下:

1,为代码建立知识图谱的可扩展工具集

2,一种表示代码及其自然语言的模型

3,它已经应用到130万个Python程序和4700万篇帖子,生成超过20亿的代码知识图

Modeling 将每一个程序建模为独立的图,在此过程中以确保每次调用或读取任何数据结构(例如列表、字典、对象字段)时,在图中都有唯一对应的节点,并且这些节点均通过一条带标签的边与真实的方法名称或函数名称相关联。而相同的函数在其不同调用之间仅需通过将它们各自的label相互连接即可实现。

论坛帖子也有自己的节点。帖子中描述了问题,解答,帖子中提到的任意代码(如Figure 3)。对于文档,一旦数据结构形成,一个代表着函数文档的节点将包含该函数的参数和返回值的类型(如Figure 4)。程序图中的松耦合通过label实现。在论坛中帖子中提及的特定的Python类、模块和函数和调用方式连接到标签节点完全相同,连接到类或函数的label上。相似地,文档连接到它的类或函数的label上。任意新的模块文档,新的程序图或新的帖子都可以被添加到已有的图上,抽取过程确保指向标签的链接是新的信息的连接。结果图允许直接使用它们的全名查询python类,函数的模式使用和自然语言描述。

该系统支持以RDF或JSON格式输出结果。在RDF版本中,为了增强与其他本体的集成能力,我们继承并利用现有的相关属性,其中语义科学集成本体(SIO)提供了一个简单、集成的上层本体(类型、关系),适用于物理、过程和信息实体之间的一致知识表示;同时我们也借鉴了schema.org等资源。然而,由于目前未发现一个单一的本体能够完整覆盖建模所需的所有概念,我们必须自行添加大量独特的属性和类别以满足需求。尽管这种方法在某些情况下非常有效,但如果我们当前的建模与特定应用程序的需求不完全匹配时,我们也提供了灵活性较高的JSON格式表示方案

3.1 代码分析
尽管WALA是一个专注于Java、JavaScript和Python的过程间数据流与控制流分析的知名库,在本研究中我们希望将WALA框架扩展至能够处理由数十万个流行Python程序调用的各种接口。这一核心问题在于如何对API函数进行语义建模。为此可采取两种策略:第一种是利用现有分析框架追踪API函数所在的代码中的数据流与控制流;第二种是通过手动定义模板对其进行抽象化处理。然而第一种方法对于Python而言不可行的原因在于:大部分Python代码是由其他语言编写的(而非基于同一语言)。此外考虑到这些接口背后隐藏着庞大的库代码(数百万行),无法达到足够的精确度来进行扩展分析。而第二种方法由于其高度抽象性仅适用于极少数量的实际接口调用情况。因此当处理成千上万的程序时该方法就显得力不从心难以发挥应有的作用。

为了将分析扩展到更大规模,我们采用:

(a)在导入函数的所有调用中都只返回一个新的对象,并且没有副作用的情况下。这一假设虽然简化了分析过程但却带来了不精确性。但目前仍未能扩展这种分析方法到数百万个程序的情况。

(b) 为了实现对象字段的任意读取均由返回自身导入函数创建的目的,在这种情况下必然区分对象字段与自身。它有助于将分析扩展至海量不同类型的API,并无需关注字段的具体语义内容,在基于动态类型的Python等语言中难以实现。

(c)新对象可能包含操作或字段读取,在处理这些操作和读取时所采用的方式与接入API的方式一致。

WALA建模框架这一项扩展当前仅限于支持Python语言;然而它同样也可采用类似的技术手段应用于其他动态编程语言;例如JavaScript等技术领域。然而对于Java语言则无需这种扩展因为它具备强大的类型系统特性。

调用Python的Pandas库函数pandas.read_csv()完成文件读取操作,并将结果展示于图1中。该过程返回的对象类型未知,在Python编程环境中大多数代码并未明确规定变量类型(即非静态类型化语言)。为了对对象进行筛选处理,在step 2中完成中间操作:通过函数where补充缺失值信息(如图2所示)。随后,在step 3中利用pandas.train_test_split()方法将样本划分为训练集与验证集两部分。在step 4中分别构建两个训练子集用于后续模型训练(如图4所示)。随后将这些预处理结果传递至step 6中的拟合操作阶段(即fit函数)。在step 5中完成SVC模型的构建过程后,在step 7中按照X和Y分量的形式存储测试集,并作为预测操作参数提供给模型。

扩展程序,进行图展示

使用绿色边框表示程序流程图中的数据流方向,在数据流难以明确识别的情况下(尤其是手动绘制流程图时),使用程序流程图中的边框来表示调用顺序非常有帮助。在图表中展示了代码中两种主要的数据流向关系:flowsTo表示从一个节点到另一个节点的数据流动;immediatelyPrecedes: 表示代码执行的顺序。

节点1代表read_csv的执行,图中捕获了参数,filename和low_memory选项。

节点2是where类型的调用,并且它连接着来自节点1的immediatelyPrecedes边和flowsTo边;这是因为其程序顺序位于节点1之后,并且需要从节点1获取数据;其中一条hasOrdinalPosition边被注释标记为0值,则表明这条flowsTo边是该where调用的操作目标

节点3标识为test_train_split函数,并且其程序执行顺序位于步骤2之后;然而,在函数调用时会将数据作为第一个参数传递给它;实际上,“test_train_split”这个函数即接受输入数据作为第一个参数;当此函数进行调用时会返回一个元组;随后会将这个元组进行拆分,并分别赋值给变量train与变量test;这一结果将被记录在标记4a和4b的第一个框中;其中每个框内的标签都将显示所接收的数据值

在代码中,每个train和test都被划分为X,Y组件;以斜体形式显示为4a和4b。其中train节点标记为4a,并用于fit操作;而test节点标记为4b,并负责从DataSet读取数据;标记为4b的节点随后连接至predict函数。

Extracting Documentation into the Graph

为了生产所有函数和类的文档,在分析阶段解析了所有的导入语句并汇总了一些流行库的信息。对于这些库而言,在运行时执行一种对象检测机制——Python内省机制(有时也称为类型内省),这种机制允许我们获取对象的所有相关信息,包括其类型及其属性等基础属性。随后构建一个虚拟环境并安装这些库;使用inspect模块收集文档信息;这一操作显然具有语言特定性——目前该工具包仅支持从Python代码中抽取代码文档;然而我们注意到支持多语言抽取的可能性因此在对新语言进行扩展时需要针对该语言编写特定代码;最后将每个函数和类抽取得到的文档信息添加到知识图谱中;存储文档字符串、基类信息、参数名称及其类型、返回类型等关键数据字段如图所示

许多研究倾向于采用tokens或抽象语法树作为代码的表征手段。这些编码方案主要应用于特定领域,并其目标通常是实现高效的分布式编码。其中一些研究会从给定的代码中构建不同类型的概率模型以满足相关需求。少部分研究则采用数据流与控制流相结合的方式来进行编码分析。例如,在JavaScript等语言中应用程序依赖关系图来检测重复码是一种常用方法。然而这种依赖通常发生在程序运行时以确保实时性与准确性之间的平衡点。类似地,在增强基于AST(Abstract Syntax Tree)的方法中,则会利用局部的数据流与控制流程信息来预测变量名称并发现潜在引用错误。结合基于token的编码方案与基于边的对象分析方法以及AST节点预测技术文档

我们工作的显著优势体现在以下两个方面:其一,在程序间的数据和控制流关系中,在第一类函数存在且无需外部输入时(即当第一类函数存在且无需外部输入时),我们能够构建出更加详尽的代码表征方案。其二,在上述基础上的基础上(即在此基础上),我们通过这种表征构建多目标代码知识图谱,并将其与之相关的文本内容相连。

GraphGen4Code基于用于代码理解的库静态分析技术(WALA)进行本体建模。其核心在于通过建模控制代码与数据流的关系,并实现对类与方法的文档化连接。

全部评论 (0)

还没有任何评论哟~