Ich möchte die Jensen-Shannon-Divergenz für die folgenden 3 Verteilungen berechnen. Ist die unten stehende Berechnung korrekt? (Ich folgte der JSD-Formel aus 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
Danke im Voraus...
BEARBEITEN Hier ist ein einfacher, schmutziger Python-Code, der dies ebenfalls berechnet:
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
quelle
quelle
Antworten:
Es liegt ein Fehler in der Gemischverteilung vor. Es sollte anstelle von ( 1 / 6 , 1 / 5 , 9 / 30 ) , die nicht auf 1 ist es zusammenzufassen , die Entropie (mit natürlichen log) von dem ist 1,084503 . Ihre anderen Entropiebegriffe sind falsch.( 5 / 18 , 28 / 90 , 37 / 90 ) ( 1 / 6 , 1 / 5 , 9 / 30 )
Ich werde das Detail einer Berechnung geben:
In ähnlicher Weise lauten die anderen Begriffe 0,325083 und 1,098612. Das Endergebnis ist also 1,084503 - (0,6931472 + 0,325083 + 1,098612) / 3 = 0,378889
quelle
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)}
. Argumentp
ist eine Matrix, deren Zeilen die Verteilungen und Argumentq
der Vektor der Gewichte sind. Beispielp <- 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)
kehrt (das das Protokoll des approximiert 3 34 / 15 5 1 / 9 2 - 13 / 45 7 - 14 / 45 37 - 37 / 90 ).h <- function(x) {
wurde zweimal eingefügt. Löschen Sie es einfach: alles andere funktioniert und liefert die Ergebnisse, die ich zitiere. Ändern Sie dann dasapply(p, 2, h)
to,apply(p, 1, h)
wie im Kommentar von Legend angegeben .Python:
Java:
quelle
Sie haben eine Wikipedia-Referenz angegeben. Hier gebe ich den vollständigen Ausdruck für die Jensen-Shannon-Divergenz mit mehreren Wahrscheinlichkeitsverteilungen:
Die ursprüngliche Frage wurde ohne mathematischen Ausdruck einer JS-Divergenz mit mehreren Verteilungen gestellt, was zu einer Verwirrung beim Verständnis der bereitgestellten Berechnung führte. Es wurde auch ein Begriff
weight
verwendet, der wiederum zu Verwirrung darüber führt, wie Sie geeignete Gewichtungen für die Multiplikation auswählen. Der obige Ausdruck verdeutlicht diese Verwirrungen. Wie aus dem obigen Ausdruck hervorgeht, werden Gewichte automatisch in Abhängigkeit von der Anzahl der Verteilungen ausgewählt.quelle
Scala-Version der JS-Divergenz zweier Sequenzen beliebiger Länge:
Kreuzen Sie diese Antwort mit dem Code im Abschnitt zum Bearbeiten von Fragen an:
quelle
Eine allgemeine Version für n Wahrscheinlichkeitsverteilungen in Python basierend auf der Wikipedia-Formel und den Kommentaren in diesem Beitrag mit dem Gewichtungsvektor ( pi ) als Parameter und benutzerdefinierter Logbase :
quelle