它是 ReduceVocab() 中的错误还是遗漏了啥?

Posted

技术标签:

【中文标题】它是 ReduceVocab() 中的错误还是遗漏了啥?【英文标题】:Is it a bug in ReduceVocab() or missing something?它是 ReduceVocab() 中的错误还是遗漏了什么? 【发布时间】:2022-01-22 16:45:44 【问题描述】:

这是我从google word2vec.c下载的word2vec的一段代码:

// Reduces the vocabulary by removing infrequent tokens
void ReduceVocab() 
    int a, b = 0;
    unsigned int hash;
    for (a = 0; a < vocab_size; a++) if (vocab[a].cn > min_reduce) 
            vocab[b].cn = vocab[a].cn;
            vocab[b].word = vocab[a].word;
            b++;
         else free(vocab[a].word);
    vocab_size = b;
    
    for (a = 0; a < vocab_hash_size; a++) vocab_hash[a] = -1;
    for (a = 0; a < vocab_size; a++) 
        // Hash will be re-computed, as it is not actual
        hash = GetWordHash(vocab[a].word);
        while (vocab_hash[hash] != -1) hash = (hash + 1) % vocab_hash_size;
        vocab_hash[hash] = a;
    
    fflush(stdout);
    min_reduce++;

LearnVocabFromTrainFile 函数中调用。 假设min_reduce=5 因此,如果输入文件不是那么好,我的意思是如果一个词说“你好”,出现在ReduceVocab 调用时出现4,并且vocab 将从自身中删除hello

后来,当ReduceVocab 再次调用时,幸运的是hello 出现了5 次.. 似乎ReduceVocab 将再次删除hello

事实上,hello 出现了 9 次,应该在 vocab 中,但是上面的代码删除了它。 这并不重要,因为这种情况似乎很少发生。只是想知道我的分析是否正确,或者我错过了代码中的某些内容。 感谢您的建议。

【问题讨论】:

变量声明很重要。请发布一个完整的示例,其中包含所有声明以及使用该函数的某种上下文。见minimal reproducible example 谢谢,我已经添加了我下载代码的网址。 【参考方案1】:

查看相关来源的更好的 URL 是:

https://github.com/tmikolov/word2vec/blob/master/word2vec.c#L185

据我了解,这不是错误 - 只是与非直观效果的妥协。

此代码故意使用粗略/近似方法来确保跟踪的词汇术语的数量永远不会超过0.7 * vocab_hash_size(2100 万)。每当术语的数量达到高水位线时,所有出现次数少于 min_reduce 的术语都会被丢弃 - 下次会增加 min_reduce 以获取更多。

(在实践中,这种不断上升的地板,连同词频的典型长尾 Zipfian 分布,可能意味着在每次触发 ReduceVocab 操作时,大多数项被丢弃,带来总词汇量比0.7 * vocab_hash_size小。)

以临时运行方式丢弃已知计数的一个不可避免的影响是,每次丢弃后的计数不再完整和准确。因此,语料库中术语的相对位置会对ReduceVocab-pruned 的术语产生很大影响——每次“错过”截止时间的术语可能比最终的min_reduce 出现的次数要多得多。 .此外,如果术语的早期出现计数没有在更早的ReduceVocab 步骤中存活下来,那么所有不太常见的单词的最终计数都可能不完整。

不过,这种方法可以防止词汇调查占用任意数量的 RAM,并且在典型情况下,稀有字数尾部的不精确性并不是太大的问题。

如果您有 RAM 并且想要防止这种行为,您可以编辑源以使 vocab_hash_size 任意变大,以便永远不会触发 ReduceVocab()(因此您的最终计数是准确的),或者很少发生足以让任何受它影响的词语都与您无关。

【讨论】:

感谢您的回答,尤其是 long-tail Zipfian distribution 信息。这在现实中很少发生。和zipf distribution 帮助我理解为什么它很少发生。

以上是关于它是 ReduceVocab() 中的错误还是遗漏了啥?的主要内容,如果未能解决你的问题,请参考以下文章

urls.py 中的 Django 时区逻辑和通用视图引发错误,但它是视图、字段还是我?

字符串错误还是编译器错误?

FxCop - CA1034 错误 - 为啥?

数组是如何存储在内存中的?

PHP 8 评论错误

java日历返回错误的星期