import numpy as np
from scipy.linalg import inv
from sklearn.datasets import load_boston
from sklearn.kernel_ridge import KernelRidge as skKernelRidge
from sklearn.linear_model import Ridge as skRidge
class KernelRidge():
def __init__(self, alpha=1.0):
self.alpha = alpha
"""
@staticmethod
def _linear_kernel(X, Y):
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.dot(X[i], Y[j])
return K
"""
@staticmethod
def _linear_kernel(X, Y):
K = np.dot(X, Y.T)
return K
def fit(self, X, y):
A = self._linear_kernel(X, X) + np.diag(np.full(X.shape[0], self.alpha))
self.dual_coef_ = np.dot(inv(A), y)
self.X_fit_ = X
return self
def predict(self, X):
K = self._linear_kernel(X, self.X_fit_)
return np.dot(K, self.dual_coef_)
for alpha in [0.1, 1, 10]:
X, y = load_boston(return_X_y = True)
clf1 = KernelRidge(alpha=alpha).fit(X, y)
clf2 = skKernelRidge(alpha=alpha).fit(X, y)
assert np.allclose(clf1.dual_coef_, clf2.dual_coef_, atol=1e-5)
assert np.allclose(clf1.X_fit_, clf2.X_fit_)
pred1 = clf1.predict(X)
pred2 = clf2.predict(X)
assert np.allclose(pred1, pred2)
# KernelRidge kernel='linear' is equivalant to Ridge
X, y = load_boston(return_X_y = True)
X = X - X.mean(axis=0)
y = y - y.mean()
clf1 = skKernelRidge().fit(X, y)
clf2 = skRidge().fit(X, y)
assert np.allclose(np.dot(X.T, clf1.dual_coef_), clf2.coef_)
pred1 = clf1.predict(X)
pred2 = clf2.predict(X)
assert np.allclose(pred1, pred2)
class KernelRidge():
def __init__(self, alpha=1.0, gamma=None):
self.alpha = alpha
self.gamma = gamma
@staticmethod
def _rbf_kernel(X, Y, gamma):
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
def fit(self, X, y):
A = self._rbf_kernel(X, X, self.gamma) + np.diag(np.full(X.shape[0], self.alpha))
self.dual_coef_ = np.dot(inv(A), y)
self.X_fit_ = X
return self
def predict(self, X):
K = self._rbf_kernel(X, self.X_fit_, self.gamma)
return np.dot(K, self.dual_coef_)
for gamma in [0.1, 1, 10, None]:
X, y = load_boston(return_X_y = True)
clf1 = KernelRidge(gamma=gamma).fit(X, y)
clf2 = skKernelRidge(kernel='rbf', gamma=gamma).fit(X, y)
assert np.allclose(clf1.dual_coef_, clf2.dual_coef_)
assert np.allclose(clf1.X_fit_, clf2.X_fit_)
pred1 = clf1.predict(X)
pred2 = clf2.predict(X)
assert np.allclose(pred1, pred2)