Gensim word2vec 在预定义字典和单词索引数据上

Gensim word2vec on predefined dictionary and word-indices data

我需要使用 gensim 在推文上训练 word2vec 表示。与我在 gensim 上看到的大多数教程和代码不同,我的数据不是原始数据,而是已经过预处理。我在包含 65k 个单词(包括一个 "unknown" 标记和一个 EOL 标记)的文本文档中有一个字典,并且推文被保存为一个带有索引的 numpy 矩阵到这个字典中。数据格式的简单示例如下所示:

dict.txt

you
love
this
code

推文(5 条未知,6 条停产)

[[0, 1, 2, 3, 6],
 [3, 5, 5, 1, 6],
 [0, 1, 3, 6, 6]]

我不确定应该如何处理索引表示。一种简单的方法是将索引列表转换为字符串列表(即 [0, 1, 2, 3, 6] -> ['0', '1', '2', '3', '6 ']) 当我将它读入 word2vec 模型时。然而,这肯定是低效的,因为 gensim 然后将尝试查找用于例如的内部索引。 '2'.

如何加载此数据并使用 gensim 以高效的方式创建 word2vec 表示?

gensim 中初始化 Word2Vec 模型的正常方法是 [1]

model = Word2Vec(sentences, size=100, window=5, min_count=5, workers=4)

问题是,sentences是什么? sentences 应该是 words/tokens 的可迭代对象的迭代器。它就像您拥有的 numpy 矩阵,但每一行的长度可以不同。

如果您查看 gensim.models.word2vec.LineSentence 的文档,它会为您提供一种将文本文件直接加载为句子的方法。作为提示,根据文档,需要

one sentence = one line; words already preprocessed and separated by whitespace.

当它说 words already preprocessed 时,它指的是小写、词干提取、停用词过滤和所有其他文本清理过程。在您的情况下,您不希望 56 出现在您的句子列表中,因此您需要将它们过滤掉。

鉴于你已经有了numpy矩阵,假设每一行都是一个句子,那么最好将它转换成一个二维数组并过滤掉所有56。生成的二维数组可以直接用作 sentences 参数来初始化模型。唯一的问题是当你想在训练后查询模型时,你需要输入索引而不是标记。

现在你有一个问题是模型是否直接采用整数。在 Python 版本中,它不检查类型,只是传递唯一的标记。在这种情况下,您的独特索引将正常工作。但大多数时候您会希望使用 C-Extended 例程来训练您的模型,这很重要,因为它可以提供 70 倍的性能。 [2] 我想在那种情况下,C 代码可能会检查字符串类型,这意味着存储了一个字符串到索引的映射。

这是低效的吗?我认为不是,因为您拥有的字符串是数字,通常比它们代表的真实标记短得多(假设它们是来自 0 的紧凑索引)。因此模型的尺寸会更小,这将在最后对模型进行序列化和反序列化时节省一些工作量。您实际上已经以较短的字符串格式对输入标记进行了编码,并将其与 word2vec 训练分开,并且 word2vec 模型不需要也不需要知道这种编码发生在训练之前。

我的哲学是try the simplest way first。我只是将整数的样本测试输入扔给模型,看看会出现什么问题。希望对你有帮助。

[1] https://radimrehurek.com/gensim/models/word2vec.html

[2] http://rare-technologies.com/word2vec-in-python-part-two-optimizing/

我遇到了同样的问题。甚至通过

转换为字符串数组
>>> arr_str = np.char.mod('%d', arr)

在 运行 Word2Vec 时引发异常:

>>> model = Word2Vec(arr_str)
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()

我的解决方案是将整数数组写成文本,然后将 word2vec 与 LineSentence 一起使用。

import numpy as np
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence

np.savetxt('train_data.txt', arr, delimiter=" ", fmt="%s") 
sentences = LineSentence('train_data.txt')
model = Word2Vec(sentences)