Mittens 库(可通过 pip 安装)如果您的语料库/词汇不是太大或者您的 RAM 大到足以处理整个共现矩阵,则可以这样做。
3 步-
import csv
import numpy as np
from collections import Counter
from nltk.corpus import brown
from mittens import GloVe, Mittens
from sklearn.feature_extraction import stop_words
from sklearn.feature_extraction.text import CountVectorizer
1- 加载预训练模型 - Mittens 需要将预训练模型作为字典加载。从https://nlp.stanford.edu/projects/glove获取预训练模型
with open("glove.6B.100d.txt", encoding='utf-8') as f:
reader = csv.reader(f, delimiter=' ',quoting=csv.QUOTE_NONE)
embed = {line[0]: np.array(list(map(float, line[1:])))
for line in reader}
数据预处理
sw = list(stop_words.ENGLISH_STOP_WORDS)
brown_data = brown.words()[:200000]
brown_nonstop = [token.lower() for token in brown_data if (token.lower() not in sw)]
oov = [token for token in brown_nonstop if token not in pre_glove.keys()]
这里使用棕色语料库作为样本数据集,new_vocab 表示预训练手套中不存在的词汇。共现矩阵是从 new_vocab 构建的。它是一个稀疏矩阵,需要 O(n^2) 的空间复杂度。您可以选择过滤掉稀有的 new_vocab 单词以节省空间
new_vocab_rare = [k for (k,v) in Counter(new_vocab).items() if v<=1]
corp_vocab = list(set(new_vocab) - set(new_vocab_rare))
删除那些稀有词并准备数据集
brown_tokens = [token for token in brown_nonstop if token not in new_vocab_rare]
brown_doc = [' '.join(brown_tokens)]
corp_vocab = list(set(new_vocab))
2- 构建共现矩阵:
sklearn 的 CountVectorizer 将文档转换为 word-doc 矩阵。
矩阵乘法Xt*X给出了词-词共现矩阵。
cv = CountVectorizer(ngram_range=(1,1), vocabulary=corp_vocab)
X = cv.fit_transform(brown_doc)
Xc = (X.T * X)
Xc.setdiag(0)
coocc_ar = Xc.toarray()
3- 微调连指手套模型 - 实例化模型并运行拟合函数。
mittens_model = Mittens(n=50, max_iter=1000)
new_embeddings = mittens_model.fit(
coocc_ar,
vocab=corp_vocab,
initial_embedding_dict= pre_glove)
将模型保存为 pickle 以备将来使用。
newglove = dict(zip(corp_vocab, new_embeddings))
f = open("repo_glove.pkl","wb")
pickle.dump(newglove, f)
f.close()