Расчет исправленного расхождения Дженсена-Шеннона Чао-Шэня
Я пытаюсь рассчитать JS-дивергенцию двух распределений P и R с коррекцией Чао-Шена (https://link.springer.com/article/10.1023/a:1026096204727). P и R — это простые массивы, где каждый элемент представляет количество определенных микросостояний. Их длина одинаковая. P может содержать множество нулевых интервалов (отсюда и использование поправки Чао-Шэня). Вот мой код:
def js_cs(P,R):
M = (P+R)/2
js = 0.5 * kl_cs(P, M) + 0.5 * kl_cs(R, M)
return js
def kl_cs(P, R):
# Convert to float
P = P.astype(float)
R = R.astype(float)
yx = P[P > 0] # remove bins with zero counts
n = np.sum(yx)
p = yx / n
f1 = np.sum(yx == 1) # number of singletons in the sample
if f1 == n: # avoid C == 0
f1 -= 1
C = 1 - (f1 / n) # estimated coverage of the sample
pa = C * p # coverage adjusted empirical frequencies
la = (1 - (1 - pa) ** n) # probability to see a bin (species) in the sample
H = -np.sum((pa * np.log(pa)) / la)
# Make sure no zero values in R for log computation
R /= np.sum(R)
# Only consider entries where P > 0
R = R[P > 0]
# Compute corrected KL-divergence
cross_entropy = -np.sum((pa * np.log(R)) / la)
return (cross_entropy - H)/np.log(2)
Я вижу, что значения div JS отрицательны, что странно. Насколько я знаю, этого не должно произойти. Что может быть причиной? Правильно ли я рассчитываю дивергенцию JS?
Следует отметить одну вещь: отрицательные значения не очень велики, они очень близки к 0, но тем не менее отрицательны.