def jensen_shannnon(prob_distributions, logbase=2): """Generalised version of Jensen-Shannon Divergence Compares two or more probability distributions and returns a distance value. Distance value is bounded as 0<JSD<log2(n) where n is the number of distributions compared. Args: prob_distributions (list): 2 Dimensional list of probability distributions (each row a distribution). logbase (int): The base of the logarithm used to compute the output. Returns: divergence (float): Distance between probability distributions. """ prob_distributions = np.array(prob_distributions) # All equal weights weights = 1 / len(prob_distributions) # Left term: entropy of mixture weight_probs = weights * prob_distributions mixture = weight_probs.sum(axis=0) entropy_of_mixture = H(mixture, base=logbase) # Right term: sum of entropies entropies = np.array([H(P_i, base=logbase) for P_i in prob_distributions]) weight_entropies = weights * entropies sum_of_entropies = weight_entropies.sum() divergence = entropy_of_mixture - sum_of_entropies return divergence
def jsd(prob_distributions, weights, logbase=math.e): k = zip(weights, np.asarray(prob_distributions)) wprobs = np.asarray([x * y for x, y in list(k)]) mixture = wprobs.sum(axis=0) entropy_of_mixture = H(mixture, base=logbase) # right term: sum of entropies entropies = np.array([H(P_i, base=logbase) for P_i in prob_distributions]) wentropies = weights * entropies sum_of_entropies = wentropies.sum() divergence = entropy_of_mixture - sum_of_entropies return (divergence)
def JSD(prob_distributions, weights, logbase=2): # left term: entropy of mixture wprobs = weights * prob_distributions mixture = wprobs.sum(axis=0) entropy_of_mixture = H(mixture, base=logbase) # right term: sum of entropies entropies = np.array([H(P_i, base=logbase) for P_i in prob_distributions]) wentropies = weights * entropies # wentropies = np.dot(weights, entropies) sum_of_entropies = wentropies.sum() divergence = entropy_of_mixture - sum_of_entropies return (divergence)