在基于 gensim 文件的训练中表示包含多个句子的文档的正确方法
Correct way to represent documents containing multiple sentences in gensim file-based training
我正在尝试使用 gensim 的基于文件的训练(来自以下文档的示例):
from multiprocessing import cpu_count
from gensim.utils import save_as_line_sentence
from gensim.test.utils import get_tmpfile
from gensim.models import Word2Vec, Doc2Vec, FastText
# Convert any corpus to the needed format: 1 document per line, words delimited by " "
corpus = api.load("text8")
corpus_fname = get_tmpfile("text8-file-sentence.txt")
save_as_line_sentence(corpus, corpus_fname)
# Choose num of cores that you want to use (let's use all, models scale linearly now!)
num_cores = cpu_count()
# Train models using all cores
w2v_model = Word2Vec(corpus_file=corpus_fname, workers=num_cores)
d2v_model = Doc2Vec(corpus_file=corpus_fname, workers=num_cores)
ft_model = FastText(corpus_file=corpus_fname, workers=num_cores)
然而,我的实际语料库包含很多文档,每个文档包含很多句子。
例如,假设我的语料库是莎士比亚的戏剧——每部戏剧都是一个文件,每个文件都有很多句子,我想为每部戏剧学习嵌入,但词嵌入只能来自同一个句子。
由于基于文件的训练意味着每行一个文件,我假设我应该每行放一个剧本。但是,基于文件的培训文档没有包含多个句子的文档示例。
有没有办法窥视模型内部以查看在训练之前找到的文档和单词上下文对?
构建此文件并保持句子边界的正确方法是什么?
谢谢
这些算法实现对实际句子没有任何真正的理解或依赖。他们只接受文本——一连串的单词标记。
提供给 Word2Vec
的文本通常是多个句子。有时像句末句号这样的标点符号甚至被保留为伪词。 (当源数据中的句子真的彼此连续时,句子之间重叠的单词上下文 windows 甚至可能是一个好处。)
所以您不必担心"maintaining sentence boundaries"。您提供的任何文本都是真正同时出现的有意义的单词单位,也可以使用。 (特别是在 Word2Vec
和 FastText
中,即使将文本之间的分隔符更改为句子、段落、部分或文档也不大可能对最终的词向量产生太大影响——它只是在改变训练上下文的一个子集,并且可能不会以任何方式显着改变哪些词影响哪些其他词。)
但是,您应该注意 gensim
中的另一个实施限制:每个训练文本的长度只能为 10,000 个标记,如果您提供更大的文本,多余的标记将被忽略.
因此,请务必使用 10k 或更短的文本——即使您必须任意拆分较长的文本。 (根据上文,令牌分组中的任何此类任意额外中断不太可能对结果产生明显影响。)
但是,在 corpus_file
模式下使用 Doc2Vec
会出现特殊问题,因为在该模式下,您无法为文本指定首选 tags
。 (文本的标签,在这种模式下,本质上就是行号。)
在原始序列语料库模式中,这个 10k 标记限制的解决方法只是将较大的文档分解为多个文档 - 但对原始文档中的所有子文档使用相同的重复 tags
。 (这非常接近任何大小的文档对训练的影响。)
如果您的文档包含超过 10k 个标记,我建议您要么不使用 corpus_file
模式,要么想出一些方法来使用少于 10k 个标记的逻辑子文档,然后也许对您的更大的模型进行建模docs 作为它们的子文档集,或者以其他方式调整您的下游任务以处理相同的子文档单元。
我正在尝试使用 gensim 的基于文件的训练(来自以下文档的示例):
from multiprocessing import cpu_count
from gensim.utils import save_as_line_sentence
from gensim.test.utils import get_tmpfile
from gensim.models import Word2Vec, Doc2Vec, FastText
# Convert any corpus to the needed format: 1 document per line, words delimited by " "
corpus = api.load("text8")
corpus_fname = get_tmpfile("text8-file-sentence.txt")
save_as_line_sentence(corpus, corpus_fname)
# Choose num of cores that you want to use (let's use all, models scale linearly now!)
num_cores = cpu_count()
# Train models using all cores
w2v_model = Word2Vec(corpus_file=corpus_fname, workers=num_cores)
d2v_model = Doc2Vec(corpus_file=corpus_fname, workers=num_cores)
ft_model = FastText(corpus_file=corpus_fname, workers=num_cores)
然而,我的实际语料库包含很多文档,每个文档包含很多句子。 例如,假设我的语料库是莎士比亚的戏剧——每部戏剧都是一个文件,每个文件都有很多句子,我想为每部戏剧学习嵌入,但词嵌入只能来自同一个句子。 由于基于文件的训练意味着每行一个文件,我假设我应该每行放一个剧本。但是,基于文件的培训文档没有包含多个句子的文档示例。 有没有办法窥视模型内部以查看在训练之前找到的文档和单词上下文对?
构建此文件并保持句子边界的正确方法是什么?
谢谢
这些算法实现对实际句子没有任何真正的理解或依赖。他们只接受文本——一连串的单词标记。
提供给 Word2Vec
的文本通常是多个句子。有时像句末句号这样的标点符号甚至被保留为伪词。 (当源数据中的句子真的彼此连续时,句子之间重叠的单词上下文 windows 甚至可能是一个好处。)
所以您不必担心"maintaining sentence boundaries"。您提供的任何文本都是真正同时出现的有意义的单词单位,也可以使用。 (特别是在 Word2Vec
和 FastText
中,即使将文本之间的分隔符更改为句子、段落、部分或文档也不大可能对最终的词向量产生太大影响——它只是在改变训练上下文的一个子集,并且可能不会以任何方式显着改变哪些词影响哪些其他词。)
但是,您应该注意 gensim
中的另一个实施限制:每个训练文本的长度只能为 10,000 个标记,如果您提供更大的文本,多余的标记将被忽略.
因此,请务必使用 10k 或更短的文本——即使您必须任意拆分较长的文本。 (根据上文,令牌分组中的任何此类任意额外中断不太可能对结果产生明显影响。)
但是,在 corpus_file
模式下使用 Doc2Vec
会出现特殊问题,因为在该模式下,您无法为文本指定首选 tags
。 (文本的标签,在这种模式下,本质上就是行号。)
在原始序列语料库模式中,这个 10k 标记限制的解决方法只是将较大的文档分解为多个文档 - 但对原始文档中的所有子文档使用相同的重复 tags
。 (这非常接近任何大小的文档对训练的影响。)
如果您的文档包含超过 10k 个标记,我建议您要么不使用 corpus_file
模式,要么想出一些方法来使用少于 10k 个标记的逻辑子文档,然后也许对您的更大的模型进行建模docs 作为它们的子文档集,或者以其他方式调整您的下游任务以处理相同的子文档单元。