21

誰かが私を助けてくれることを望んでいた別の質問があります。

Jensen-Shannon-Divergence を使用して、2 つの確率分布間の類似性を測定しています。2 を底とする対数を使用すると、類似性スコアは 1 から 0 の間にあるという意味で正しいように見えます。0 は分布が等しいことを意味します。

ただ、どこかに間違いがあるのか​​どうかは定かではなく、「はい、そうです」「いいえ、あなたは何か間違ったことをしました」と言える人がいるのだろうかと考えていました。

コードは次のとおりです。

from numpy import zeros, array
from math import sqrt, log


class JSD(object):
    def __init__(self):
        self.log2 = log(2)


    def KL_divergence(self, p, q):
        """ Compute KL divergence of two vectors, K(p || q)."""
        return sum(p[x] * log((p[x]) / (q[x])) for x in range(len(p)) if p[x] != 0.0 or p[x] != 0)

    def Jensen_Shannon_divergence(self, p, q):
        """ Returns the Jensen-Shannon divergence. """
        self.JSD = 0.0
        weight = 0.5
        average = zeros(len(p)) #Average
        for x in range(len(p)):
            average[x] = weight * p[x] + (1 - weight) * q[x]
            self.JSD = (weight * self.KL_divergence(array(p), average)) + ((1 - weight) * self.KL_divergence(array(q), average))
        return 1-(self.JSD/sqrt(2 * self.log2))

if __name__ == '__main__':
    J = JSD()
    p = [1.0/10, 9.0/10, 0]
    q = [0, 1.0/10, 9.0/10]
    print J.Jensen_Shannon_divergence(p, q)

問題は、たとえば 2 つのテキスト ドキュメントを比較する場合、スコアが十分に高くないと感じることです。ただし、これは純粋に主観的な感覚です。

いつものように、どんな助けでも大歓迎です。

4

5 に答える 5

24

以下の scipy エントロピー呼び出しは、カルバック ライブラー ダイバージェンスであることに注意してください。

参照: http://en.wikipedia.org/wiki/Jensen%E2%80%93Shannon_divergence

#!/usr/bin/env python
from scipy.stats import entropy
from numpy.linalg import norm
import numpy as np

def JSD(P, Q):
    _P = P / norm(P, ord=1)
    _Q = Q / norm(Q, ord=1)
    _M = 0.5 * (_P + _Q)
    return 0.5 * (entropy(_P, _M) + entropy(_Q, _M))

また、質問のテストケースが間違っているように見えることに注意してください?? p 分布の合計は 1.0 になりません。

参照: http://www.itl.nist.gov/div898/handbook/eda/section3/eda361.htm

于 2014-12-11T21:29:31.343 に答える