gensim Chaining Phrases objects produces inconsistent scores

xurqigkl  于 5个月前  发布在  其他
关注(0)|答案(5)|浏览(174)

您好,根据您的描述,您在使用gensim的Phrases模型时遇到了问题。当使用Phraser模型(不仅查找bigram,而且还查找trigram)时,返回的trigram模型的分数在某些情况下不正确(例如使用NPMI作为评分函数并找到得分>1)。

我理解您的情况是,当使用相同的分隔符时,后续的Phrases对象的大写字母计数错误。在上面的示例中,bigram guten_tag出现了5次,但gutentag也出现在不同的上下文中:

print(list(biphraser[sentences]))

[['guten_tag', 'meine_damen', 'und_herren'],
 ['guten_tag', 'meine_damen', 'und_herren'],
 ['guten_tag', 'meine_damen', 'und_herren'],
 ['guten_tag', 'herr_p'],
 ['ich_wünsche', 'ihnen_einen', 'guten_tag'],
 ['ich_wünsche', 'ihnen_einen', 'schönen', 'tag'],
 ['ich_wünsche', 'ihnen_einen', 'guten', 'abend']]

不是所有gutentag的出现都被合并成bigram(例如最后两个句子)。这是正确的行为。但是,当在此输入上运行后续的Phrases模型(例如trigrams)时,如果使用相同的分隔符,它将学习错误的bigram计数:

guten: 1
tag: 1
guten_tag: 5

如您所见,对于guten_tag而言,bigram计数错误(一个bigram不应该比其任何组成部分出现得更频繁)。这里的混淆来自于事实:实际上,guten_tag对于trigram模型来说只是一个单独的标记。但是由于使用了相同的分隔符,它被错误地认为是bigram计数。

如果您的假设正确,则这只会高估bigram计数,从而导致通过阈值的更多短语。

当使用不同于tokens中的分隔符来链接chained Phrases(最好使用不出现在tokens中的分隔符)时,问题就不会出现了。

我不知道如何以简单易懂的方式解决这个问题。这需要确定包含分隔符的标记是否实际上是一个bigram还是一个单独的标记(由具有相同分隔符的前一个 Phraser 创建)。实际上,我也遇到了这个问题:如果分隔符作为常规标记出现在您的语料库中。

因为有一个解决方法可用,所以我可以暂时忍受这个问题。但是至少我认为文档应该更新以反映在链接chained Phrases时出现的这个缺点(因为这是文档中明确给出的例子)。

4dc9hkyq

4dc9hkyq1#

我意识到修复可能并不那么困难。我的天真做法是在词汇表中使用元组(worda, wordb)作为键,而不是delimiter.join([worda, wordb])。如果欢迎PR,我可以尝试在周末准备一个修复。
祝好,
克里斯蒂安

du7egjpx

du7egjpx2#

感谢cgumpert提供的详细描述和示例报告👍
你是对的,trigram认为guten_tag是不同的标记(在这种情况下这是正确的)。
一方面,我同意这是一个错误(因为nmpi产生的分数不是来自一个范围),另一方面-计数器在这种情况下是正确的(因为guten_tag对于短语来说不是一个bigram,这是语料库中的另一个标记)。当然,PR总是欢迎的!
需要通过@piskvorky@alexgarel讨论这个问题吗?

uqxowvwt

uqxowvwt3#

真的,我不是统计学方面的Maven,但我认为@cgumpert是正确的,因为实际的Phrases实现并不知道链式处理,如果你期望链式处理能真正检测到原始语料库中的3-grams统计意义。

我认为使用元组是一个好方法,但我不确定你是否可以将短语广义化以考虑这一点并在统计意义上正确。但这确实值得一试。

@cgumpert,如果你觉得需要的话,你可以向第二个短语器传递一个特定的参数,使其处于“链”模式(这样的例子它就知道它必须在条目中分割n-grams)。一个明确的参数可能会避免破坏与实际实现的兼容性。

@cgumpert,作为旁注,如果分隔符出现在你的语料库中,你需要选择另一个分隔符(当然!这就是为什么有一个参数的原因)。我不打算解决原始语料库中出现分隔符的问题(至少在链式模式下)。

5lhxktic

5lhxktic4#

@alexgarel 另一个想法(供讨论)-也许可以添加一个参数,说明“n元组的最大字数是多少”,这允许仅应用一次短语(立即使用三元组,或5-元组等)。在这种情况下,当前的问题不再发生(因为用户可以在拟合短语之前对其进行参数化,并没有必要多次应用它)。

mtb9vblg

mtb9vblg5#

我认为这是一个更好的解决方案。

相关问题