Gostaria de calcular a divergência de Jensen-Shannon para ele após três distribuições. O cálculo abaixo está correto? (Eu segui a fórmula JSD da 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
Desde já, obrigado...
EDIT Aqui está um código Python simples e sujo que calcula isso também:
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
fonte
fonte
Respostas:
Vou dar os detalhes de uma computação:
De maneira semelhante, os outros termos são 0,325083 e 1,098612. Portanto, o resultado final é 1.084503 - (0.6931472 + 0.325083 + 1.098612) / 3 = 0.378889
fonte
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)}
. Argumentop
é uma matriz cujas linhas são as distribuições e o argumentoq
é o vetor de pesos. Por exemplo,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)
h <- function(x) {
foi colada duas vezes. Basta excluí-lo: tudo o resto funciona e produz os resultados que cito. Em seguida, modifique oapply(p, 2, h)
paraapply(p, 1, h)
como indicado no comentário da legenda .Pitão:
Java:
fonte
Você deu uma referência da Wikipedia. Aqui, dou a expressão completa da divergência de Jensen-Shannon com múltiplas distribuições de probabilidade:
A pergunta original foi publicada sem expressão matemática da divergência JS de multi-distribuição, o que levou a uma confusão no entendimento da computação fornecida. Além disso,
weight
foi utilizado o termo que novamente causa confusão quanto à maneira como você seleciona pesos apropriados para multiplicação. A expressão acima esclarece essas confusões. Como claramente acima da expressão, os pesos são escolhidos automaticamente, dependendo do número de distribuição.fonte
Versão Scala da divergência JS de duas seqüências arbitrárias de comprimento:
Verifique esta resposta com o código na seção de edição de perguntas:
fonte
Uma versão geral, para n distribuições de probabilidade, em python com base na fórmula da Wikipedia e comentários neste post com vetor de pesos ( pi ) como parâmetro e base de log personalizada :
fonte