Hamel Husain作者魔王编译

如何提升代码搜索效果?GitHub团队打造代码搜索领域的GLUE数据集

想提升代码搜索效果?首先你得知道怎么才算提升。GitHub 团队创建 CodeSearchNet 语料库,旨在为代码搜索领域提供基准数据集,提升代码搜索结果的质量。

搜索代码进行重用、调用,或者借此查看别人处理问题的方式,是软件开发者日常工作中最常见的任务之一。然而,代码搜索引擎的效果通常不太好,和常规的 web 搜索引擎不同,它无法充分理解你的需求。GitHub 团队尝试使用现代机器学习技术改善代码搜索结果,但很快意识到一个问题:他们无法衡量改善效果。自然语言处理领域有 GLUE 基准,而代码搜索评估领域并没有适合的标准数据集。

因此 GitHub 与 Weights & Biases 公司展开合作,并于昨日推出 CodeSearchNet Challenge 评估环境和排行榜。与此同时,GitHub 还发布了一个大型数据集,以帮助数据科学家构建适合该任务的模型,并提供了多个代表当前最优水平的基线模型。该排行榜使用一个 query 标注数据集来评估代码搜索工具的质量。

  • 论文地址:https://arxiv.org/abs/1909.09436

  • 语料库及基线模型地址:https://github.com/github/CodeSearchNet

  • 挑战赛地址:https://app.wandb.ai/github/codesearchnet/benchmark

CodeSearchNet 语料库

使用专家标注创建足以训练高容量模型的大型数据集成本高昂,不切实际,因此 GitHub 创建了一个质量较低的代理数据集。GitHub 遵循文献 [5, 6, 9, 11] 中的做法,将开源软件中的函数与其对应文档中的自然语言进行匹配。但是,这样做需要执行大量预处理步骤和启发式方法。

通过对常见错误案例进行深入分析,GitHub 团队总结出一些通用法则和决策。

CodeSearchNet 语料库收集过程

GitHub 团队从开源 non-fork GitHub repo 中收集语料,使用 libraries.io 确认所有项目均被至少一个其他项目使用,并按照「流行度」(popularity)对其进行排序(流行度根据 star 和 fork 数而定)。然后,删除没有 license 或者 license 未明确允许重新分发的项目。之后,GitHub 团队使用其通用解析器 TreeSitter 对所有 Go、Java、JavaScript、Python、PHP 和 Ruby 函数(或方法)执行分词操作,并使用启发式正则表达式对函数对应的文档文本进行分词处理。

筛选

为了给 CodeSearchNet Challenge 生成训练数据,GitHub 团队首先考虑了语料库中具备相关文档的函数。这就得到了一组 (c_i , d_i) 对,其中 c_i 是函数,d_i 是对应的文档。为了使数据更加适合代码搜索任务,GitHub 团队执行了一系列预处理步骤:

  • 文档 d_i 被截断,仅保留第一个完整段落,以使文档长度匹配搜索 query,并删除对函数参数和返回值的深入讨论。

  • 删除 d_i 短于三个 token 的对,因为此类注释无法提供有效信息。

  • 删除 c_i 实现少于三行的对,因为它们通常包含未实现的方法、getters、setters 等。

  • 删除名称中包含子字符串「test」的函数。类似地,删除构造函数和标准扩展方法,如 Python 中的 __str__、Java 中的 toString。

  • 识别数据集中的(近似)重复函数,仅保留其中一个副本,从而删除数据集中的重复项。这就消除了出现多个版本自生成代码和复制粘贴的情况。

筛选后的语料库和数据抽取代码详见:https://github.com/github/CodeSearchNet

数据集详情

该数据集包含 200 万函数-文档对、约 400 万不具备对应文档的函数(见下表 1)。GitHub 团队将该数据集按照 80-10-10 的比例划分为训练集/验证集/测试集,建议用户按照该比例使用此数据集。

表 1:数据集详情。

局限性

