Exemplo n.º 1
0
def hsic(
    X: np.ndarray,
    Y: np.ndarray,
    kernel: Callable,
    params_x: Dict[str, float],
    params_y: Dict[str, float],
    bias: bool = False,
) -> float:
    """Normalized HSIC (Tangent Kernel Alignment)

    A normalized variant of HSIC method which divides by
    the HS-Norm of each dataset.

    Parameters
    ----------
    X : jax.numpy.ndarray
        the input value for one dataset

    Y : jax.numpy.ndarray
        the input value for the second dataset

    kernel : Callable
        the kernel function to be used for each of the kernel
        calculations

    params_x : Dict[str, float]
        a dictionary of parameters to be used for calculating the
        kernel function for X

    params_y : Dict[str, float]
        a dictionary of parameters to be used for calculating the
        kernel function for Y

    Returns
    -------
    cka_value : float
        the normalized hsic value.

    Notes
    -----

        This is a metric that is similar to the correlation, [0,1]
    """
    # kernel matrix
    Kx = covariance_matrix(kernel, params_x, X, X)
    Ky = covariance_matrix(kernel, params_y, Y, Y)

    Kx = centering(Kx)
    Ky = centering(Ky)

    hsic_value = np.sum(Kx * Ky)
    if bias:
        bias = 1 / (Kx.shape[0] ** 2)
    else:
        bias = 1 / (Kx.shape[0] - 1) ** 2
    return bias * hsic_value
Exemplo n.º 2
0
def mmd_mi(
    X: np.ndarray,
    Y: np.ndarray,
    kernel: Callable,
    params_x: Dict[str, float],
    params_y: Dict[str, float],
) -> float:
    """Maximum Mean Discrepancy

    Parameters
    ----------
    X : jax.numpy.ndarray
        array-like of shape (n_samples, n_features)
    Y : np.ndarray
        The data matrix.

    Notes
    -----

        This method is equivalent to the HSIC method.
    """
    # calculate kernel matrices
    Kx = gram(kernel, params_x, X, X)
    Ky = gram(kernel, params_y, Y, Y)

    # center kernel matrices
    Kx = centering(Kx)
    Ky = centering(Ky)

    # get the expectrations
    A = np.mean(Kx * Ky)
    B = np.mean(np.mean(Kx, axis=0) * np.mean(Ky, axis=0))
    C = np.mean(Kx) * np.mean(Ky)

    # calculate the mmd value
    mmd_value = A - 2 * B + C

    return mmd_value
Exemplo n.º 3
0
def test_centering():

    n_samples = 100

    X = onp.random.rand(n_samples)

    # sklearn rbf_kernel
    K_sk = rbf_sklearn(X[:, np.newaxis], X[:, np.newaxis], gamma=1.0)

    K_sk = KernelCenterer().fit_transform(K_sk)

    K = gram(rbf_kernel, {"gamma": 1.0}, X, X)
    # H = np.eye(n_samples) - (1.0 / n_samples) * np.ones((n_samples, n_samples))
    # K = np.einsum("ij,jk,kl->il", H, K, H)
    # K = np.dot(H, np.dot(K, H))
    K = centering(K)

    onp.testing.assert_array_almost_equal(K_sk, onp.array(K))
Exemplo n.º 4
0
def nhsic_cka(
    X: np.ndarray,
    Y: np.ndarray,
    kernel: Callable,
    params_x: Dict[str, float],
    params_y: Dict[str, float],
) -> float:
    """Normalized HSIC (Tangent Kernel Alignment)

    A normalized variant of HSIC method which divides by
    the HS-Norm of each dataset.

    Parameters
    ----------
    X : jax.numpy.ndarray
        the input value for one dataset

    Y : jax.numpy.ndarray
        the input value for the second dataset

    kernel : Callable
        the kernel function to be used for each of the kernel
        calculations

    params_x : Dict[str, float]
        a dictionary of parameters to be used for calculating the
        kernel function for X

    params_y : Dict[str, float]
        a dictionary of parameters to be used for calculating the
        kernel function for Y

    Returns
    -------
    cka_value : float
        the normalized hsic value.

    Notes
    -----

        This is a metric that is similar to the correlation, [0,1]

    References
    ----------
    """
    # calculate hsic normally (numerator)
    # Pxy = hsic(X, Y, kernel, params_x, params_y)

    # # calculate denominator (normalize)
    # Px = np.sqrt(hsic(X, X, kernel, params_x, params_x))
    # Py = np.sqrt(hsic(Y, Y, kernel, params_y, params_y))

    # # print(Pxy, Px, Py)

    # # kernel tangent alignment value (normalized hsic)
    # cka_value = Pxy / (Px * Py)
    Kx = covariance_matrix(kernel, params_x, X, X)
    Ky = covariance_matrix(kernel, params_y, Y, Y)

    Kx = centering(Kx)
    Ky = centering(Ky)

    cka_value = np.sum(Kx * Ky) / np.linalg.norm(Kx) / np.linalg.norm(Ky)

    return cka_value
