python - 如何使用 KenLM 计算困惑度?

标签 python nlp language-model kenlm perplexity

假设我们在此基础上构建一个模型:

$ wget https://gist.githubusercontent.com/alvations/1c1b388456dc3760ffb487ce950712ac/raw/86cdf7de279a2b9bceeb3adb481e42691d12fbba/something.txt
$ lmplz -o 5 < something.txt > something.arpa

来自困惑度公式 (https://web.stanford.edu/class/cs124/lec/languagemodeling.pdf)

应用逆对数公式求和得到内变量,然后取n次方根,困惑度数异常小:

>>> import kenlm
>>> m = kenlm.Model('something.arpa')

# Sentence seen in data.
>>> s = 'The development of a forward-looking and comprehensive European migration policy,'
>>> list(m.full_scores(s))
[(-0.8502398729324341, 2, False), (-3.0185394287109375, 3, False), (-0.3004383146762848, 4, False), (-1.0249041318893433, 5, False), (-0.6545327305793762, 5, False), (-0.29304179549217224, 5, False), (-0.4497605562210083, 5, False), (-0.49850910902023315, 5, False), (-0.3856896460056305, 5, False), (-0.3572353720664978, 5, False), (-1.7523181438446045, 1, False)]
>>> n = len(s.split())
>>> sum_inv_logs = -1 * sum(score for score, _, _ in m.full_scores(s))
>>> math.pow(sum_inv_logs, 1.0/n)
1.2536033936438895

使用数据中未找到的句子重试:

# Sentence not seen in data.
>>> s = 'The European developement of a forward-looking and comphrensive society is doh.'
>>> sum_inv_logs = -1 * sum(score for score, _, _ in m.full_scores(s))
>>> sum_inv_logs
35.59524390101433
>>> n = len(s.split())
>>> math.pow(sum_inv_logs, 1.0/n)
1.383679905428275

并再次尝试使用完全超出域的数据:

>>> s = """On the evening of 5 May 2017, just before the French Presidential Election on 7 May, it was reported that nine gigabytes of Macron's campaign emails had been anonymously posted to Pastebin, a document-sharing site. In a statement on the same evening, Macron's political movement, En Marche!, said: "The En Marche! Movement has been the victim of a massive and co-ordinated hack this evening which has given rise to the diffusion on social media of various internal information"""
>>> sum_inv_logs = -1 * sum(score for score, _, _ in m.full_scores(s))
>>> sum_inv_logs
282.61719834804535
>>> n = len(list(m.full_scores(s)))
>>> n
79
>>> math.pow(sum_inv_logs, 1.0/n)
1.0740582373271952

虽然,预计较长的句子具有较低的困惑度,但奇怪的是,差异小于 1.0 并且在小数范围内。

以上是使用 KenLM 计算困惑度的正确方法吗?如果没有,有谁知道如何通过 Python API 使用 KenLM 计算困惑度?

最佳答案

参见https://github.com/kpu/kenlm/blob/master/python/kenlm.pyx#L182

import kenlm

model=kenlm.Model("something.arpa") 
per=model.perplexity("your text sentance")

print(per)

关于python - 如何使用 KenLM 计算困惑度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43841467/

相关文章:

python - 在列表中查找与其他元素不同的元素的最pythonic方法是什么?

python - 如何猜测以某种方式生成的句子列表的语法?

java - 从公司名称查找公司部门/行业

nlp - 计算文本字符串相似度的方法?

python - 来自 Tensorflow TextLineDataset 的 Ngram

machine-learning - 如何标准化不同长度句子中单词的概率?

python - 如何测试 matplotlib 的 show() 显示图形而不实际显示它?

python - 在python中裁剪视频

python - 将 NumPy 数组转换为 Python 列表

nlp - 使用 Google T5 进行词嵌入?