# Build Word and Tag vocab
vocab_words, vocab_tags = get_vocabs([train, dev, test])
vocab_glove = get_glove_vocab(config.filename_glove)
下一段,看字面意思这是根据训练集、开发集和测试集建立了一个单词和标签的键值对,然后再导入Glove词向量。先看第一句,我们进data_utils.py中看一下get_vocabs()函数。
def get_vocabs(datasets):
"""Build vocabulary from an iterable of datasets objects
Args:
datasets: a list of dataset objects
Returns:
a set of all the words in the dataset
"""
print("Building vocab...")
vocab_words = set()
vocab_tags = set()
for dataset in datasets:
for words, tags in dataset:
vocab_words.update(words)
vocab_tags.update(tags)
print("- done. {} tokens".format(len(vocab_words)))
return vocab_words, vocab_tags
先看它的介绍,从可迭代的数据集对象中建立词汇表,传入的参数是数据集对象datasets,然后返回单词(words)和标签(tags),而且返回的是set类型对象。
看函数体,首先这里建立了两个set函数vocab_words和vocab_tags,关于set类型,set是一个无序不重复的集合。set和dict类似,也是一组key的集合,但是不存储value,关于set的详细用法之后我也会单独出一个章节,这里可以先看一下。
之后是一个for循环,遍历datasets,for words,tags in datasets:这是将之前传入的打包好的[word, tag]键值对传入进去了,然后执行set的update()函数,来更新集合,最后打印【- done. {} tokens】,参数是vocab_words的长度,最后再返回vocab_words和vocab_tags。
再看第二句
vocab_glove = get_glove_vocab(config.filename_glove)
建立Glove词向量,传入的参数是config中的filename_glove,其中config是我们之前实例化的一个类,进去看一下。
# embeddings
dim_word = 300
dim_char = 100
# glove files
filename_glove = "data/glove.6B/glove.6B.{}d.txt".format(dim_word)
# trimmed embeddings (created from glove_filename with build_data.py)
filename_trimmed = "data/glove.6B.{}d.trimmed.npz".format(dim_word)
use_pretrained = True
可以看到,文件名是【 "data/glove.6B/glove.6B.{}d.txt"】,在这里是【 "data/glove.6B/glove.6B.300d.txt"】
有了文件名参数,我们进入get_glove_vocab()看一下。
def get_glove_vocab(filename):
"""Load vocab from file
Args:
filename: path to the glove vectors
Returns:
vocab: set() of strings
"""
print("Building vocab...")
vocab = set()
with open(filename, encoding='utf-8') as f:
for line in f:
word = line.strip().split(' ')[0]
vocab.add(word)
print("- done. {} tokens".format(len(vocab)))
return vocab
函数体介绍,加载vocab文件,参数是filename,返回vocab,关于【glove.6B.300d】,它长这个样子。
每个单词有300个维度。
- 首先打印【building vocab...】,随后新建一个set类型,以utf-8模式打开文件,然后按行读取,strip我们之前介绍过,去除句子首部和尾部的指定字符,接下来一个split()函数,以空格拆分,这样得到一个列表,我们只去第0位置的元素,也就是它的单词,最后加入vocab中,不过这次用的是add()函数,而不是之前的update()函数,两者有什么区别和联系呢?
相同点:首先都是添加无重复的元素到字典里,然后位置也是随机的。
不同点:add ,是把str作为一个整体放进set里面;update,是拆散了放进set。
image.png - 最后,返回vocab单词表到vocab_glove。