该数据集噪声很大。首先,文档与 query 存在本质区别,它们使用的是不同的语言形式。文档通常是代码作者在写代码的同时写成的,更倾向于使用同样的词汇,这与搜索 query 存在差异。其次,尽管 GitHub 团队在创建数据集的过程中执行了数据清洗,但他们无法得知每个文档 d_i 描述对应代码段 c_i 的精确程度。最后,一些文档是用非英语文本写成的,而 CodeSearchNet Challenge 评估数据集主要关注的是英文 query。

CodeSearchNet 基线模型

基于 GitHub 之前在语义代码搜索领域的努力,该团队发布了一组基线模型,这些模型利用现代技术学习序列(包括 BERT 类的自注意力模型),帮助数据科学家开启代码搜索。

和之前的工作一样,GitHub 团队使用代码和 query 的联合嵌入来实现神经搜索系统。该架构对每个输入(自然或编程)语言使用一个编码器,并训练它们使得输入映射至一个联合向量空间。其训练目标是将代码及其对应语言映射至邻近的向量,这样我们就可以嵌入 query 实现搜索,然后返回嵌入空间中「邻近」的代码段集合。

考虑 query 和代码之间更多交互的较复杂模型当然性能更好,但是为每个 query 或代码段生成单个向量可以实现更高效的索引和搜索。

为了学习这些嵌入函数,GitHub 团队在架构中加入了标准序列编码器模型,如图 3 所示。首先,根据输入序列的语义对其执行预处理:将代码 token 中的标识符分割为子 token(如变量 camelCase 变成了两个子 token:camel 和 case),使用字节对编码(byte-pair encoding,BPE)分割自然语言 token。

图 3:模型架构概览。

然后使用以下架构之一处理 token 序列,以获得(语境化的)token 嵌入。

  • 神经词袋模型:每个(子)token 都被转换为可学习嵌入(向量表示)。

  • 双向 RNN 模型:利用 GRU 单元总结输入序列。

  • 一维卷积神经网络:用于处理输入 token 序列。

  • 自注意力模型:其多头注意力用于计算序列中每个 token 的表示。

之后,使用池化函数将这些 token 嵌入组合为一个序列嵌入,GitHub 团队已经实现了 mean/max-pooling 和类注意力的加权和机制。

下图展示了基线模型的通用架构:

CodeSearchNet 挑战赛

为了评估代码搜索模型,GitHub 团队收集了一组代码搜索 query,并让程序员标注 query 与可能结果的关联程度。他们首先从必应中收集了一些常见搜索 query,结合 StaQC 中的 query 一共获得 99 个与代码概念相关的 query(GitHub 团队删除了 API 文档查询方面的问题)。

图 1:标注者指导说明。

之后,GitHub 团队使用标准 Elasticsearch 和基线模型,从 CodeSearchNet 语料库中为每个 query 获得 10 个可能的结果。最后,GitHub 团队请程序员、数据科学家和机器学习研究者按照 [0, 3] 的标准标注每个结果与 query 的关联程度(0 表示「完全不相关」,3 表示「完全匹配」)。

未来,GitHub 团队想在该评估数据集中纳入更多语言、query 和标注。接下来几个月,他们将持续添加新的数据,为下一个版本的 CodeSearchNet Challenge 制作扩展版数据集。

原文链接:https://github.blog/2019-09-26-introducing-the-codesearchnet-challenge/

工程语料库代码搜索数据集GitHub
1
相关数据
池化技术

池化(Pooling)是卷积神经网络中的一个重要的概念,它实际上是一种形式的降采样。有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见的。它是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。直觉上,这种机制能够有效的原因在于,在发现一个特征之后,它的精确位置远不及它和其他特征的相对位置的关系重要。池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。通常来说,CNN的卷积层之间都会周期性地插入池化层。

机器学习技术

机器学习是人工智能的一个分支,是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、计算复杂性理论等多门学科。机器学习理论主要是设计和分析一些让计算机可以自动“学习”的算法。因为学习算法中涉及了大量的统计学理论,机器学习与推断统计学联系尤为密切,也被称为统计学习理论。算法设计方面,机器学习理论关注可以实现的,行之有效的学习算法。

