Source code for secml.ml.kernel.c_kernel_linear

"""
.. module:: CKernelLinear
   :synopsis: Linear kernel

.. moduleauthor:: Battista Biggio <battista.biggio@unica.it>
.. moduleauthor:: Marco Melis <marco.melis@unica.it>

"""
from sklearn import metrics

from secml.array import CArray
from secml.ml.kernel import CKernel


[docs]class CKernelLinear(CKernel): """Linear kernel. Given matrices X and Y, this is computed by:: K(x, y) = x * y^T for each pair of rows in X and in Y. Attributes ---------- class_type : 'linear' Parameters ---------- batch_size : int or None, optional Size of the batch used for kernel computation. Default None. Examples -------- >>> from secml.array import CArray >>> from secml.ml.kernel.c_kernel_linear import CKernelLinear >>> print(CKernelLinear().k(CArray([[1,2],[3,4]]), CArray([[10,20],[30,40]]))) CArray([[ 50. 110.] [110. 250.]]) >>> print(CKernelLinear().k(CArray([[1,2],[3,4]]))) CArray([[ 5. 11.] [11. 25.]]) """ __class_type = 'linear' def _k(self, x, y): """Compute the linear kernel between x and y. Parameters ---------- x : CArray or array_like First array of shape (n_x, n_features). y : CArray or array_like Second array of shape (n_y, n_features). Returns ------- kernel : CArray Kernel between x and y. Array of shape (n_x, n_y). See Also -------- :meth:`CKernel.k` : Main computation interface for kernels. """ return CArray(metrics.pairwise.linear_kernel( CArray(x).get_data(), CArray(y).get_data())) def _gradient(self, u, v): """Calculate Linear kernel gradient wrt vector 'v'. The gradient of Linear kernel is given by:: dK(u,v)/dv = u if u != v = 2 * u if u == v Parameters ---------- u : CArray or array_like First array of shape (1, n_features). v : CArray or array_like Second array of shape (1, n_features). Returns ------- kernel_gradient : CArray Kernel gradient of u with respect to vector v, shape (1, n_features). See Also -------- :meth:`CKernel.gradient` : Gradient computation interface for kernels. Examples -------- >>> from secml.array import CArray >>> from secml.ml.kernel.c_kernel_linear import CKernelLinear >>> array = CArray([[15, 25], [45, 55]]) >>> vector = CArray([2, 5]) >>> print(CKernelLinear().gradient(array, vector)) CArray([[15 25] [45 55]]) >>> print(CKernelLinear().gradient(vector, vector)) CArray([ 4 10]) """ k_grad = CArray(u) v_carray = CArray(v) if k_grad.shape[0] + v_carray.shape[0] > 2: raise ValueError( "Both input arrays must be 2-Dim of shape (1, n_features).") # Format of output array should be the same as v k_grad = k_grad.tosparse() if v_carray.issparse else k_grad.todense() if (k_grad - v_carray).norm() < 1e-8: return 2 * k_grad else: return k_grad.deepcopy()