Source code for polylearn.kernels

# Author: Vlad Niculae <vlad@vene.ro>
# License: Simplified BSD

from sklearn.metrics.pairwise import polynomial_kernel
from sklearn.utils.extmath import safe_sparse_dot
from scipy.sparse import issparse

import numpy as np


[docs]def safe_power(X, degree=2): """Element-wise power supporting both sparse and dense data. Parameters ---------- X : ndarray or sparse The array whose entries to raise to the power. degree : int, default: 2 The power to which to raise the elements. Returns ------- X_ret : ndarray or sparse Same shape as X, but (x_ret)_ij = (x)_ij ^ degree """ if issparse(X): if hasattr(X, 'power'): return X.power(degree) else: # old scipy X = X.copy() X.data **= degree return X else: return X ** degree
def _D(X, P, degree=2): """The "replacement" part of the homogeneous polynomial kernel. D[i, j] = sum_k [(X_ik * P_jk) ** degree] """ return safe_sparse_dot(safe_power(X, degree), P.T ** degree)
[docs]def homogeneous_kernel(X, P, degree=2): """Convenience alias for homogeneous polynomial kernel between X and P:: K_P(x, p) = <x, p> ^ degree Parameters ---------- X : ndarray of shape (n_samples_1, n_features) Y : ndarray of shape (n_samples_2, n_features) degree : int, default 2 Returns ------- Gram matrix : array of shape (n_samples_1, n_samples_2) """ return polynomial_kernel(X, P, degree=degree, gamma=1, coef0=0)
[docs]def anova_kernel(X, P, degree=2): """ANOVA kernel between X and P:: K_A(x, p) = sum_i1>i2>...>id x_i1 p_i1 x_i2 p_i2 ... x_id p_id See John Shawe-Taylor and Nello Cristianini, Kernel Methods for Pattern Analysis section 9.2. Parameters ---------- X : ndarray of shape (n_samples_1, n_features) Y : ndarray of shape (n_samples_2, n_features) degree : int, default 2 Returns ------- Gram matrix : array of shape (n_samples_1, n_samples_2) """ if degree == 2: K = homogeneous_kernel(X, P, degree=2) K -= _D(X, P, degree=2) K /= 2 elif degree == 3: K = homogeneous_kernel(X, P, degree=3) K -= 3 * _D(X, P, degree=2) * _D(X, P, degree=1) K += 2 * _D(X, P, degree=3) K /= 6 else: raise NotImplementedError("ANOVA kernel for degree >= 4 not yet " "implemented efficiently.") return K
def _poly_predict(X, P, lams, kernel, degree=2): if kernel == "anova": K = anova_kernel(X, P, degree) elif kernel == "poly": K = homogeneous_kernel(X, P, degree) else: raise ValueError(("Unsuppported kernel: {}. Use one " "of {{'anova'|'poly'}}").format(kernel)) return np.dot(K, lams)