機器學習:SVM(核函數、高斯核函數RBF)


一、核函數(Kernel Function)

 1)格式

  • K(x, y):表示樣本 x 和 y,添加多項式特征得到新的樣本 x'、y',K(x, y) 就是返回新的樣本經過計算得到的值;
  • 在 SVM 類型的算法 SVC() 中,K(x, y) 返回點乘:x' . y' 得到的值;

 

 2)多項式核函數

  • 業務問題:怎么分類非線性可分的樣本的分類?
  • 內部實現:

  1. 對傳入的樣本數據點添加多項式項;
  2. 新的樣本數據點進行點乘,返回點乘結果;
  • 多項式特征的基本原理:依靠升維使得原本線性不可分的數據線性可分;
  • 升維的意義:使得原本線性不可分的數據線性可分;
  • 例:

  1. 一維特征的樣本,兩種類型,分布如圖,線性不可分:
  2. 為樣本添加一個特征:x2 ,使得樣本在二維平面內分布,此時樣本在 x 軸升的分布位置不變;如圖,可以線性可分:

 

 3)優點 / 特點

  •  不需要每次都具體計算出原始樣本點映射的新的無窮維度的樣本點,直接使用映射后的新的樣本點的點乘計算公式即可;
  • 減少計算量
  • 減少存儲空間
  1. 一般將原始樣本變形,通常是將低維的樣本數據變為高維數據,存儲高維數據花費較多的存儲空間;使用核函數,不用考慮原來樣本改變后的樣子,也不用存儲變化后的結果,只需要直接使用變化的結果進行運算並返回運算結果即可;

 

  • 核函數的方法和思路不是 SVM 算法特有,只要可以減少計算量和存儲空間,都可以設計核函數方便運算;
  • 對於比較傳統的常用的機器學習算法,核函數這種技巧更多的在 SVM 算法中使用;

 

 4)SVM 中的核函數

  • svm 類中的 SVC() 算法中包含兩種核函數:
  1. SVC(kernel = 'ploy'):表示算法使用多項式核函數;
  2. SVC(kernel = 'rbf'):表示算法使用高斯核函數;
  • SVM 算法的本質就是求解目標函數的最優化問題;

 

  • 求解最優化問題時,將數學模型變形:

 

 5)多項式核函數

 

  • 格式:
    from sklearn.svm import SVC
    
    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) ;
  1. x(i) 添加多項式特征后:x'(i) ;
  2. x(j) 添加多項式特征后:x'(j)
  3. x(i)x(j) 轉化為:x'(i) . x'(j)
  • 其實不使用核函數也能達到同樣的目的,這里核函數相當於一個技巧,更方便運算;

 

 

二、高斯核函數(RBF)

  • 業務問題:怎么分類非線性可分的樣本的分類?

 1)思想

  • 業務的目的是樣本分類,采用的方法:按一定規律統一改變樣本的特征數據得到新的樣本,新的樣本按新的特征數據能更好的分類,由於新的樣本的特征數據與原始樣本的特征數據呈一定規律的對應關系,因此根據新的樣本的分布及分類情況,得出原始樣本的分類情況。
  1. 應該是試驗反饋,將樣本的特征數據按一定規律統一改變后,同類樣本更好的凝聚在了一起;
  • 高斯核和多項式核干的事情截然不同的,如果對於樣本數量少,特征多的數據集,高斯核相當於對樣本降維;
  • 高斯核的任務:找到更有利分類任務的新的空間。
  • 方法:類似  的映射。

 

  • 高斯核本質是在衡量樣本和樣本之間的“相似度”,在一個刻畫“相似度”的空間中,讓同類樣本更好的聚在一起,進而線性可分。
  • 疑問
  • “衡量”的手段 ,經過這種映射之后,為什么同類樣本能更好的分布在一起?

 

 2)定義方式

  1. x、y:樣本或向量;
  2. γ:超參數;高斯核函數唯一的超參數;
  3. || x - y ||:表示向量的范數,可以理解為向量的模;
  4. 表示兩個向量之間的關系,結果為一個具體值;
  5. 高斯核函數的定義公式就是進行點乘的計算公式;

 

 3)功能

  • 先將原始的數據點(x, y)映射為新的樣本(x',y');
  • 再將新的特征向量點乘(x' . y'),返回其點乘結果;
  • 計算點積的原因此處只針對 SVM 中的應用,在其它算法中的應用不一定需要計算點積;

 

 4)特點

  • 高斯核運行開銷耗時較大,訓練時間較長
  • 一般使用場景:數據集 (m, n),m < n;
  • 一般應用領域:自然語言處理;
  1. 自然語言處理:通常會構建非常高維的特征空間,但有時候樣本數量並不多;

 

 5)高斯函數

  • 正態分布就是一個高斯函數;
  • 高斯函數和高斯核函數,形式類似;

 

 6)其它

  • 高斯核函數,也稱為 RBF 核(Radial Basis Function Kernel),也稱為徑向基函數;
  • 高斯核函數的本質:將每一個樣本點映射到一個無窮維的特征空間;
  1. 無窮維:將 m*n 的數據集,映射為 m*m 的數據集,m 表示樣本個數,n 表示原始樣本特征種類,樣本個數是無窮的,因此,得到的新的數據集的樣本也是無窮維的;
  2. 高斯核升維的本質,使得線性不可分的數據線性可分;

 

三、RBF 轉化特征數據原理

 1)轉化原理

  1. x:需要改變維度的樣本;
  2. np.array([l1, l2, ..., lm]) == X == np.array([x1, x2, ... , xm])Landmark,地標,一般直接選取數據集 X 的所有樣本作為地標;(共 m 個)
  3. 對於 (m, n) 的數據集:轉化為 (m, m)  的數據集;將 n 維的樣本轉化為 m 維的樣本;
  4. 對於原始數據集中的每一個樣本 x,也可以有幾個地標點,就將 x 轉化為幾維;

 

 2)主要為兩部分

  • 先將原始的數據點映射為一種新的特征向量,再將新的特征向量點乘,返回其點乘結果;

 

  1. 維度轉化:樣本 x1 轉化 x1'(e-γ||x1 - x1||**2, e-γ||x1 - x2||**2, e-γ||x1 - x3||**2, ..., e-γ||x1 - xm||**2)同理樣本 x2 的轉化 x2' ;(地標點就是數據集 X 的樣本點)
  2. 點乘計算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]
    import numpy as np
    import matplotlib.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;
  1. for i, data in enumerate(x):i 存放向量 x 的 index,data 存放向量 x 的 index 對應的元素值;
    def gaussian(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, 1
    x_new = np.empty((len(x), 2))
    
    for i, data in enumerate(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()

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM