2012-11-13 23 views
5
function [ d ] = hcompare_KL(h1,h2) 
%This routine evaluates the Kullback-Leibler (KL) distance between histograms. 
%    Input:  h1, h2 - histograms 
%    Output: d – the distance between the histograms. 
%    Method: KL is defined as: 
%    Note, KL is not symmetric, so compute both sides. 
%    Take care not to divide by zero or log zero: disregard entries of the sum  for which with H2(i) == 0. 

temp = sum(h1 .* log(h1 ./ h2)); 
temp(isinf(temp)) = 0; % this resloves where h1(i) == 0 
d1 = sum(temp); 

temp = sum(h2 .* log(h2 ./ h1)); % other direction of compare since it's not symetric 
temp(isinf(temp)) = 0; 
d2 = sum(temp); 

d = d1 + d2; 

end 

il mio problema è che ogni volta che h1 (i) o h2 (i) == 0 sto ottenendo inf che è come previsto. tuttavia nella distanza KL suppongo di restituire 0 ogni volta che h1 o h2 == 0 come posso farlo senza usare un ciclo?Kullback-Leibler (KL) distanza tra istogrammi - matlab

+1

E 'davvero difficile per aiutarti se non chiedere di meglio domande. Non riesco a trovare il tuo errore neanche se non so cosa dovrebbe fare il programma in primo luogo. Si prega di suggerire un esempio di input, dicci quale output ti aspetti e cosa va storto. La funzione genera un errore? La funzione non restituisce ciò che vuoi? Ho sviato la tua domanda, anche se sono felice di rivedere il mio voto se la domanda migliora. – Jonas

+0

ciao @ Jonas grazie per le risposte quotidiane come puoi vedere sto imparando mentre andiamo. lasciatemi specificare la mia domanda più tardi, mi dispiace e grazie – Gilad

+0

@jonas ho modificato la mia domanda, per favore, guardatela, supponiamo di avere h1 = [0: 9] e h2 = [1:10] come input otterrò un errore quando ho 0 come input .. log (0) – Gilad

risposta

3

per evitare di avere problemi quando uno dei conti è 0, io suggerisco di creare un indice che segna i "buoni" punti di dati:

%# you may want to do some input testing, such as whether h1 and h2 are 
%# of the same size 

%# preassign the output 
d = zeros(size(h1)); 

%# create an index of the "good" data points 
goodIdx = h1>0 & h2>0; %# bin counts <0 are not good, either 

d1 = sum(h1(goodIdx) .* log(h1(goodIdx) . /h2(goodIdx))); 
d2 = sum(h2(goodIdx) .* log(h2(goodIdx) . /h1(goodIdx))); 

%# overwrite d only where we have actual data 
%# the rest remains zero 
d(goodIdx) = d1 + d2; 
+0

sì esattamente quello che ho fatto ho usato h1 (find (h1 == 0)) = 1, grazie – Gilad

2

vedo qualche torto nell'implementazione. Si prega di Registro modifiche da log2

1

tenta di utilizzare

d=sum(h1.*log2(h1+eps)-h1.*log2(h2+eps)) 

noti che KL (h1, h2) è diverso con KL (H2, H1). Nel tuo caso è KL (h1, h2), giusto? Penso che la tua implementazione sia sbagliata. Non è la distanza tra h1 e h2. La distanza tra i KL H1 e H2 è definito

KL(h1,h2)=sum(h1.log(h1/h2))=sum(h1.logh1-h2.logh2). 

Quindi la corretta attuazione deve essere

d=sum(h1.*log2(h1+eps)-h1.*log2(h2+eps)) %KL(h1,h2) 

o

d=sum(h2.*log2(h2+eps)-h2.*log2(h1+eps)) %KL(h2,h1)