改进现有的基本GloVe模型

时间:2017-04-25 18:15:29

标签: nlp text-classification

我使用GloVe作为我研究的一部分。我已经从here下载了模型。我一直在使用GloVe进行句子分类。我分类的句子特定于特定领域,比如一些STEM主题。但是,由于现有的GloVe模型是在一般语料库中训练的,因此它们可能无法为我的特定任务产生最佳结果。

所以我的问题是,我将如何加载重新训练的模型,并在我自己的语料库上再学习一点,以便学习语料库的语义?如果可能的话,这样做是有好处的。

3 个答案:

答案 0 :(得分:3)

经过一番挖掘后,我在git repo上找到了this issue。有人提出以下建议:

  

是的,由于优化设置,这不会很好。但你可以做的是在你自己的语料库上训练GloVe向量,然后用预训练的GloVe向量连接这些向量,以便在你的最终应用程序中使用。

这就是答案。

答案 1 :(得分:1)

Mittens库(可通过pip安装)会执行以下操作:如果您的语料库/ vocab不太大或者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-加载预训练模型-手套需要将预训练模型作为字典加载。从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)

将模型另存为泡菜,以备将来使用。

newglove = dict(zip(corp_vocab, new_embeddings))
f = open("repo_glove.pkl","wb")
pickle.dump(newglove, f)
f.close()

答案 2 :(得分:0)

我相信GloVe(全局向量)不是要附加的,因为它是基于语料库的整体单词共现统计数据,该统计信息来自仅在初始训练时才知道的单个语料库

您可以做的是使用gensim.scripts.glove2word2vec api将GloVe向量转换为word2vec,但我认为您无法继续训练,因为它加载在KeyedVector而非完整模型中