Exemplo n.º 5
0
def nhsic_cca(
    X: np.ndarray,
    Y: np.ndarray,
    kernel: Callable,
    params_x: Dict[str, float],
    params_y: Dict[str, float],
    epsilon: float = 1e-5,
    bias: bool = False,
) -> float:
    """Normalized HSIC (Tangent Kernel Alignment)

    A normalized variant of HSIC method which divides by
    the HS-Norm of each dataset.

    Parameters
    ----------
    X : jax.numpy.ndarray
        the input value for one dataset

    Y : jax.numpy.ndarray
        the input value for the second dataset

    kernel : Callable
        the kernel function to be used for each of the kernel
        calculations

    params_x : Dict[str, float]
        a dictionary of parameters to be used for calculating the
        kernel function for X

    params_y : Dict[str, float]
        a dictionary of parameters to be used for calculating the
        kernel function for Y

    Returns
    -------
    cka_value : float
        the normalized hsic value.

    Notes
    -----

        This is a metric that is similar to the correlation, [0,1]
    """
    n_samples = X.shape[0]

    # kernel matrix
    Kx = gram(kernel, params_x, X, X)
    Ky = gram(kernel, params_y, Y, Y)

    # center kernel matrices
    Kx = centering(Kx)
    Ky = centering(Ky)

    K_id = np.eye(Kx.shape[0])
    Kx_inv = np.linalg.inv(Kx + epsilon * n_samples * K_id)
    Ky_inv = np.linalg.inv(Ky + epsilon * n_samples * K_id)

    Rx = np.dot(Kx, Kx_inv)
    Ry = np.dot(Ky, Ky_inv)

    hsic_value = np.sum(Rx * Ry)

    if bias:
        bias = 1 / (Kx.shape[0] ** 2)
    else:
        bias = 1 / (Kx.shape[0] - 1) ** 2
    return bias * hsic_value
Exemplo n.º 6
0
def nhsic_nbs(
    X: np.ndarray,
    Y: np.ndarray,
    kernel: Callable,
    params_x: Dict[str, float],
    params_y: Dict[str, float],
) -> float:
    """Normalized Bures Similarity (NBS)

    A normalized variant of HSIC method which divides by
    the HS-Norm of the eigenvalues of each dataset.

    ..math::
        \\rho(K_x, K_y) = \\
        \\text{Tr} ( K_x^{1/2} K_y K_x^{1/2)})^{1/2} \\
        \ \\text{Tr} (K_x) \\text{Tr} (K_y)

    Parameters
    ----------
    X : jax.numpy.ndarray
        the input value for one dataset

    Y : jax.numpy.ndarray
        the input value for the second dataset

    kernel : Callable
        the kernel function to be used for each of the kernel
        calculations

    params_x : Dict[str, float]
        a dictionary of parameters to be used for calculating the
        kernel function for X

    params_y : Dict[str, float]
        a dictionary of parameters to be used for calculating the
        kernel function for Y

    Returns
    -------
    cka_value : float
        the normalized hsic value.

    Notes
    -----

        This is a metric that is similar to the correlation, [0,1]

    References
    ----------

    @article{JMLR:v18:16-296,
    author  = {Austin J. Brockmeier and Tingting Mu and Sophia Ananiadou and John Y. Goulermas},
    title   = {Quantifying the Informativeness of Similarity Measurements},
    journal = {Journal of Machine Learning Research},
    year    = {2017},
    volume  = {18},
    number  = {76},
    pages   = {1-61},
    url     = {http://jmlr.org/papers/v18/16-296.html}
    }
    """
    # calculate hsic normally (numerator)
    # Pxy = hsic(X, Y, kernel, params_x, params_y)

    # # calculate denominator (normalize)
    # Px = np.sqrt(hsic(X, X, kernel, params_x, params_x))
    # Py = np.sqrt(hsic(Y, Y, kernel, params_y, params_y))

    # # print(Pxy, Px, Py)

    # # kernel tangent alignment value (normalized hsic)
    # cka_value = Pxy / (Px * Py)
    Kx = covariance_matrix(kernel, params_x, X, X)
    Ky = covariance_matrix(kernel, params_y, Y, Y)

    Kx = centering(Kx)
    Ky = centering(Ky)

    # numerator
    numerator = np.real(np.linalg.eigvals(np.dot(Kx, Ky)))

    # clip rogue numbers
    numerator = np.sqrt(np.clip(numerator, 0.0))

    numerator = np.sum(numerator)

    # denominator
    denominator = np.sqrt(np.trace(Kx) * np.trace(Ky))

    # return nbs value
    return numerator / denominator