作者:Hamel Husain
机器之心编译
参与:魔王

想提升代码搜索效果?首先你得知道怎么才算提升。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/