在 gensim word2vec 中使用 PathLineSentences 嵌入多词 ngram 短语

问题描述

我有大约 82 个 gzipped 文件(每个大约 180MB,总共 14GB),其中每个文件都包含换行分隔的句子。我正在考虑使用 gensim Word2Vec 中的 PathLineSentences 来训练词汇表上的 word2vec 模型。以这种方式 I do not have to worry about taking all the sentences 列表进入 RAM。

现在我还想让嵌入包含多词短语。但是从 documentation 来看,我似乎需要一个已经训练过的短语检测器和我拥有的所有句子,例如

from gensim.models import Phrases
# Train a bigram detector.
bigram_transformer = Phrases(all_sentences)
# Apply the trained MWE detector to a corpus,using the result to train a Word2vec model.
model = Word2Vec(bigram_transformer[all_sentences],min_count=1)

现在,我有两个问题:

  1. 有什么方法可以在以流式方式在每个单独文件上运行 Word2Vec 的同时进行短语检测?
  2. 如果没有,有没有什么办法可以像 PathLinesentences 那样进行初始短语检测,就像以流式方式进行短语检测一样?

解决方法

Gensim Phrases 类将接受与 Word2Vec 完全相同形式的数据:所有标记化文本的迭代。

您可以提供两者作为初始训练语料库,然后作为要转换为成对二元组的语料库。

但是,出于清晰度和效率的原因,我强烈建议您不要尝试在同步流中进行短语组合作为 Word2Vec 的馈送。

相反,进行一次转换,将结果写入一个新的单一语料库文件。然后:

  • 您可以轻松查看二元组合的结果
  • 决定要组合哪些单词的逐对计算将只执行一次,从而创建一个简单的空格分隔标记语料库。 (否则,`Word2Vec 完成的每个 epochs + 1 传递都需要重复相同的计算。)

大概是这样的:

with open('corpus.txt','w') as of:
    for phrased_sentence in bigram_transformer[all_sentences]:
        of.write(' '.join(phrased_sentence)
        of.write('\n')

(如果您愿意,您可以改为使用 corpus.txt.gzGzipFile 的 gzip 功能写入像 smart_open 这样的 gzip 文件。)

然后新文件会向您显示 Word2Vec 正在操作的确切数据,并且可以作为简单的语料库提供 - 用 LineSentence 包装为可迭代对象,甚至可以使用 corpus_file 选项传递可以更好地使用更多 workers 线程。