9. Method of kernels

import numpy as np
from scipy.spatial import distance
from sklearn.datasets import make_regression
from sklearn.metrics import mean_absolute_error,mean_squared_error
X,y = make_regression(n_samples=100,
    n_features=2,
    n_informative=2,
)
def kernel(x,z):
    return x.T @ z

def transform_X(X):
    def phi(x):
        return np.array([x[0]**2,np.sqrt(2)*x[0]*x[1],x[1]**2])
    
    n = X.shape[0]
    D = np.zeros(shape=(n,3))
    for i in range(n):
        D[i] = phi(X[i])
    return D

def compute_inner_product_matrix(X):
    n = X.shape[0]
    Inner = np.zeros(shape=(n,n))
    for i in range(n):
        for j in range(n):
            Inner[i,j] = np.dot(X[i,:],X[j,:])
    return Inner

def compute_k_vector(x):
    k_vec = np.zeros(shape=(X.shape[0],1))
    for i in range(X.shape[0]):
        k_vec[i] = kernel(D[i],x)
    return k_vec

def compute_prediction(D,K,I,λ,y):
    pred = np.zeros(shape=(X.shape[0],1))
    for i in range(D.shape[0]):
        k = compute_k_vector(D[i])
        pred[i] = (k.T @ np.linalg.inv(K + λ*I)) @ y
    return pred
\[y(x) = k(x)^{T}(K + \lambda I_{N})^{-1}t\]
from sklearn.linear_model import LinearRegression

lr = LinearRegression()
lr.fit(X,y)
lr_pred = lr.predict(X)

random_pred = np.random.uniform(y.min(),y.max(),size=X.shape[0])
print(mean_squared_error(y,lr_pred),mean_absolute_error(y,lr_pred))
print(mean_squared_error(y,random_pred),mean_absolute_error(y,random_pred))
8.296923456752514e-28 2.1564972030319042e-14
27412.036219363403 135.89770144320772

9.1. Kernel linear

def transform_X(X):
    def phi(x):
        return x
    n = X.shape[0]
    D = np.zeros(shape=(n,2))
    for i in range(n):
        D[i] = phi(X[i])
    return D

D = transform_X(X)
K = compute_inner_product_matrix(D)
I = np.eye(N=X.shape[0])
λ = 1

pred = compute_prediction(D,K,I,λ,y)

print(mean_squared_error(y,pred),mean_absolute_error(y,pred))
print(mean_squared_error(y,random_pred),mean_absolute_error(y,random_pred))
1.1661110964802706 0.8596882108136374
27412.036219363403 135.89770144320772

9.2. Kernel polinomial de grau 2

def transform_X(X):
    def phi(x):
        return np.array([x[0]**2,np.sqrt(2)*x[0]*x[1],x[1]**2])
    
    n = X.shape[0]
    D = np.zeros(shape=(n,3))
    for i in range(n):
        D[i] = phi(X[i])
    return D

D = transform_X(X)
K = compute_inner_product_matrix(D)
I = np.eye(N=X.shape[0])
λ = 1

pred = compute_prediction(D,K,I,λ,y)
print(mean_squared_error(y,pred),mean_absolute_error(y,pred))
print(mean_squared_error(y,random_pred),mean_absolute_error(y,random_pred))
7481.93414419529 66.19456243858396
27412.036219363403 135.89770144320772

9.3. Kernel exponencial do kernel linear

def transform_X(X):
    def phi(x):
        return x
    n = X.shape[0]
    D = np.zeros(shape=(n,2))
    for i in range(n):
        D[i] = phi(X[i])
    return D

def compute_k_vector(x):
    k_vec = np.zeros(shape=(X.shape[0],1))
    for i in range(X.shape[0]):
        k_vec[i] = np.exp(kernel(D[i],x))
    return k_vec

D = transform_X(X)
K = compute_inner_product_matrix(D)
I = np.eye(N=X.shape[0])
λ = 1

pred = compute_prediction(D,K,I,λ,y)

print(mean_squared_error(y,pred),mean_absolute_error(y,pred))
print(mean_squared_error(y,random_pred),mean_absolute_error(y,random_pred))
4307616.037771 351.46191685860873
27412.036219363403 135.89770144320772

9.4. Kernel customizado 1 - distância euclidiana

def transform_X(X):
    def phi(x):
        return x
    n = X.shape[0]
    D = np.zeros(shape=(n,2))
    for i in range(n):
        D[i] = phi(X[i])
    return D

def kernel(x,z):
    return distance.euclidean(x,z)

def compute_k_vector(x):
    k_vec = np.zeros(shape=(X.shape[0],1))
    for i in range(X.shape[0]):
        k_vec[i] = kernel(D[i],x)
    return k_vec

D = transform_X(X)
K = compute_inner_product_matrix(D)
I = np.eye(N=X.shape[0])
λ = 1

pred = compute_prediction(D,K,I,λ,y)

print(mean_squared_error(y,pred),mean_absolute_error(y,pred))
print(mean_squared_error(y,random_pred),mean_absolute_error(y,random_pred))
18602.7080658687 112.41003282458912
27412.036219363403 135.89770144320772

9.5. Kernel gaussiano

def transform_X(X):
    def phi(x):
        return x
    n = X.shape[0]
    D = np.zeros(shape=(n,2))
    for i in range(n):
        D[i] = phi(X[i])
    return D

def kernel(x,z):
    return np.exp(-(np.linalg.norm(x-z,2))/2*1.0**2)

def compute_k_vector(x):
    k_vec = np.zeros(shape=(X.shape[0],1))
    for i in range(X.shape[0]):
        k_vec[i] = kernel(D[i],x)
    return k_vec

D = transform_X(X)
K = compute_inner_product_matrix(D)
I = np.eye(N=X.shape[0])
λ = 1

pred = compute_prediction(D,K,I,λ,y)

print(mean_squared_error(y,pred),mean_absolute_error(y,pred))
print(mean_squared_error(y,random_pred),mean_absolute_error(y,random_pred))
6709.227697241312 64.29307176293953
27412.036219363403 135.89770144320772