核函數(shù)的作用
某些數(shù)據(jù)在原始空間無(wú)法線性可分,可以將其映射到高維空間處理昆著。
提問(wèn):如何映射省容?何種高維空間?
假設(shè):映射為Φ匀油,映射后的空間為Φ(x)
問(wèn)題:要跟不知道我們要什么樣的Φ
在高維空間中劃分超平面主要涉及 樣本xi 和 樣本xj 之間的內(nèi)積運(yùn)算<Φ(xi),Φ(xj)>(這里具體參見(jiàn)西瓜書(shū)P126)
核函數(shù)的作用就是:k(xi,xj) = <Φ(xi),Φ(xj)>, 使得在低維空間操作xi,xj上完成高維Φ(xi),Φ(xj)想要完成的運(yùn)算缘缚。
結(jié)合上圖《hands on machine learning with scikit-learn and tensorflow》中的描述,做出個(gè)人理解:
核函數(shù)首先在samples上找1個(gè)landmark敌蚜,然后計(jì)算其他所有數(shù)據(jù)同這個(gè)landmark的核函數(shù)距離桥滨,之后將這個(gè)距離作為一個(gè)特征使用。
如要生成更多的特征弛车,那么就找更多的landmark齐媒,最多可以找到m個(gè)(m = the num of samples)
核函數(shù)是一種距離公式,它可以用來(lái)生成特征纷跛。
核函數(shù)的公式
這里只例舉高斯核函數(shù)喻括,我看過(guò)兩種表達(dá)方式,分別為高斯核贫奠、高斯徑向基函數(shù)如下:
核函數(shù)的代碼
'''
np.linalg.norm(): 默認(rèn)參數(shù)下求二范數(shù)拷恨,雙豎運(yùn)算符∥...∥ 表示Norm運(yùn)算,即取向量的‘度量’
np.subtract(a,b):a-b
---
高斯核函數(shù):k(||x-xc||)=exp{- ||x-xc||^2 / (2*σ^2) }
xc為核函數(shù)中心
σ為函數(shù)的寬度參數(shù)
---
高斯核函數(shù)圖像類似于一張紙中間隆起一塊谢肾,σ越小則越尖
'''
def calc_gaussian(x, center, width):
return np.exp(-(np.square(np.linalg.norm(np.subtract(x, center))))/(2*np.square(width)))
for i in range(1,M):
phi[:,i] = calc_gaussian(x,landmark[i],1) # 設(shè)置了m個(gè)landmark
核函數(shù)邏輯回歸
y = wx+b 無(wú)法完成分類腕侄,對(duì)x進(jìn)行變化,x' = k(x,l) ==> y = wx'+b 可以對(duì)x'劃分
已知x',y可以求出w,b
對(duì)new_x,進(jìn)行變化new_x'兜挨,帶入y = wx'+b膏孟,即可進(jìn)行預(yù)測(cè)
為了提高預(yù)測(cè)準(zhǔn)確性,往往會(huì)設(shè)置多個(gè)landmark求多個(gè)x'得到多個(gè)模型y = wx'+b
"""
===================================================================
Support Vector Regression (SVR) and Least Squares with Guassion Kernal
===================================================================
Source: https://github.com/JinScientist/Gaussion-Kernal-Least-Squares-Regression/
"""
print(__doc__)
import numpy as np
from sklearn.svm import SVR
import matplotlib.pyplot as plt
M=20 # number of kernal function
lamda=1 #regularization coefficient
############# Linear Combination of Gaussion(LGK) kernal
def LGK(M,x,y,lamda):
N=len(x)
mu=np.linspace(0, 6, M)
phi=np.zeros(shape=[N,M])
for i in range(1,M):
phi[:,i]=np.exp(-np.square(x-mu[i-1])/2).reshape(40,)
phiinv=np.linalg.pinv(phi)
w=phiinv.dot(y)
phiT=np.transpose(phi)
wr=np.linalg.inv(lamda*np.identity(M)+phiT.dot(phi)).dot(phiT).dot(y)
print('Dimension of Moore-Penrose pseudo-inverse:')
print(phiinv.shape)
print('Dimension of y:')
print(y.shape)
return(w,wr)#wr:regularized w
###########predict from trained LGK
def LGKpredict(M,w,x):
N=len(x)
phi=np.zeros(shape=[N,M])
mu=np.linspace(0, 6, M)
for i in range(1,M):
phi[:,i]=np.exp(-np.square(x-mu[i-1])/2).reshape(40,)
ypredict=phi.dot(w.reshape(M,1))
return(ypredict)
# Generate sample data
X = np.sort(5 * np.random.rand(40, 1), axis=0)
y = np.sin(X).ravel()
###############################################################################
# Add noise to targets
y[::5] += 3 * (0.5 - np.random.rand(8))
###############################################################################
# Fit regression model
(w,wr)=LGK(M,X,y,lamda)
y_LGK=LGKpredict(M,w,X)
y_LGK_r=LGKpredict(M,wr,X)
np.savetxt("w.csv", w, delimiter=",")
print('Dimension of W_ML:')
print(w.shape)
svr_rbf = SVR(kernel='rbf', C=1e3, gamma=0.1)
svr_lin = SVR(kernel='linear', C=1e3)
svr_poly = SVR(kernel='poly', C=1e3, degree=2)
y_rbf = svr_rbf.fit(X, y).predict(X)
y_lin = svr_lin.fit(X, y).predict(X)
y_poly = svr_poly.fit(X, y).predict(X)
###############################################################################
# look at the results
lw = 1
plt.scatter(X, y, color='darkorange', label='data')
plt.hold('on')
plt.plot(X, y_rbf, color='navy', lw=lw, label='RBF model')
plt.plot(X, y_lin, color='c', lw=lw, label='Linear model')
plt.plot(X, y_poly, color='cornflowerblue', lw=lw, label='Polynomial model')
plt.plot(X, y_LGK, color='maroon', lw=lw, label='Gausian kernal \n Least square model')
plt.plot(X, y_LGK_r, color='lime', lw=lw, label='Regularized Gausian kernal \n Least square model')
plt.xlabel('data')
plt.ylabel('target')
plt.title('Gausian Kernal Least Square and Support Vector Regression')
lgd=plt.legend(bbox_to_anchor=(1.05, 1), loc=2)
plt.savefig('SVR.png',bbox_extra_artists=(lgd,), bbox_inches='tight')