Source code for metrics

import numpy as np
import scipy as sp
import math

def hyperbolic_transform(distance):
    
    try:
        hyperbolic_distance = math.log( (1 + distance)/(1 - distance) )
    except ValueError:
        print(distance)
        print(1 + distance)/(1 - distance)
        raise ValueError
    
    return hyperbolic_distance
    

[docs]def hellinger(x,y): """Computes the Hellinger distance between two sum-normalized vectors :math:`d_h(x,y) = \\frac{1}{2} \sqrt{\sum_{i} \\left(\sqrt{x_i} - \sqrt{y_i}\\right)^2}` Equivalently, for sum-normalized vectors :math:`d_h(x,y) = 1 - \sum_{i} \\left(\sqrt{x_i} - \sqrt{y_i}\\right)` :param x: The first vector :param y: The second vector :type x: ndarray :type y: ndarray :returns: ``hellinger(x,y) = np.sqrt( 1 - np.dot(np.sqrt(x),np.sqrt(y)) )`` """ #hellinger_distance = sp.spatial.distance.euclidean(np.sqrt(x),np.sqrt(y)) squared_hellinger_distance = 1 - np.dot(np.sqrt(x),np.sqrt(y)) hellinger_distance = np.sqrt(squared_hellinger_distance) return hellinger_distance
[docs]def hellinger_hyp(x,y): """Computes the hyperbolic Hellinger distance metric between two vectors .. math:: d_{hy} = \log \\left(\\frac{1 + d_h}{1 - d_h}\\right) :param x: The first vector :param y: The second vector :type x: ndarray :type y: ndarray :returns: ``hellinger_hyp(x,y) = math.log( (1+hellinger(x,y))/(1 - hellinger(x,y)) )`` """ hellinger_distance = hellinger(x,y) try: hellinger_hyperbolic_distance = hyperbolic_transform(hellinger_distance) except: print(hellinger_distance) return hellinger_hyperbolic_distance
[docs]def jeffries(x,y): """Computes the Jeffries divergence between two vectors .. math:: d_{SKL}(x,y) = \\frac{1}{2} \\left( \sum_{i} \\left( x_i - y_i \\right) \log \\frac{x_i}{y_i} \\right) :param x: The first vector :param y: The second vector :type x: ndarray :type y: ndarray :returns: ``jeffries(x,y) = (1/2) * ( entropy(x,y) + entropy(y,x) )`` """ entropy_xy = sp.stats.entropy(x,y) entropy_yx = sp.stats.entropy(y,x) jeffries_entropy = (entropy_xy+entropy_yx)/2.0 return jeffries_entropy
[docs]def jensen(x,y): """Computes the Jensen-Shannon metric between two vectors .. math:: d^2_j = \sum_{i} \\left( x_i \log_2 \\frac{2x_i}{x_i + y_i} + y_i \log_2 \\frac{2y_i}{x_i + y_i} \\right) :param x: The first vector :param y: The second vector :type x: ndarray :type y: ndarray :returns: ``jensen(x,y) = entropy(x,m) + entropy(y,m)`` where ``m = (1/2) * (x + y)`` """ mean = (x+y)/2.0 entropy_xm = sp.stats.entropy(x,mean) entropy_ym = sp.stats.entropy(y,mean) jensen_entropy = (entropy_xm + entropy_ym)/(2.0 * math.log(2)) #Log 2 is to go from nats to bits return jensen_entropy
def jensen_distance(x,y): """Computes the Jensen-Shannon distance between two vectors .. math:: d_j = \sum_{i} \\left( x_i \log \\frac{2x_i}{x_i + y_i} + y_i \log \\frac{2y_i}{x_i + y_i} \\right) :param x: The first vector :param y: The second vector :type x: ndarray :type y: ndarray :returns: ``jensen_distance(x,y) = sqrt(entropy(x,m) + entropy(y,m))`` where ``m = (1/2) * (x + y)`` """ jensen_entropy = jensen(x,y) jensen_distance = np.sqrt(jensen_entropy) return jensen_distance
[docs]def jensen_hyp(x,y): """Computes the hyperbolic Jensen-Shannon metric between two vectors .. math:: d_{hy} = \log \\left(\\frac{1 + d_j}{1 - d_j}\\right) :param x: The first vector :param y: The second vector :type x: ndarray :type y: ndarray :returns: ``jensen_hyp(x,y) = math.log( (1+jensen_distance(x,y))/(1 - jensen_distance(x,y)) )`` """ jensen_entropy = jensen(x,y) jensen_distance = np.sqrt(jensen_entropy) jensen_hyperbolic_distance = hyperbolic_transform(jensen_distance) return jensen_hyperbolic_distance