基於jupyter notebook的python編程-----支持向量機學習二(SVM處理線性[鳶尾花數據集]和非線性數據集[月亮數據集])


前面我們通過學習了支持向量機(Support Vector Machine)算法的基礎學習,並對比了其他兩種算法:LDA和K-means算法的線性可視化,主要目的就是通過對比學習支持向量機,並沒有深入瞭解支持向量機的算法原理,本次博客,林君學長主要帶大家瞭解支持向量機的深度學習,數據來源同樣爲鳶尾花數據集和月亮數據集,一起來看吧!

一、SVM處理線性數據集(鳶尾花數據集)

1、導入需要的python庫

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
  • numpy:用於計算
  • matplotlib.pyplot:用於作圖
  • sklearn:包括鳶尾花和月亮數據集
  • StandardScaler:標準化,計算數據集的均值和方差
  • sklearn.svm:構建SVM算法和決策邊界

2、選取鳶尾花的數據集的兩個特徵,用於分類構建SVM算法

1)、選取鳶尾花的兩個特徵:長寬

iris = datasets.load_iris()

X = iris.data
y = iris.target

X = X [y<2,:2] #只取y<2的類別,也就是0 1 並且只取前兩個特徵
y = y[y<2] # 只取y<2的類別

# 分別畫出類別0和1的點
plt.scatter(X[y==0,0],X[y==0,1],color='red') 
plt.scatter(X[y==1,0],X[y==1,1],color='blue')
plt.show()

2)、可視化的運行結果顯示
在這裏插入圖片描述

3、標準化、構建SVM分類(實例化SVC)及訓練SVM

1)、標準化後構建分類器及訓練SVM數據,傳入C值爲10的9次方

# 標準化
standardScaler = StandardScaler()
standardScaler.fit(X) #計算訓練數據的均值和方差
X_standard = standardScaler.transform(X) #再用scaler中的均值和方差來轉換X,使X標準化
svc = LinearSVC(C=1e9) #線性SVM分類器
svc.fit(X_standard,y) # 訓練svm

2)、訓練結果展示
在這裏插入圖片描述

4、定義繪製決策邊界函數

def plot_decision_boundary(model, axis):
    x0, x1 = np.meshgrid(
        np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1),
        np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1)
    )
    X_new = np.c_[x0.ravel(), x1.ravel()]
    
    y_predict = model.predict(X_new)
    zz = y_predict.reshape(x0.shape)
    
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])    
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

5、繪製決策邊界

1)、調用函數,繪製鳶尾花數據集兩個特徵的決策邊界

# 繪製決策邊界
plot_decision_boundary(svc,axis=[-3,3,-3,3]) # x,y軸都在-3到3之間
# 繪製原始數據
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='red') 
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='blue')
plt.show()

2)、決策邊界繪製結果展示:
在這裏插入圖片描述

6、實例化SVC,並傳入參數C值

1)、再次實例化SVC,傳遞參數C值爲0.05

svc2 = LinearSVC(C=0.05)
svc2.fit(X_standard,y)

2)、調用決策邊界函數進行鳶尾花數據集的繪製

plot_decision_boundary(svc2,axis=[-3,3,-3,3]) # x,y軸都在-3到3之間
# 繪製原始數據
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='red') 
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='blue')
plt.show()

3)、C值爲0.05時候的決策邊界繪製結果
在這裏插入圖片描述
4)、更改C值爲一個較大的值,例如100000,再次繪製進行對比

svc2 = LinearSVC(C=100000)
svc2.fit(X_standard,y)
plot_decision_boundary(svc2,axis=[-3,3,-3,3]) # x,y軸都在-3到3之間
# 繪製原始數據
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='red') 
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='blue')
plt.show()

在這裏插入圖片描述
可以很明顯的看到和第一個決策邊界的不同,在第一個決策邊界彙總,有一個紅點是分類錯誤的,這意味着:C值越小容錯空間越大,越容易出現錯誤。我們可以通過svc.coef_ 函數來獲取學習到的權重係數,svc.intercept_ 函數獲取偏差

二、SVM處理非線性數據集(月亮數據集)

1、導入需要的python庫

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import PolynomialFeatures,StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
  • numpy:用於計算
  • matplotlib.pyplot:用於作圖
  • sklearn:包括月亮數據集
  • PolynomialFeatures,StandardScaler:生成多項式和標準化
  • LinearSVC:構建決策邊界
  • sklearn.pipeline:管道:可以將許多算法模型串聯起來,比如將特徵提取、歸一化、分類組織在一起形成一個典型的機器學習問題工作流
  • SVC:用於核處理(核技巧來對數據進行處理)

2、構建月亮的特徵數據並可視化

1)、構建月亮數據集的兩個特徵數據並可視化

X, y = datasets.make_moons() #使用生成的數據
#print(X.shape) # (100,2)
#print(y.shape) # (100,)
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

2)、可視化運行結果
在這裏插入圖片描述

3、生成噪聲點並可視化

1)、生成噪聲點並可視化

X, y = datasets.make_moons(noise=0.15,random_state=777) #隨機生成噪聲點,random_state是隨機種子,noise是方差
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

2)、可視化運行結果展示
在這裏插入圖片描述

