機器學習“傻瓜式”理解(14)SVM(1)

SVM(Support Vector Machine):支撐向量機(重點)

基本介紹
在我們進行機器學習的過程中,會不可避免的出現“不適定問題”,所謂的不適定問題便是值得我們在進行決策的時候,決策邊界不唯一,可能會偏向某一樣本類型,模型的泛化能力差,其原因可能是模型由訓練數據集所得,訓練數據集中沒有包含所有類型的所有樣本,訓練數據集中的樣本的分佈,可能並不能準確的反應不同樣本之間的分佈規律,並且通過訓練數據集所得到的決策邊界也不是真正的決策邊界,例如,邏輯迴歸中,
決策邊界可能會呈現下面的這種狀態:
在這裏插入圖片描述
針對上面提到的問題,SVM應運而生,SVM的目的便是找到一個最優的決策邊界,不僅可以正確的劃分數據集而且還具有很好的模型泛化能力。
在這裏插入圖片描述
其實現的主要的方法是找到一條決策邊界使得其距離兩部分的數據儘可能的遠。
值得注意的是,SVM在考慮模型的泛化能力的時候並不是寄希望在數據的預處理上,而是通過對算法內部進行相應的改造。

實現的具體方法
根據SVM的中文名字,我們可以知道,SVM是由支撐向量和margin組成的。
在這裏插入圖片描述

SVM的目標便是最大化的margin。
另外不論是邏輯迴歸還是SVM討論的前提都是樣本線性可分。
Hard Margin SVM解決的是兩部分數據線性可分,而Soft Margin SVM解決的是線性不可分(實際中這種情況十分多)。
Soft Margin SVM 算法是從 Hard Margin SVM 的基礎上改進的。
目標函數推導
在這裏插入圖片描述
重要思想:所謂的正則化,是一個概念,但是並不是對所有模型添加同樣的L1正則或者L2正則,有時候我們需要進行靈活的調整,但是其最終的目的是相同的,都是爲了提高模型的泛化能力。

使用SVM

'''
    注意:我們在進行試驗的過程中,不論數據是線性可分還是不可分的,我們都需要進行數據的標準化處理,因爲如果數據的
    量綱差距過大,會導致決策邊界是一條直線的現象。
'''
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler

from sklearn.svm import LinearSVC
from myML.metrics import plot_decision_boundary

'''模擬數據集'''
iris = datasets.load_iris()
X = iris.data
y = iris.target


X = X[y<2,:2]
y = y[y<2]


'''使用SVM算法進行試驗'''
standardScaler = StandardScaler()
standardScaler.fit(X)
X_std = standardScaler.transform(X)

svc = LinearSVC(C=10**9)
svc.fit(X_std,y)

# hard margin
'''查看決策邊界'''
plot_decision_boundary(svc,axis=[-3,3,-3,3])
'''散點圖分佈'''
plt.scatter(X_std[y==0,0],X_std[y==0,1],color='red')
plt.scatter(X_std[y==1,0],X_std[y==1,1],color='blue')
plt.show()


#soft margin
svc2 = LinearSVC(C = 0.01)
'''查看決策邊界'''
plot_decision_boundary(svc,axis=[-3,3,-3,3])
'''散點圖分佈'''
plt.scatter(X_std[y==0,0],X_std[y==0,1],color='red')
plt.scatter(X_std[y==1,0],X_std[y==1,1],color='blue')
plt.show()


'''繪製支撐向量所在直線'''


def plot_svc_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)

    w = model.coef_[0]
    b = model.intercept_[0]

    plot_x = np.linspace(axis[0], axis[1], 200)
    up_y = -w[0] / w[1] * plot_x - b / w[1] + 1 / w[1]
    down_y = -w[0] / w[1] * plot_x - b / w[1] - 1 / w[1]

    up_index = (up_y >= axis[2]) & (up_y <= axis[3])
    down_index = (down_y >= axis[2]) & (down_y <= axis[3])
    plt.plot(plot_x[up_index], up_y[up_index], color='black')
    plt.plot(plot_x[down_index], down_y[down_index], color='black')


# hard margin
'''查看決策邊界'''
plot_svc_decision_boundary(svc,axis=[-3,3,-3,3])
'''散點圖分佈'''
plt.scatter(X_std[y==0,0],X_std[y==0,1],color='red')
plt.scatter(X_std[y==1,0],X_std[y==1,1],color='blue')
plt.show()


#soft margin
svc2 = LinearSVC(C = 0.01)
'''查看決策邊界'''
plot_svc_decision_boundary(svc,axis=[-3,3,-3,3])
'''散點圖分佈'''
plt.scatter(X_std[y==0,0],X_std[y==0,1],color='red')
plt.scatter(X_std[y==1,0],X_std[y==1,1],color='blue')
plt.show()

四張圖形依次的運行結果爲:
在這裏插入圖片描述

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