Gensim 短语模型词汇长度与迭代添加文档的数量不对应
原文标题 :Gensim phrases model vocabulary length does not correspond to amount of iteratively added documents
我反复应用…
bigram.add_vocab(<List of List with Tokens>)
方法来更新…
bigram = gensim.models.phrases.Phrases(min_count=bigramMinFreq, threshold=10.0)
Gensim 短语模型。每次迭代最多添加约 10,000 个文档。因此,我的直觉是 Phrases 模型随着每个添加的文档集而增长。我通过检查双元词汇的长度来检查这种直觉……
len(bigram.vocab))
此外,我还检查了冻结短语模型中短语的数量…
bigram_freezed = bigram.freeze()
len(bigram_freezed.phrasegrams)
结果输出如下所示:
Data of directory: 000 is loaded
Num of Docs: 97802
Updated Bigram Vocab is: 31819758
Amount of phrasegrams in freezed bigram model: 397554
-------------------------------------------------------
Data of directory: 001
Num of Docs: 93368
Updated Bigram Vocab is: 17940420
Amount of phrasegrams in freezed bigram model: 429162
-------------------------------------------------------
Data of directory: 002
Num of Docs: 87265
Updated Bigram Vocab is: 36120292
Amount of phrasegrams in freezed bigram model: 661023
-------------------------------------------------------
Data of directory: 003
Num of Docs: 55852
Updated Bigram Vocab is: 20330876
Amount of phrasegrams in freezed bigram model: 604504
-------------------------------------------------------
Data of directory: 004
Num of Docs: 49390
Updated Bigram Vocab is: 31101880
Amount of phrasegrams in freezed bigram model: 745827
-------------------------------------------------------
Data of directory: 005
Num of Docs: 56258
Updated Bigram Vocab is: 19236483
Amount of phrasegrams in freezed bigram model: 675705
-------------------------------------------------------
...
可以看出,冻结的二元模型的二元词汇计数和短语元计数都没有持续增加。我预计这两个计数都会随着文档的增加而增加。
我不明白phrase.vocabandphraser.phrasegrams 指的是什么吗? (如果需要,我可以添加整个对应的 Jupyter Notebook 单元格)
回复
我来回复-
gojomo 评论
该回答已被采纳!
默认情况下,为了避免使用无限量的 RAM,Gensim
Phrases
类使用默认参数max_vocab_size=40000000
,根据以下源代码和文档:https://radimrehurek.com/gensim/models/phrases.html#gensim.models.phrases.Phrases
不幸的是,这个上限背后的机制非常粗糙且不直观。每当他们调查字典中所有已知键的计数(包括单字和双字)达到此阈值(默认为 40,000,000)时,就会执行
prune
操作以低频丢弃所有令牌计数(单字和双字),直到总唯一-密钥低于阈值。并且,它将未来修剪的低频下限设置为至少与修剪所需的一样高。例如,第一次被击中时,它可能需要丢弃所有 1-count 标记。并且由于词频的典型 Zipfian 分布,这一步可能不仅使已知标记的总数略低于阈值,而且大大低于阈值。并且,任何后续的修剪都将首先消除至少出现少于 2 次的所有内容。
这会导致您看到的锯齿计数。当模型无法适应
max_vocab_size
时,它会过度收缩。在处理一个非常大的语料库的过程中,它可能会多次这样做。因此,低频词/二元组的最终计数也可能被严重低估——这在某种程度上取决于一个键的计数是否在各种修剪阈值中幸存下来。 (这也受令牌出现在语料库中的位置的影响。仅在最后一次修剪后出现在语料库中的令牌仍然会有精确的计数,即使它只出现一次!尽管出现任意次数的稀有令牌可能会被严重低估,如果它们在每次之前的修剪时总是低于截止值。)最好的解决方案是使用精确计数来使用/关联磁盘上的一些溢出存储,仅在最后修剪(如果有的话),确保仅丢弃真正最不常用的密钥。不幸的是,Gensim 从未实现过该选项。
在许多情况下,次优可能是使用内存高效的近似计数算法,该算法模糊地为大量键保持正确的计数值。过去在 Gensim 中对此进行了少量工作,但尚未与
Phrases
功能集成。这给您留下了短期内唯一可行的解决方法:将
max_vocab_size
参数更改为更大。您可以尝试将其设置为
math.inf
(由于 int-vs-float 比较可能会降低性能)或sys.maxsize
– 基本上完全关闭修剪,以查看您的调查是否可以在不耗尽 RAM 的情况下完成。但是,无论如何,您可能会耗尽内存。你也可以尝试一个更大但不是本质上无限的上限——任何适合你的 RAM——这样修剪的工作就会少得多。但你仍然会看到总数的非直观减少,有时,如果事实上阈值是强制执行的。根据文档,非常粗略(可能已经过时)估计默认
max_vocab_size=40000000
在峰值饱和时消耗大约 3.6GB。所以如果你有一台 64GB 的机器,你可能会尝试 10-14x大于默认值等。2年前