4、定義非線性SVM分類函數

def PolynomialSVC(degree,C=1.0):
    return Pipeline([
        ("poly",PolynomialFeatures(degree=degree)),#生成多項式
        ("std_scaler",StandardScaler()),#標準化
        ("linearSVC",LinearSVC(C=C))#最後生成svm
    ])

5、調用PolynomialSVC函數進行分類可視化

1)、調用非線性SVM分類,實例化SVC,傳遞參數爲5並可視化

poly_svc = PolynomialSVC(degree=5)
poly_svc.fit(X,y)
plot_decision_boundary(poly_svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

2)、可視化運行結果
在這裏插入圖片描述
我們可以看到,生成的邊界不再是線性的直線了,因爲月亮數據集提取的兩個特徵並不是線性的,所以決策邊界自然不會是線性!

6、核處理(核技巧來對數據進行處理)

使用核技巧來對數據進行處理,使其維度提升,使原本線性不可分的數據,在高維空間變成線性可分的。再用線性SVM來進行處理。
1)、定義核處理函數

def PolynomialKernelSVC(degree,C=1.0):
    return Pipeline([
        ("std_scaler",StandardScaler()),
        ("kernelSVC",SVC(kernel="poly")) # poly代表多項式特徵
    ])

2)、調用核處理函數並實例化非線性SVC後可視化

poly_kernel_svc = PolynomialKernelSVC(degree=5)
poly_kernel_svc.fit(X,y)
plot_decision_boundary(poly_kernel_svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

3)、可視化運行結果展示
在這裏插入圖片描述
可以看到這種方式也生成了一個非線性的邊界,但與上面有巨大的不同,這個在慢慢餓趨於近似線性.
這裏SVC(kernel=“poly”)有個參數是kernel,就是核函數,下面林君學長將帶大家瞭解核函數,一起來看吧!

三、核函數

核函數的重要作用就是通過升維來進行線性迴歸的模擬,對於核函數的具體瞭解,小夥伴可以通過如下鏈接進行深入學習,本次博客林君學長主要通過python代碼進行相應的核函數理解,鏈接如下:https://baike.baidu.com/item/%E6%A0%B8%E5%87%BD%E6%95%B0/4693132?fr=aladdin

1、隨機生成數據並可視化

1)、隨機數據構建

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]))# x取y=0的點, y取0,有多少個x,就有多少個y
plt.scatter(x[y==1],[0]*len(x[y==1]))
plt.show()

2)、可視化運行結果
在這裏插入圖片描述

2、利用高斯核函數,進行數據的升維(一維升二維)

1)、高斯核函數定義

def gaussian(x,l):
    gamma = 1.0
    return np.exp(-gamma * (x -l)**2)

2)、數據升維,調用高斯核函數

l1,l2 = -1,1
X_new = np.empty((len(x),2)) #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()

3)、升維可視化運行結果展示
在這裏插入圖片描述
對於這樣的二維數據顯然是線性可分的,在藍色和黃色的點中插入直線切割分類就好:
在這裏插入圖片描述
瞭解了核函數的原理,接下來我們通過核函數來進行非線性數據集月亮數據集的分類處理吧:

四、核函數處理月亮數據集

1、導入需要的python庫

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline

2、導入月亮數據集並可視化

1)、導入月亮數據集並可視化(選取兩個特徵)

X,y = datasets.make_moons(noise=0.15,random_state=777)
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

2)、可視化運行結果展示
在這裏插入圖片描述

3、定義RBF核的SVM分類函數

我們設置函數的默認參數γ=1.0\gamma=1.0,該值自己可以設定,後面我們做對比分析

def RBFKernelSVC(gamma=1.0):
    return Pipeline([
        ('std_scaler',StandardScaler()),
        ('svc',SVC(kernel='rbf',gamma=gamma))
    ])

4、實例化SVC並傳遞γ\gamma參數

1)、傳遞γ\gamma值爲200並可視化

svc = RBFKernelSVC(200)
svc.fit(X,y)
plot_decision_boundary(svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

2)、可視化運行結果
在這裏插入圖片描述
3)、傳遞γ\gamma值爲20並可視化

svc = RBFKernelSVC(20)
svc.fit(X,y)
plot_decision_boundary(svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在這裏插入圖片描述
從上面我們可以知道,γ\gamma取值越大,就是高斯分佈的鐘形圖越窄,這裏相當於每個樣本點都形成了鐘形圖。很明顯這樣是過擬合的
4)、傳遞γ\gamma值爲0.2並可視化

svc = RBFKernelSVC(0.2)
svc.fit(X,y)
plot_decision_boundary(svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在這裏插入圖片描述
此時它是欠擬合的。因此,我們可以看出γ\gamma值相當於在調整模型的複雜度。
以上就是本次博客的全部內容啦,希望通過對本次博客的閱讀,可以幫助小夥伴深入瞭解支持向量機,同時,通過python代碼學習SVM如何進行線性數據集和非線性數據集的分類,通過代碼瞭解原理,是程序員的必備技能啦!
遇到問題的小夥伴記得留言評論哦,林君學長看到會爲大家進行解答的,這個學長不太冷

陳一月的又一天編程歲月^ _ ^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章