import numpy as np
from sklearn.datasets import load_iris
from sklearn.preprocessing import KernelCenterer as skKernelCenterer
class KernelCenterer():
def fit(self, K):
n_samples = K.shape[0]
self.K_fit_rows_ = np.sum(K, axis=0) / n_samples
self.K_fit_all_ = self.K_fit_rows_.sum() / n_samples
return self
def transform(self, K):
Kt = (K - (np.sum(K, axis=1) / K.shape[1])[:, np.newaxis]
- self.K_fit_rows_ + self.K_fit_all_)
return Kt
def linear_kernel(X, Y=None):
if Y is None:
Y = X
K = np.dot(X, Y.T)
return K
def rbf_kernel(X, Y=None, gamma=None):
if Y is None:
Y = X
if gamma is None:
gamma = 1 / X.shape[1]
K = np.zeros((X.shape[0], Y.shape[0]))
for i in range(X.shape[0]):
for j in range(Y.shape[0]):
K[i, j] = np.exp(-gamma * np.sum(np.square(X[i] - Y[j])))
return K
# definition
X, _ = load_iris(return_X_y=True)
X_train, X_test = X[:100], X[100:]
X_mean = np.mean(X_train, axis=0)
Xt_train = X_train - X_mean
Xt_test = X_test - X_mean
K_train = linear_kernel(X_train)
K_test = linear_kernel(X_test, X_train)
Kt_train = linear_kernel(Xt_train)
Kt_test = linear_kernel(Xt_test, Xt_train)
trans = KernelCenterer().fit(K_train)
assert np.allclose(trans.transform(K_train), Kt_train)
assert np.allclose(trans.transform(K_test), Kt_test)
# linear kernel
X, _ = load_iris(return_X_y=True)
X_train, X_test = X[:100], X[100:]
K_train = linear_kernel(X_train)
K_test = linear_kernel(X_test, X_train)
trans1 = KernelCenterer().fit(K_train)
trans2 = skKernelCenterer().fit(K_train)
Kt1 = trans1.transform(K_train)
Kt2 = trans2.transform(K_train)
assert np.allclose(Kt1, Kt2)
Kt1 = trans1.transform(K_test)
Kt2 = trans2.transform(K_test)
assert np.allclose(Kt1, Kt2)
# rbf kernel
X, _ = load_iris(return_X_y=True)
X_train, X_test = X[:100], X[100:]
K_train = rbf_kernel(X_train)
K_test = rbf_kernel(X_test, X_train)
trans1 = KernelCenterer().fit(K_train)
trans2 = skKernelCenterer().fit(K_train)
Kt1 = trans1.transform(K_train)
Kt2 = trans2.transform(K_train)
assert np.allclose(Kt1, Kt2)
Kt1 = trans1.transform(K_test)
Kt2 = trans2.transform(K_test)
assert np.allclose(Kt1, Kt2)