我正在实施论文中概述的在线主题建模 - 使用主题模型进行在线趋势分析:#twitter趋势检测主题模型在线 我需要在更新之前和之后找到每个主题t的单词分布之间的Jensen-Shannon散度度量,并且如果度量超过阈值则将主题分类为新颖的。 在每次更新时,词汇表都会更新,因此词汇表中的词汇分布在每次更新后都会有不同的长度。如何计算两个不等长度分布之间的JS差异?
答案 0 :(得分:1)
在继续之前,您需要很好地了解KL分歧。这是一个很好的起点:
给出两个概率分布,即P和Q.
P=(p1....pi), Q=(q1....qi)
KL(P||Q)= sum([pi * log(pi/qi) for i in P if i in Q])
KL不是对称的,因此它不是指标。为了使KL对称,Jensen和Shannon提出了Jensen-Shannon散度,这是两个参数交换时KL分歧的平均值,即
JSd(P||Q)= (KL(P,Z) + KL(Q,Z))/2
where Z=(P + Q)/2
简单来说,Jensen-Shannon散度是两个概率分布之间平均KL偏差的平均值。
我希望这会有所帮助。
答案 1 :(得分:0)
使用random.choice样本数据使p和q的分布长度相同
def jsd(p, q, base=np.e):
'''
Implementation of pairwise `jsd` based on
https://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence
'''
if len(p)>len(q):
p = np.random.choice(p,len(q)) # random.choice make same length to p/q
elif len(q)>len(p):
q = np.random.choice(q,len(p))
## convert to np.array
p, q = np.asarray(p), np.asarray(q)
## normalize p, q to probabilities
p, q = p/p.sum(), q/q.sum()
m = 1./2*(p + q)
return scipy.stats.entropy(p,m, base=base)/2. + scipy.stats.entropy(q, m, base=base)/2.