您现在的位置:主页 > 新闻动态 >

用code2vec、glow和spaCy举行词嵌入

时期:2022-07-05 11:05 点击数:
本文摘要:革新机械学习模型的一个有效方法是使用词嵌入。使用词嵌入,你可以捕捉文档中单词的上下文,然后找到语义和语法上的相似之处。在这篇文章中,我们将讨论词嵌入技术的一个不寻常的应用。 我们将实验使用OpenAPI的规范作为数据集在其中找到最好的词嵌入技术。作为OpenAPI规范的一个例子,我们将使用OpenAPI specifications(https://swagger.io/specification/)提供的OpenAPI规范数据集。

华体会体育

革新机械学习模型的一个有效方法是使用词嵌入。使用词嵌入,你可以捕捉文档中单词的上下文,然后找到语义和语法上的相似之处。在这篇文章中,我们将讨论词嵌入技术的一个不寻常的应用。

我们将实验使用OpenAPI的规范作为数据集在其中找到最好的词嵌入技术。作为OpenAPI规范的一个例子,我们将使用OpenAPI specifications(https://swagger.io/specification/)提供的OpenAPI规范数据集。

最大的挑战是,OpenAPI规范既不是自然语言,也不是代码。但这也意味着我们可以自由使用任何可用的嵌入模型。在这个实验中,我们将研究三种可能可行的候选方案:code2vec、glow和spaCy。

code2vec是一个神经模型,可以学习与源代码相关的类比。该模型是在Java代码数据库上训练的,可是你可以将其应用于任何代码。另有GloVe。

GloVe是一种常用的自然语言处置惩罚算法。它是在维基百科和Gigawords上训练的。最后,我们有了spaCy。虽然spaCy是最近才生长起来的,但该算法已经以世界上最快的词嵌入而闻名。

让我们看看这些算法中哪一种更适合OpenAPI数据集,哪种算法对于OpenAPI规范的运行速度更快. 我把这篇文章分为六个部门,每个部门都包罗代码示例和一些未来使用的提示,外加一个结论。下载数据集下载词汇表提取字段名称标识化建立字段名称的数据集测试嵌入结论现在,我们可以开始了。1.下载数据集首先,我们需要下载整个apis-guru数据库:https://apis.guru/。你会注意到,大多数apis-guru规范都是Swagger 2.0花样。

可是,OpenAPI规范的最新版本是OpenAPI 3.0。因此,让我们使用Unmock剧本将整个数据集转换为这种花样!你可以根据Unmock openapi剧本的README文件中的说明完成此操作:https://github.com/meeshkan/unmock-openapi-scripts/blob/master/README.md。这可能需要一段时间,最后,你将获得一个大数据集。

2.下载词汇表code2vec从code2vec GitHub页面下载模型,根据快速入门部门中的说明举行操作。使用gensim库加载。model = word2vec.load_word2vec_format(vectors_text_path, binary=False)GloVe从网站下载一个GloVe词汇表。

我们选了最大的一个,因为这样它就更有可能找到我们所有的单词。你可以选择下载它的位置,但为了利便起见,最好将其存储在事情目录中。手动加载GloVe词汇表。embeddings_dict = {}with open("../glove/glove.6B.300d.txt", 'r', encoding="utf-8") as f: for line in f: values = line.split() word = values[0] vector = np.asarray(values[1:], "float32") embeddings_dict[word] = vectorspaCy加载spaCy的词汇表:nlp = spacy.load(‘en_core_web_lg’).3.提取字段名OpenAPI规范名称的整个列表可以从scripts/fetch-list.sh文件或使用以下函数(对于Windows)获取:def getListOfFiles(dirName): listOfFile = os.listdir(dirName) allFiles = list() for entry in listOfFile: fullPath = posixpath.join(dirName, entry) if posixpath.isdir(fullPath): allFiles = allFiles + getListOfFiles(fullPath) else: allFiles.append(fullPath) return allFiles另一个大问题是从我们的OpenAPI规范中获取字段名。

为此,我们将使用openapi-typed库。让我们界说一个get_fields函数,该函数接受OpenAPI规范并返回字段名列表:def get_fields_from_schema(o: Schema) -> Sequence[str]: return [ *(o['properties'].keys() if ('properties' in o) and (type(o['properties']) == type({})) else []), *(sum([ get_fields_from_schema(schema) for schema in o['properties'].values() if not ('$ref' in schema) and type(schema) == type({})], []) if ('properties' in o) and ($ *(get_fields_from_schema(o['additionalProperties']) if ('additionalProperties' in o) and (type(o['additionalProperties']) == type({})) else []), *(get_fields_from_schema(o['items']) if ('items' in o) and (type(o['items'] == type({}))) else []), ]def get_fields_from_schemas(o: Mapping[str, Union[Schema, Reference]]) -> Sequence[str]: return sum([get_fields_from_schema(cast(Schema, maybe_schema)) for maybe_schema in o.values() if not ('$ref' in maybe_schema) and (type(maybe_schema) == type({}))], [])def get_fields_from_components(o: Components) -> Sequence[str]: return [ *(get_fields_from_schemas(o['schemas']) if 'schemas' in o else []), ] def get_fields(o: OpenAPIObject) -> Sequence[str]: return [ *(get_fields_from_components(o['components']) if 'components' in o else []), ]恭喜!现在我们的数据集准备好了。4.标识化字段名可能包罗标点符号,如_和-符号,或巨细写为驼峰的单词。

我们可以把这些单词切分,称为标识。下面的camel_case函数检查驼峰命名。

首先,它检查是否有标点符号。如果是,那就不是驼峰命名。

然后,它检查单词内部是否有大写字母(不包罗第一个和最后一个字符)。def camel_case(example): if any(x in example for x in string.punctuation)==True: return False else: if any(list(map(str.isupper, example[1:-1])))==True: return True else: return False下一个函数camel_case_split将驼峰单词拆分为多个部门。为此,我们应该识别大写字母并标志巨细写更改的位置。函数返回拆分后的单词列表。

例如,字段名BodyAsJson转换为一个列表['Body','As','Json']。def camel_case_split(word): idx = list(map(str.isupper, word)) case_change = [0] for (i, (x, y)) in enumerate(zip(idx, idx[1:])): if x and not y: case_change.append(i) elif not x and y: case_change.append(i+1) case_change.append(len(word)) return [word[x:y] for x, y in zip(case_change, case_change[1:]) if x < y]这个camel_case_split函数随后用于以下标志化算法。

在这里,我们首先检查单词中是否有标点符号。然后,我们把这个词分成几部门。这些词有可能是驼峰词。

华体会体育

如果是这样的话,我们可以把它分成小块。最后,拆分每个元素后,整个列表将转换为小写。def tokenizer(mylist): tokenized_list=[] for word in mylist: if '_' in word: splitted_word=word.split('_') for elem in splitted_word: if camel_case(elem): elem=camel_case_split(elem) for el1 in elem: tokenized_list.append(el1.lower()) else: tokenized_list.append(elem.lower()) elif '-' in word: hyp_word=word.split('-') for i in hyp_word: if camel_case(i): i=camel_case_split(i) for el2 in i: tokenized_list.append(el2.lower()) else: tokenized_list.append(i.lower()) elif camel_case(word): word=camel_case_split(word) for el in word: tokenized_list.append(el.lower()) else: tokenized_list.append(word.lower()) return(tokenized_list)tokenizer(my_word)5.建立字段名的数据集现在,让我们用所有规范中的字段名建立一个大数据集。

下面的dict_dataset函数获取文件名和路径的列表,并打开每个规范文件。对于每个文件,get_field函数返回字段名的列表。

某些字段名称可能在一个规范中重复。为了制止这种重复,让我们使用list(dict.fromkeys(col))将列表中的字段名列表转换为字典,然后再返回。然后我们可以将列表标识化。

华体会体育

最后,我们建立一个以文件名为键,以字段名列表为值的字典。def dict_dataset(datasets): dataset_dict={} for i in datasets: with open(i, 'r') as foo: col=algo.get_fields(yaml.safe_load(foo.read())) if col: mylist = list(dict.fromkeys(col)) tokenized_list=tokenizer(mylist) dataset_dict.update({i: tokenized_list}) else: continue return (dataset_dict)6.测试嵌入code2vec和GloVe现在我们可以找出词汇表外的单词(未识此外单词)并盘算这些单词在code2vec词汇表中所占的百分比。

以下代码也适用于GloVe。not_identified_c2v=[]count_not_indent=[]total_number=[]for ds in test1: count=0 for i in data[ds]: if not i in model: not_identified_c2v.append(i) count+=1 count_not_indent.append(count) total_number.append(len(data[ds]))total_code2vec=sum(count_not_indent)/sum(total_number)*100spaCyspaCy词汇表差别,因此我们需要相应地修改代码:not_identified_sp=[]count_not_indent=[]total_number=[]for ds in test1: count=0 for i in data[ds]: f not i in nlp.vocab: count+=1 not_identified_sp.append(i) count_not_indent.append(count) total_number.append(len(data[ds]))total_spacy=sum(count_not_indent)/sum(total_number)*100对于code2vec、glow和spaCy,未识别单词的百分比划分为3.39、2.33和2.09。

由于每个算法的百分比相对较小且相似,因此我们可以举行另一个测试。首先,让我们建立一个测试字典,其中的单词应该在所有API规范中都是相似的:test_dictionary={'host': 'server','pragma': 'cache','id': 'uuid','user': 'client','limit': 'control','balance': 'amount','published': 'date','limit': 'dailylimit','ratelimit': 'rate','start': 'display','data': 'categories'}对于GloVe和code2vec,我们可以使用gensim库提供的similar_by_vector方法。spaCy还没有实现这个方法,可是通过这个我们可以自己找到最相似的单词。

为此,我们需要花样化输入向量,以便在距离函数中使用。我们将在字典中建立每个键,并检核对应的值是否在100个最相似的单词中。首先,我们将花样化词汇表以便使用distance.cdist函数。

这个函数盘算词汇表中每对向量之间的距离。然后,我们将从最小距离到最大距离对列表举行排序,并取前100个单词。from scipy.spatial import distancefor k, v in test_dictionary.items(): input_word = k p = np.array([nlp.vocab[input_word].vector]) closest_index = distance.cdist(p, vectors)[0].argsort()[::-1][-100:] word_id = [ids[closest_ind] for closest_ind in closest_index] output_word = [nlp.vocab[i].text for i in word_id] #output_word list1=[j.lower() for j in output_word] mylist = list(dict.fromkeys(list1))[:50] count=0 if test_dictionary[k] in mylist: count+=1 print(k,count, 'yes') else: print(k, 'no')下表总结了却果。

spaCy显示单词“client”位于单词“user”的前100个最相似的单词中。它对险些所有的OpenAPI规范都是有用的,而且可以用于未来OpenAPI规范相似性的分析。

单词“balance”的向量靠近单词“amount”的向量。我们发现它对支付API特别有用。结论我们已经为OpenAPI规范实验了三种差别的词嵌入算法。

只管这三个词在这个数据集上都体现得很好,可是对最相似的单词举行分外的比力讲明spaCy对我们的情况更好。spaCy比其他算法更快。spaCy词汇表的读取速度比glow或code2vec词汇表快5倍。

然而,在使用该算法时,缺少内置函数(如similar_by_vector和similar_word)是一个障碍。另外,spaCy与我们的数据集很好地事情,这并不意味着spaCy对世界上的每个数据集都市更好。所以,请随意实验为你自己的数据集嵌入差别的单。


本文关键词:用,code2vec,、,glow,和,spaCy,举行,词,嵌入,革新,华体会体育

本文来源:华体会体育-www.cerison.cn



Copyright © 2007-2022 www.cerison.cn. 华体会体育科技 版权所有 备案号:ICP备16211411号-3