两个不等长的离散概率分布之间的JS差异

时间:2013-11-30 16:28:16

标签: stat

我正在实施论文中概述的在线主题建模 - 使用主题模型进行在线趋势分析:#twitter趋势检测主题模型在线 我需要在更新之前和之后找到每个主题t的单词分布之间的Jensen-Shannon散度度量,并且如果度量超过阈值则将主题分类为新颖的。 在每次更新时,词汇表都会更新,因此词汇表中的词汇分布在每次更新后都会有不同的长度。如何计算两个不等长度分布之间的JS差异?

2 个答案:

答案 0 :(得分:1)

Jensen-Shannon散度是两个概率分布的相对熵,它是Kullback-Leibler(KL)散度的对称形式。当您与发散相比较的两个论点被交换时,它是KL分歧的平均值。

在继续之前,您需要很好地了解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.