[英]Build vocab using spacy
我正在使用 spacy 标记器来标记我的数据,然后构建 vocab。
这是我的代码:
import spacy
nlp = spacy.load("en_core_web_sm")
def build_vocab(docs, max_vocab=10000, min_freq=3):
stoi = {'<PAD>':0, '<UNK>':1}
itos = {0:'<PAD>', 1:'<UNK>'}
word_freq = {}
idx = 2
for sentence in docs:
for word in [i.text.lower() for i in nlp(sentence)]:
if word not in word_freq:
word_freq[word] = 1
else:
word_freq[word] += 1
if word_freq[word] == min_freq:
if len(stoi) < max_vocab:
stoi[word] = idx
itos[idx] = word
idx += 1
return stoi, itos
但是因为我有超过 800000 个句子,所以需要几个小时才能完成。
有没有更快更好的方法来实现这一目标? 谢谢。
更新:试图删除 min_freq:
def build_vocab(docs, max_vocab=10000):
stoi = {'<PAD>':0, '<UNK>':1}
itos = {0:'<PAD>', 1:'<UNK>'}
idx = 2
for sentence in docs:
for word in [i.text.lower() for i in nlp(sentence)]:
if word not in stoi:
if len(stoi) < max_vocab:
stoi[word] = idx
itos[idx] = word
idx += 1
return stoi, itos
仍然需要很长时间,spacy 是否有一个 function 可以像在 torchtext (.build_vocab) 中一样构建词汇。
您可以做几件事来加快速度。
import spacy
from collections import Counter
def build_vocab(texts, max_vocab=10000, min_freq=3):
nlp = spacy.blank("en") # just the tokenizer
wc = Counter()
for doc in nlp.pipe(texts):
for word in doc:
wc[word.lower_] += 1
word2id = {}
id2word = {}
for word, count in wc.most_common():
if count < min_freq: break
if len(word2id) >= max_vocab: break
wid = len(word2id)
word2id[word] = wid
id2word[wid] = word
return word2id, id2word
解释:
spacy.blank
nlp.pipe
对于大量文本来说很快(不太重要,可能与空白 model 无关)Counter
针对这种计数任务进行了优化另一件事是,您在最初的示例中构建词汇的方式,您将使用具有足够标记的前 N 个单词,而不是前 N 个单词,这可能是错误的。
另一件事是,如果您使用 spaCy,您不应该以这种方式构建您的词汇 - spaCy 有自己的内置词汇 class 可以处理将令牌转换为 ID。 我猜您可能需要将此映射用于下游任务或其他内容,但请查看vocab 文档以查看是否可以使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.