gpt4 book ai didi

python - 计算两个文档之间的对称 Kullback-Leibler 散度

转载 作者:太空狗 更新时间:2023-10-29 18:09:21 25 4
gpt4 key购买 nike

我已经关注论文here和代码 here (它是使用对称 kld 和论文中第一个链接中提出的退避模型实现的)用于计算两个文本数据集之间的 KLD。我在最后更改了 for 循环以返回两个数据集的概率分布,以测试两者之和是否为 1:

import re, math, collections

def tokenize(_str):
stopwords = ['and', 'for', 'if', 'the', 'then', 'be', 'is', \
'are', 'will', 'in', 'it', 'to', 'that']
tokens = collections.defaultdict(lambda: 0.)
for m in re.finditer(r"(\w+)", _str, re.UNICODE):
m = m.group(1).lower()
if len(m) < 2: continue
if m in stopwords: continue
tokens[m] += 1

return tokens
#end of tokenize

def kldiv(_s, _t):
if (len(_s) == 0):
return 1e33

if (len(_t) == 0):
return 1e33

ssum = 0. + sum(_s.values())
slen = len(_s)

tsum = 0. + sum(_t.values())
tlen = len(_t)

vocabdiff = set(_s.keys()).difference(set(_t.keys()))
lenvocabdiff = len(vocabdiff)

""" epsilon """
epsilon = min(min(_s.values())/ssum, min(_t.values())/tsum) * 0.001

""" gamma """
gamma = 1 - lenvocabdiff * epsilon

""" Check if distribution probabilities sum to 1"""
sc = sum([v/ssum for v in _s.itervalues()])
st = sum([v/tsum for v in _t.itervalues()])

ps=[]
pt = []
for t, v in _s.iteritems():
pts = v / ssum
ptt = epsilon
if t in _t:
ptt = gamma * (_t[t] / tsum)
ps.append(pts)
pt.append(ptt)
return ps, pt

我测试过

d1 = """许多研究出版物希望您使用 BibTeX,哪个更好
组织整个过程。为了具体起见,假设您的来源
文件是 x.tex。基本上,您创建一个文件 x.bib 包含
引用书目,然后在该文件上运行 bibtex。"""
d2 = """在这种情况下,您必须同时提供\left 和\right,因为
定界符的高度与
两个命令。但是,\left 不一定是实际的 'left
分隔符',也就是说,如果有某种原因,你可以使用'\left)'
去做。"""

sum(ps) = 1 但 sum(pt) 在以下情况下远小于 1:

This should be the case.

代码中是否有不正确的地方?谢谢!

更新:

为了使 pt 和 ps 的和都为 1,我不得不将代码更改为:

    vocab = Counter(_s)+Counter(_t)
ps=[]
pt = []
for t, v in vocab.iteritems():
if t in _s:
pts = gamma * (_s[t] / ssum)
else:
pts = epsilon

if t in _t:
ptt = gamma * (_t[t] / tsum)
else:
ptt = epsilon

ps.append(pts)
pt.append(ptt)

return ps, pt

最佳答案

sum(ps) 和 sum(pt) 都是 _s 和 _t 的总概率质量在 s 的支持下(“s 的支持”我指的是出现在 _s 中的所有单词,不管 _t 中出现的单词)。这意味着

  1. sum(ps)==1,因为 for 循环对 _s 中的所有单词求和。
  2. sum(pt) <= 1,如果 t 的支持度是 s 的支持度的子集(也就是说,如果 _t 中的所有单词都出现在 _s 中),则相等性成立。此外,如果 _s 和 _t 中的单词之间的重叠很小,则 sum(pt) 可能接近 0。具体来说,如果 _s 和 _t 的交集是空集,则 sum(pt) == epsilon*len(_s)。

所以,我不认为代码有问题。

此外,与问题的标题相反,kldiv() 不计算对称 KL 散度,而是计算 _s 和平滑版本的 _t 之间的 KL 散度。

关于python - 计算两个文档之间的对称 Kullback-Leibler 散度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35482943/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com