上一篇文章咱們介紹了使用邏輯迴歸來處理分類問題,本文咱們講一個更強大的分類模型。本文依舊側重代碼實踐,你會發現咱們解決問題的手段愈來愈豐富,問題處理起來愈來愈簡單。機器學習
支持向量機(Support Vector Machine, SVM)是最受歡迎的機器學習模型之一。它特別適合處理中小型複雜數據集的分類任務。函數
SMV在衆多實例中尋找一個最優的決策邊界,這個邊界上的實例叫作支持向量,它們「支持」(支撐)分離開超平面,因此它叫支持向量機。學習
那麼咱們如何保證咱們獲得的決策邊界是最優的呢?lua
如上圖,三條黑色直線均可以完美分割數據集。由此可知,咱們僅用單一直線能夠獲得無數個解。那麼,其中怎樣的直線是最優的呢?spa
如上圖,咱們計算直線到分割實例的距離,使得咱們的直線與數據集的距離儘量的遠,那麼咱們就能夠獲得惟一的解。最大化上圖虛線之間的距離就是咱們的目標。而上圖中重點圈出的實例就叫作支持向量。code
這就是支持向量機。blog
添加引用:ci
import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt
導入數據集(你們不用在乎這個域名):get
df = pd.read_csv('https://blog.caiyongji.com/assets/mouse_viral_study.csv') df.head()
Med_1_mL | Med_2_mL | Virus Present | |
---|---|---|---|
0 | 6.50823 | 8.58253 | 0 |
1 | 4.12612 | 3.07346 | 1 |
2 | 6.42787 | 6.36976 | 0 |
3 | 3.67295 | 4.90522 | 1 |
4 | 1.58032 | 2.44056 | 1 |
該數據集模擬了一項醫學研究,對感染病毒的小白鼠使用不一樣劑量的兩種藥物,觀察兩週後小白鼠是否感染病毒。數學
sns.scatterplot(x='Med_1_mL',y='Med_2_mL',hue='Virus Present',data=df)
咱們用seaborn繪製兩種藥物在不一樣劑量特徵對應感染結果的散點圖。
sns.pairplot(df,hue='Virus Present')
咱們經過pairplot方法繪製特徵兩兩之間的對應關係。
咱們能夠作出大概的判斷,當加大藥物劑量可以使小白鼠避免被感染。
#SVC: Supprt Vector Classifier支持向量分類器 from sklearn.svm import SVC #準備數據 y = df['Virus Present'] X = df.drop('Virus Present',axis=1) #定義模型 model = SVC(kernel='linear', C=1000) #訓練模型 model.fit(X, y) # 繪製圖像 # 定義繪製SVM邊界方法 def plot_svm_boundary(model,X,y): X = X.values y = y.values # Scatter Plot plt.scatter(X[:, 0], X[:, 1], c=y, s=30,cmap='coolwarm') # plot the decision function ax = plt.gca() xlim = ax.get_xlim() ylim = ax.get_ylim() # create grid to evaluate model xx = np.linspace(xlim[0], xlim[1], 30) yy = np.linspace(ylim[0], ylim[1], 30) YY, XX = np.meshgrid(yy, xx) xy = np.vstack([XX.ravel(), YY.ravel()]).T Z = model.decision_function(xy).reshape(XX.shape) # plot decision boundary and margins ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--']) # plot support vectors ax.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1], s=100, linewidth=1, facecolors='none', edgecolors='k') plt.show() plot_svm_boundary(model,X,y)
咱們導入sklearn
下的SVC
(Supprt Vector Classifier)分類器,它是SVM的一種實現。
SVC方法參數C
表明L2正則化參數,正則化的強度與C
的值城反比,即C值越大正則化強度越弱,其必須嚴格爲正。
model = SVC(kernel='linear', C=0.05) model.fit(X, y) plot_svm_boundary(model,X,y)
咱們減小C的值,能夠看到模型擬合數據的程度減弱。
SVC方法的kernel
參數可取值{'linear', 'poly', 'rbf', 'sigmoid', 'precomputed'}
。像前文中所使用的那樣,咱們能夠使kernel='linear'
進行線性分類。那麼若是咱們像進行非線性分類呢?
多項式內核kernel='poly'
的原理簡單來講就是,用單一特徵生成多特徵來擬合曲線。好比咱們拓展X到y的對應關係以下:
X | X^2 | X^3 | y | |
---|---|---|---|---|
0 | 6.50823 | 6.50823**2 | 6.50823**3 | 0 |
1 | 4.12612 | 4.12612**2 | 4.12612**3 | 1 |
2 | 6.42787 | 6.42787**2 | 6.42787**3 | 0 |
3 | 3.67295 | 3.67295**2 | 3.67295**3 | 1 |
4 | 1.58032 | 1.58032**2 | 1.58032**3 | 1 |
這樣咱們就能夠用曲線來擬合數據集。
model = SVC(kernel='poly', C=0.05,degree=5) model.fit(X, y) plot_svm_boundary(model,X,y)
咱們使用多項式內核,並經過degree=5
設置多項式的最高次數爲5。咱們能夠看出分割出現了必定的弧度。
SVC方法默認內核爲高斯RBF
,即Radial Basis Function(徑向基函數)。這時咱們須要引入gamma
參數來控制鐘形函數的形狀。增長gamma值會使鐘形曲線變得更窄,所以每一個實例影響的範圍變小,決策邊界更不規則。減少gamma值會使鐘形曲線變得更寬,所以每一個實例的影響範圍變大,決策邊界更平坦。
model = SVC(kernel='rbf', C=1,gamma=0.01) model.fit(X, y) plot_svm_boundary(model,X,y)
from sklearn.model_selection import GridSearchCV svm = SVC() param_grid = {'C':[0.01,0.1,1],'kernel':['rbf','poly','linear','sigmoid'],'gamma':[0.01,0.1,1]} grid = GridSearchCV(svm,param_grid) grid.fit(X,y) print("grid.best_params_ = ",grid.best_params_,", grid.best_score_ =" ,grid.best_score_)
咱們能夠經過GridSearchCV
方法來遍歷超參數的各類可能性來尋求最優超參數。這是經過算力碾壓的方式暴力調參的手段。固然,在分析問題階段,咱們必須限定了各參數的可選範圍才能應用此方法。
由於數據集太簡單,咱們在遍歷第一種可能性時就已經獲得100%的準確率了,輸出以下:
grid.best_params_ = {'C': 0.01, 'gamma': 0.01, 'kernel': 'rbf'} , grid.best_score_ = 1.0
當咱們處理線性可分的數據集時,能夠使用SVC(kernel='linear')
方法來訓練數據,固然咱們也能夠使用更快的方法LinearSVC
來訓練數據,特別是當訓練集特別大或特徵很是多的時候。
當咱們處理非線性SVM分類時,能夠使用高斯RBF內核,多項式內核,sigmoid內核來進行非線性模型的的擬合。固然咱們也能夠經過GridSearchCV尋找最優參數。
往期文章: