Tig*_*er1 11 numpy distance python-2.7
我的目标是计算以下文本文档之间的KL距离:
1)The boy is having a lad relationship
2)The boy is having a boy relationship
3)It is a lovely day in NY
Run Code Online (Sandbox Code Playgroud)
我首先将文件矢量化,以便轻松应用numpy
1)[1,1,1,1,1,1,1]
2)[1,2,1,1,1,2,1]
3)[1,1,1,1,1,1,1]
Run Code Online (Sandbox Code Playgroud)
然后,我应用以下代码计算文本之间的KL距离:
import numpy as np
import math
from math import log
v=[[1,1,1,1,1,1,1],[1,2,1,1,1,2,1],[1,1,1,1,1,1,1]]
c=v[0]
def kl(p, q):
p = np.asarray(p, dtype=np.float)
q = np.asarray(q, dtype=np.float)
return np.sum(np.where(p != 0,(p-q) * np.log10(p / q), 0))
for x in v:
KL=kl(x,c)
print KL
Run Code Online (Sandbox Code Playgroud)
以下是上述代码的结果:[0.0, 0.602059991328, 0.0].文本1和3完全不同,但它们之间的距离为0,而高度相关的文本1和2的距离为0 0.602059991328.这不准确.
有没有人知道我对KL的做法不对?非常感谢你的建议.
dpb*_*dpb 30
虽然我不想添加另一个答案,但这里有两点.首先,正如Jaime在评论中指出的那样,KL分歧(或距离 - 根据以下文档,它们是相同的)旨在衡量概率分布之间的差异.这意味着你传递给函数的基本上应该是两个数组,每个元素的总和为1.
其次,scipy显然确实实现了这一点,其命名方案更多地与信息理论领域相关.功能是"熵":
scipy.stats.entropy(pk, qk=None, base=None)
Run Code Online (Sandbox Code Playgroud)
http://docs.scipy.org/doc/scipy-dev/reference/generated/scipy.stats.entropy.html
来自文档:
如果qk不是None,则计算相对熵(也称为Kullback-Leibler散度或Kullback-Leibler距离)S = sum(pk*log(pk/qk),axis = 0).
这个函数的好处是它会将你传递的向量标准化,如果它们不总和为1(虽然这意味着你必须小心你传递的数组 - 即它们是如何从数据构造的).
希望这会有所帮助,至少有一个库提供它,所以不必编写自己的代码.
经过一番谷歌搜索以理解 KL 概念后,我认为您的问题是由于向量化造成的:您正在比较不同单词的出现次数。您应该将列索引链接到一个单词,或者使用字典:
# The boy is having a lad relationship It lovely day in NY
1)[1 1 1 1 1 1 1 0 0 0 0 0]
2)[1 2 1 1 1 0 1 0 0 0 0 0]
3)[0 0 1 0 1 0 0 1 1 1 1 1]
Run Code Online (Sandbox Code Playgroud)
然后你可以使用你的 kl 函数。
要自动矢量化为字典,请参阅如何计算列表中元素的频率?(collections.Counter正是您所需要的)。然后你可以循环字典键的并集来计算 KL 距离。
| 归档时间: |
|
| 查看次数: |
24854 次 |
| 最近记录: |