一、核函數(Kernel Function)
1)格式
K(x, y):表示樣本 x 和 y,添加多項式特征得到新的樣本 x'、y',K(x, y) 就是傳回新的樣本經過計算得到的值;
在 SVM 類型的算法 SVC() 中,K(x, y) 傳回點乘:x' . y' 得到的值;
2)多項式核函數
業務問題:怎麼分類非線性可分的樣本的分類?
内部實作:
對傳入的樣本資料點添加多項式項;
新的樣本資料點進行點乘,傳回點乘結果;
多項式特征的基本原理:依靠升維使得原本線性不可分的資料線性可分;
升維的意義:使得原本線性不可分的資料線性可分;
例:
一維特征的樣本,兩種類型,分布如圖,線性不可分:
為樣本添加一個特征:x2 ,使得樣本在二維平面内分布,此時樣本在 x 軸升的分布位置不變;如圖,可以線性可分:
3)優點 / 特點
不需要每次都具體計算出原始樣本點映射的新的無窮次元的樣本點,直接使用映射後的新的樣本點的點乘計算公式即可;
減少計算量
減少存儲空間
一般将原始樣本變形,通常是将低維的樣本資料變為高維資料,存儲高維資料花費較多的存儲空間;使用核函數,不用考慮原來樣本改變後的樣子,也不用存儲變化後的結果,隻需要直接使用變化的結果進行運算并傳回運算結果即可;
核函數的方法和思路不是 SVM 算法特有,隻要可以減少計算量和存儲空間,都可以設計核函數友善運算;
對于比較傳統的常用的機器學習算法,核函數這種技巧更多的在 SVM 算法中使用;
4)SVM 中的核函數
svm 類中的 SVC() 算法中包含兩種核函數:
SVC(kernel = 'ploy'):表示算法使用多項式核函數;
SVC(kernel = 'rbf'):表示算法使用高斯核函數;
SVM 算法的本質就是求解目标函數的最優化問題;
求解最優化問題時,将數學模型變形:
5)多項式核函數
格式:
from sklearn.svm importSVC
svc= SVC(kernel = 'ploy')
思路:設計一個函數( K(xi, xj) ),傳入原始樣本(x(i) 、 x(j)),傳回添加了多項式特征後的新樣本的計算結果(x'(i) . x'(j));
内部過程:先對 xi 、xj 添加多項式,得到:x'(i) 、 x'(j),再進行運算:x'(i) . x'(j) ;
x(i) 添加多項式特征後:x'(i) ;
x(j) 添加多項式特征後:x'(j) ;
x(i) .x(j)轉化為:x'(i) .x'(j) ;
其實不使用核函數也能達到同樣的目的,這裡核函數相當于一個技巧,更友善運算;
二、高斯核函數(RBF)
業務問題:怎麼分類非線性可分的樣本的分類?
1)思想
業務的目的是樣本分類,采用的方法:按一定規律統一改變樣本的特征資料得到新的樣本,新的樣本按新的特征資料能更好的分類,由于新的樣本的特征資料與原始樣本的特征資料呈一定規律的對應關系,是以根據新的樣本的分布及分類情況,得出原始樣本的分類情況。
應該是試驗回報,将樣本的特征資料按一定規律統一改變後,同類樣本更好的凝聚在了一起;
高斯核和多項式核幹的事情截然不同的,如果對于樣本數量少,特征多的資料集,高斯核相當于對樣本降維;
高斯核的任務:找到更有利分類任務的新的空間。
方法:類似
的映射。
高斯核本質是在衡量樣本和樣本之間的“相似度”,在一個刻畫“相似度”的空間中,讓同類樣本更好的聚在一起,進而線性可分。
疑問:
“衡量”的手段
,經過這種映射之後,為什麼同類樣本能更好的分布在一起?
2)定義方式
;
x、y:樣本或向量;
γ:超參數;高斯核函數唯一的超參數;
|| x - y ||:表示向量的範數,可以了解為向量的模;
表示兩個向量之間的關系,結果為一個具體值;
高斯核函數的定義公式就是進行點乘的計算公式;
3)功能
先将原始的資料點(x, y)映射為新的樣本(x',y');
再将新的特征向量點乘(x' . y'),傳回其點乘結果;
計算點積的原因:此處隻針對 SVM 中的應用,在其它算法中的應用不一定需要計算點積;
4)特點
高斯核運作開銷耗時較大,訓練時間較長;
一般使用場景:資料集 (m, n),m < n;
一般應用領域:自然語言處理;
自然語言處理:通常會建構非常高維的特征空間,但有時候樣本數量并不多;
5)高斯函數
正态分布就是一個高斯函數;
高斯函數和高斯核函數,形式類似;
6)其它
高斯核函數,也稱為 RBF 核(Radial Basis Function Kernel),也稱為徑向基函數;
高斯核函數的本質:将每一個樣本點映射到一個無窮維的特征空間;
無窮維:将 m*n 的資料集,映射為 m*m 的資料集,m 表示樣本個數,n 表示原始樣本特征種類,樣本個數是無窮的,是以,得到的新的資料集的樣本也是無窮維的;
高斯核升維的本質,使得線性不可分的資料線性可分;
三、RBF 轉化特征資料原理
1)轉化原理
x:需要改變次元的樣本;
np.array([l1, l2, ..., lm])== X == np.array([x1, x2, ... , xm]):Landmark,地标,一般直接選取資料集 X 的所有樣本作為地标;(共 m 個)
對于 (m, n) 的資料集:轉化為 (m, m) 的資料集;将 n 維的樣本轉化為 m 維的樣本;
對于原始資料集中的每一個樣本 x,也可以有幾個地标點,就将 x 轉化為幾維;
2)主要為兩部分
先将原始的資料點映射為一種新的特征向量,再将新的特征向量點乘,傳回其點乘結果;
次元轉化:樣本 x1 轉化x1' :(e-γ||x1 - x1||**2, e-γ||x1 - x2||**2, e-γ||x1 - x3||**2, ..., e-γ||x1 - xm||**2),同理樣本x2 的轉化 x2';(地标點就是資料集 X 的樣本點)
點乘計算:x1' . x2' == K(x1, x2) == e-γ||x1 - x2||**2,最終結果為一個具體值;
3)執行個體模拟次元轉化過程
一維升到二維
原始樣本分布:
第一步:選取地标點:L1、L2 ;
第二步:升維計算
四、程式模拟
目的:将線性不可分的資料變為線性可分;
方法:一維資料升到二維;
1)模拟資料集
x 資料集:每一個樣本隻有一個特征,且分布規律線性不可分;
np.arange(m, n, l):将區間 [m, n) 按間距為 l 等分,等分後的資料點包含 m 值,不包含 n;
[0]*len(x[y==0]):[0] 是一個 list,list * C 表示将清單複制 C 份;
如:[0]*5 == [0, 0, 0, 0, 0]
importnumpy as npimportmatplotlib.pyplot as plt
x= np.arange(-4, 5, 1)
y= np.array((x >= -2) & (x <= 2), dtype='int')
plt.scatter(x[y==0], [0]*len(x[y==0]))
plt.scatter(x[y==1], [0]*len(x[y==1]))
plt.show()
2)經過高斯核,得到新的資料集
np.exp(m):表示 e 的 m 次幂;
np.empty(元組):(元組)=(m, n),生成一個 m 行 n 列的空的矩陣;
enumerate(iterator):傳回可疊代對象的 index 和 value;
for i, data in enumerate(x):i 存放向量 x 的 index,data 存放向量 x 的 index 對應的元素值;
defgaussian(x, l):#此處直接将超參數 γ 設定為 1.0;
#此處 x 表示一維的樣本,也就是一個具體的值,l 相應的也是一個具體的數,因為 l 和 x 一樣,從特征空間中標明;
gamma = 1.0
#此處因為 x 和 l 都隻是一個數,不需要再計算模,可以直接平方;
return np.exp(-gamma * (x-l)**2)#設定地标 l1、l2 為 -1和1
l1, l2 = -1, 1x_new= np.empty((len(x), 2))for i, data inenumerate(x):
x_new[i, 0]=gaussian(data, l1)
x_new[i,1] =gaussian(data, l2)
plt.scatter(x_new[y==0, 0], x_new[y==0, 1])
plt.scatter(x_new[y==1, 0], x_new[y==1, 1])
plt.show()