自注意力技术

自注意力(Self-attention),有时也称为内部注意力,它是一种涉及单序列不同位置的注意力机制,并能计算序列的表征。自注意力在多种任务中都有非常成功的应用,例如阅读理解、摘要概括、文字蕴含和语句表征等。自注意力这种在序列内部执行 Attention 的方法可以视为搜索序列内部的隐藏关系,这种内部关系对于翻译以及序列任务的性能非常重要。

基准技术

一种简单的模型或启发法,用作比较模型效果时的参考点。基准有助于模型开发者针对特定问题量化最低预期效果。

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

数据科学技术

数据科学,又称资料科学,是一门利用数据学习知识的学科,其目标是通过从数据中提取出有价值的部分来生产数据产品。它结合了诸多领域中的理论和技术,包括应用数学、统计、模式识别、机器学习、数据可视化、数据仓库以及高性能计算。数据科学通过运用各种相关的数据来帮助非专业人士理解问题。

验证集技术

验证数据集是用于调整分类器超参数(即模型结构)的一组数据集,它有时也被称为开发集(dev set)。

卷积神经网络技术

卷积神经网路(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。卷积神经网路由一个或多个卷积层和顶端的全连通层(对应经典的神经网路)组成,同时也包括关联权重和池化层(pooling layer)。这一结构使得卷积神经网路能够利用输入数据的二维结构。与其他深度学习结构相比,卷积神经网路在图像和语音识别方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他深度、前馈神经网路,卷积神经网路需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。 卷积网络是一种专门用于处理具有已知的、网格状拓扑的数据的神经网络。例如时间序列数据,它可以被认为是以一定时间间隔采样的一维网格,又如图像数据,其可以被认为是二维像素网格。

词袋模型技术

词袋模型(英语:Bag-of-words model)是个在自然语言处理和信息检索(IR)下被简化的表达模型。此模型下,像是句子或是文件这样的文字可以用一个袋子装着这些词的方式表现,这种表现方式不考虑文法以及词的顺序。最近词袋模型也被应用在电脑视觉领域。

映射技术

映射指的是具有某种特殊结构的函数,或泛指类函数思想的范畴论中的态射。 逻辑和图论中也有一些不太常规的用法。其数学定义为:两个非空集合A与B间存在着对应关系f,而且对于A中的每一个元素x,B中总有有唯一的一个元素y与它对应,就这种对应为从A到B的映射,记作f:A→B。其中,y称为元素x在映射f下的象,记作:y=f(x)。x称为y关于映射f的原象*。*集合A中所有元素的象的集合称为映射f的值域,记作f(A)。同样的,在机器学习中,映射就是输入与输出之间的对应关系。

语料库技术

语料库一词在语言学上意指大量的文本,通常经过整理,具有既定格式与标记;事实上,语料库英文 "text corpus" 的涵意即为"body of text"。

查询技术

一般来说,查询是询问的一种形式。它在不同的学科里涵义有所不同。在信息检索领域,查询指的是数据库和信息系统对信息检索的精确要求

自然语言处理技术

自然语言处理(英语:natural language processing,缩写作 NLP)是人工智能和语言学领域的分支学科。此领域探讨如何处理及运用自然语言;自然语言认知则是指让电脑“懂”人类的语言。自然语言生成系统把计算机数据转化为自然语言。自然语言理解系统把自然语言转化为计算机程序更易于处理的形式。

数据集成技术

数据集成是把不同来源、格式、特点性质的数据在逻辑上或物理上有机地集中,从而为企业提供全面的数据共享。在企业数据集成领域,已经有了很多成熟的框架可以利用。目前通常采用联邦式、基于中间件模型和数据仓库等方法来构造集成的系统,这些技术在不同的着重点和应用上解决数据共享和为企业提供决策支持。

推荐文章
暂无评论
暂无评论~