機器學習——支持向量機(SVM)

前言:參考《機器學習》,對偶問題沒看懂。。。。(我只是一個代碼的搬運工。。。)
機器學習專欄dom

  1. 機器學習——線性迴歸(預測)
  2. 機器學習——邏輯迴歸(分類)
  3. 機器學習——特徵縮放
  4. 機器學習——正則化
  5. 機器學習——支持向量機(SVM)

支持向量機(SVM)

一、基本原理

現給定數據集\(D={((x^{(1)},y^{(i)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)}))},y^{(i)}\in\{-1,1 \}\),咱們如今的目的就是找一個超平面將這兩個類別的樣本點分開。
在樣本空間中,劃分超平面能夠由線性方程表示爲:
\[w^Tx+b=0\]
則樣本點\(x^{(i)}\)到超平面\((w,x)\)的距離爲:
\[r=\frac{|w^Tx^{(i)}+b|}{||w||}\]
其中,\(||w||\)表示範數,這是空間的一個性質,通常指歐式範數。到原點距離的意思,超平面能夠理解爲平面中的直線、空間中的平面的推廣到更高維度,可是做用都是劃分。機器學習

一個超平面\((w,x)\)能夠將它所在的空間分爲兩半, 它的法向量指向的那一半對應的一面是它的正面, 另外一面則是它的反面,假設超平面\((w,x)\)可以將訓練樣本正確分類,即:
\[ \left\{\begin{matrix} w^Tx^{(i)}+b>0,&&y^{(i)}=+1\\ w^Tx^{(i)}+b<0,&&y^{(i)}=-1 \end{matrix}\right. \]
支持向量機要求知足:
\[ \left\{\begin{matrix} w^Tx^{(i)}+b\geqslant+1,&&y^{(i)}=+1\\ w^Tx^{(i)}+b\leqslant -1,&&y^{(i)}=-1 \end{matrix}\right. \]
距離超平面最近的樣本點使上式等號成立,它們被稱爲「支持向量」(support vector),兩個異類支持向量到超平面的距離之和:
\[ \gamma =\frac{2}{||w||} \]
被稱爲「間隔」(margin)
在這裏插入圖片描述
欲使分類效果更好,咱們就要找到具備「最大間隔」的劃分超平面,即:
\[ \mathop{max}\limits_{w,b} \quad \frac{2}{||w||} \\ s.t. \quad y^{(i)}(w^Tx^{(i)}+b)\geqslant1,\quad i=1,2,...,m \]
最大化\(\frac{2}{||w||}\)等價於最小化\(\frac{||w||^2}{2}\),,即:
\[ \mathop{min}\limits_{w,b} \quad \frac{||w||^2}{2} \\ s.t. \quad y^{(i)}(w^Tx^{(i)}+b)\geqslant1,\quad i=1,2,...,m \]
這就是SVM模型,是一個QP問題。(對偶問題之後再看吧,看不懂。)函數

二、軟間隔

在處理現實問題的時候,咱們其實很難找到一個能恰好劃分的超平面,就算找到了,咱們也不能肯定這個結果不是因爲過擬合致使。因此咱們要放寬條件,即容許一些樣本不知足約束條件,咱們稱爲「軟間隔」。
在這裏插入圖片描述
可是,咱們在最大化間隔的時候,應使不知足約束條件的樣本點儘量少,即:
\[ \mathop{min}\limits_{w,b} \quad \frac{||w||^2}{2}+C\sum_{i=1}^{m}l_{0/1}(y^{(i)}(w^Tx^{(i)}+b)-1) \]
其中,\(C>0\)取有限值常數,\(l_{0/1}\)是「0/1」損失函數
\[ l_{0/1}(z)=\left\{\begin{matrix} 1,&& if\quad z<0\\ 0.&& otherwise \end{matrix}\right. \]
可是,\(l_{0/1}\)非凸、非連續,數學性質很差,經常使用「替代損失」(surrogate loss)函數代替:學習

  1. hinge損失:\(l_{hinge}(z)=max(0,1-z)\)
  2. 指數損失(exponential loss):\(l_{exp}(z)=exp(-z)\)
  3. 對率損失(logistic loss):\(l_{log}(z)=log(1+exp(-z))\)

若採用hinge損失,則模型表示爲:
\[ \mathop{min}\limits_{w,b} \quad \frac{||w||^2}{2}+C\sum_{i=1}^{m}max(0,1-y^{(i)}(w^Tx^{(i)}+b)) \]
引入「鬆弛變量\(\xi_i\geqslant0\),可得「軟間隔支持向量機」,可是要求在這個軟間隔區域的樣本點儘量少,即:
\[ \mathop{min}\limits_{w,b} \quad \frac{||w||^2}{2}+C\sum_{i=1}^{m}\xi_i \\ s.t. \quad y^{(i)}(w^Tx^{(i)}+b)\geqslant1-\xi_i,\quad i=1,2,...,m \]spa

三、核函數

前面說的是線性可分的狀況,那要是出現線性不可分怎麼辦?好比:
在這裏插入圖片描述
對於這樣的問題,咱們須要將樣本從原始空間映射到一個更高維的特徵空間,使得樣本在這個特徵空間線性可分。好比:如今有樣本點以下,很明顯咱們用\(x^2\)二次項去擬合更好,這其實就是一個維度提高,核函數就是實現這樣的做用的。
在這裏插入圖片描述
\(\phi(x)\)表示將\(x\)映射後的特徵向量,因而在新的特徵空間的超平面表示爲:
\[ f(x)=w^T\phi(x)+b \]
此時,SVM模型表示爲:
\[ \mathop{min}\limits_{w,b} \quad \frac{||w||^2}{2} \\ s.t. \quad y^{(i)}(w^T\phi(x)+b)\geqslant1,\quad i=1,2,...,m \]
(這裏等我之後再慢慢弄懂).net

四、sklearn實現SVM

# -*- coding:utf-8 -*-
"""
@author: 1
@file: SVM.py
@time: 2019/11/25 23:58
"""

from sklearn import svm
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

df = pd.read_csv(r'D:\workspace\python\machine learning\data\breast_cancer.csv',header=None)
X = df.iloc[:, 1:10]      # 屬性
y = df.iloc[:, 30]       # 分類結果
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
clf = svm.SVC(gamma='scale')
'''SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
 decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',
 max_iter=-1, probability=False, random_state=None, shrinking=True,
 tol=0.001, verbose=False)'''
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print('accuracy_score:', accuracy_score(y_test, y_pred))

五、SVM多分類

4.1多分類原理

一、一對多法(one-versus-rest,簡稱1-v-r SVMs)。訓練時依次把某個類別的樣本歸爲一類,其餘剩餘的樣本歸爲另外一類,這樣k個類別的樣本就構造出了k個SVM。分類時將未知樣本分類爲具備最大分類函數值的那類。(這個與邏輯迴歸的多分類原理相同設計

二、一對一法(one-versus-one,簡稱1-v-1 SVMs)。其作法是在任意兩類樣本之間設計一個SVM,所以k個類別的樣本就須要設計k(k-1)/2個SVM。當對一個未知樣本進行分類時,最後得票最多的類別即爲該未知樣本的類別。Libsvm中的多類分類就是根據這個方法實現的。3d

三、層次支持向量機(H-SVMs)。層次分類法首先將全部類別分紅兩個子類,再將子類進一步劃分紅兩個次級子類,如此循環,直到獲得一個單獨的類別爲止。rest

4.2sklearn實現SVM多分類

# -*- coding:utf-8 -*-
"""
@author: 1
@file: SVM_mc.py
@time: 2019/11/26 20:34
"""


from sklearn import svm
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

df = pd.read_csv(r'D:\workspace\python\machine learning\data\iris.csv')
X = df.iloc[:, 0:3]
Y = df.iloc[:, 4]
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2)
clf = svm.SVC(gamma='scale', decision_function_shape='ovr')    # 一對多法
# clf = svm.SVC(gamma='scale', decision_function_shape='ovo')  一對一法
clf.fit(x_train, y_train)
'''LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
 intercept_scaling=1, loss='squared_hinge', max_iter=1000,
 multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
 verbose=0)'''
y_pred = clf.predict(x_test)
print('accuracy_score:', accuracy_score(y_test, y_pred))
相關文章
相關標籤/搜索