Je voudrais calculer la divergence jensen-shannon pour il suivant 3 distributions. Le calcul ci-dessous est-il correct? (J'ai suivi la formule JSD de wikipedia ):
P1 a:1/2 b:1/2 c:0
P2 a:0 b:1/10 c:9/10
P3 a:1/3 b:1/3 c:1/3
All distributions have equal weights, ie 1/3.
JSD(P1, P2, P3) = H[(1/6, 1/6, 0) + (0, 1/30, 9/30) + (1/9,1/9,1/9)] -
[1/3*H[(1/2,1/2,0)] + 1/3*H[(0,1/10,9/10)] + 1/3*H[(1/3,1/3,1/3)]]
JSD(P1, P2, P3) = H[(1/6, 1/5, 9/30)] - [0 + 1/3*0.693 + 0] = 1.098-0.693 = 0.867
Merci d'avance...
EDIT Voici un code Python sale simple qui calcule cela également:
def entropy(prob_dist, base=math.e):
return -sum([p * math.log(p,base) for p in prob_dist if p != 0])
def jsd(prob_dists, base=math.e):
weight = 1/len(prob_dists) #all same weight
js_left = [0,0,0]
js_right = 0
for pd in prob_dists:
js_left[0] += pd[0]*weight
js_left[1] += pd[1]*weight
js_left[2] += pd[2]*weight
js_right += weight*entropy(pd,base)
return entropy(js_left)-js_right
usage: jsd([[1/2,1/2,0],[0,1/10,9/10],[1/3,1/3,1/3]])
distance-functions
information-theory
kanzen_master
la source
la source
Réponses:
Il y a une erreur dans la distribution du mélange. Il devrait être au lieu de qui ne se résume pas à 1. L'entropie (avec logarithme naturel) de celle-ci est 1.084503 . Vos autres termes d'entropie sont incorrects.( une / six , une / cinq , 9 / 30 )( Cinq / 18 , 28 / 90 , 37 / 90 ) ( 1 / 6 , 1 / cinq , 9 / 30 )
Je vais donner le détail d'un calcul:
De la même manière, les autres termes sont 0,325083 et 1,098612. Le résultat final est donc 1,084503 - (0,6931472 + 0,325083 + 1,098612) / 3 = 0,378889
la source
h <- function(x) {h <- function(x) {y <- x[x > 0]; -sum(y * log(y))}; jsd <- function(p,q) {h(q %*% p) - q %*% apply(p, 2, h)}
. L'argumentp
est une matrice dont les lignes sont les distributions et l'argumentq
est le vecteur des poids. Par exemple,p <- matrix(c(1/2,1/2,0, 0,1/10,9/10, 1/3,1/3,1/3), ncol=3, byrow=TRUE); q <- c(1/3,1/3,1/3); jsd(p,q)
renvoie (qui correspond approximativement au journal de ). 3 34 / 15 5 1 / neuf 2 - treize / 45 sept - quatorze / 45 37 - 37 / 90h <- function(x) {
été collée deux fois. Supprimez-le simplement: tout le reste fonctionne et produit les résultats que je cite. Modifiez ensuite leapply(p, 2, h)
toapply(p, 1, h)
comme indiqué dans le commentaire de Legend .Python:
Java:
la source
Vous avez donné une référence à Wikipedia. Ici, je donne l'expression complète de la divergence de Jensen-Shannon avec plusieurs distributions de probabilité:
La question d'origine a été publiée sans expression mathématique de divergence JS multi-distribution, ce qui a conduit à une confusion dans la compréhension du calcul fourni. En outre, le terme a
weight
été utilisé, ce qui crée à nouveau une confusion sur la façon dont vous sélectionnez les poids appropriés pour la multiplication. L'expression ci-dessus clarifie ces confusions. Comme le montre clairement l'expression ci-dessus, les poids sont automatiquement choisis en fonction du nombre de distribution.la source
Version Scala de la divergence JS de deux séquences de longueur arbitraire:
Vérifiez cette réponse avec le code dans la section d'édition des questions:
la source
Une version générale, pour n distributions de probabilités, en python basée sur la formule Wikipédia et les commentaires dans cet article avec un vecteur de poids ( pi ) comme paramètre et une base de données personnalisée :
la source