1.快速了解SVM
2.SVM定義與公式建立
3. 核函數
4.SVM 應用實例
支持向量機(support vector machines,SVM)是一種二類分類模型。它的基本模型是定義在特徵空間上的間隔最大的線性分類器,間隔最大使它有別於感知機;而且SVM還支持核技巧,能夠對非線形的數據進行分類,其實就是將非線形問題變換為線性問題,通過解變換後的線性問題來得到原來非線形問題的解。
舉個例子來說明支持向量機是來幹什麼的吧!
將實例的特徵向量(以二維為例)映射為空間中的一些點,就是如下圖的圓心點和『x』,它們屬於不同的兩類。那麼SVM的目的就是想要畫出一條線,以「最好地」區分這兩類點,以至如果以後有了新的點,這條線也能做出很好的分類。
image-20200911211014780從圖中我們可以看出能夠畫出多條線對樣本點進行區分,區別就在於效果好不好。比如粉色線就不好,綠色還湊合,黑色的線看起來就比較好。我們希望找到這條效果最好的線叫作劃分超平面。
看官老爺們可能會問畫這條線的標準是什麼?
SVM將會尋找可以區分兩個類別並且能夠使間隔(margin)最大的超平面,即劃分超平面。
註:間隔就是某一條線距離它兩側最近的點的距離之和。
2.SVM定義與公式建立在樣本空間中,劃分超平面可以定義為:
其中
將超平面記為(
假設超平面(
如下圖所示,距離超平面最近的幾個樣本點使得公式(2.3)的等號成立,這個個樣本點被稱為 「支持向量」(support vector),兩個異類支持向量到超平面的距離之和為
第一小節我們講到 SVM 就是要找到區分兩個類別並使兩個異類支持向量到超平面的距離之和最大,也就是要找到滿足式(2.3)中約束的參數
s.t.
為了使
s.t.
這就是支持向量機(Support Vector Machine,SVM)的基本型.
3. 核函數支持向量機通過某非線性變換 ∂( x ),將輸入空間映射到高維特徵空間。特徵空間的維數可能非常高。如果支持向量機的求解只用到內積運算,而在低維輸入空間又存在某個函數
3.1 常用的核函數(kernel functions)線性核
多項式核
高斯核
拉普拉斯核
Sigmoid 核
tanh為雙曲線正切函數,
核函數那麼多,那麼一般如何選擇?
嘗試不同的 kernel ,根據結果準確度而定,嘗試不同的 kernel。
根據先驗知識,比如圖像分類,通常用RBF(高斯核),文字不使用RBF。
舉個小例子來說明核函數吧!
假設兩個向量
可以定義方程(Grim矩陣):
設函數為 $K(x,y)=()^2$
假設
如果不使用核函數,直接求內積:
$=16+40+72+40+100+180+72+180+324=1024$
使用核函數:
兩種方法都可以得到同樣的結果,但是使用kernel方法計算容易很多,在樣本維度很高時這種方法會更加顯示其優勢。
4.SVM 應用實例由於 SVM 算法本身的實現較為複雜,所以這裡就不給出如何實現SVM的代碼,採用 sklearn庫來幫助我們學習SVM 的應用例子。
這裡對sklearn畫出超平面步驟做個說明
1)首先獲取權重矩陣
weight = model.coef_[0]
列印結果如下
有兩個值,分別是
這樣的好處在於如果有多組特徵,方便擴展。在預測時,將待測的(x0,x1)帶入上式,根據大於或者小於0即可判斷類別。
2)bias的值可以使用model.intercept_即可獲取
為了方便畫圖,我們可以通過移項轉換為我們熟悉的斜截式:
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from sklearn.svm import SVC
def create_data():
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
data = np.array(df.iloc[:100, [0, 1, -1]])
# 將label==0的實例賦值為-1
for i in range(len(data)):
if data[i, -1] == 0:
data[i, -1] = -1
return data[:, :-1], data[:, -1]
def SVM():
x, y = create_data()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
model = SVC(kernel="linear")
model.fit(x_train, y_train)
precise = model.score(x_test, y_test)
print(precise)
# 畫出散點圖
plt.scatter(x[:50, 0], x[:50, 1], label='0')
plt.scatter(x[50:100, 0], x[50:100, 1], label='1')
# 查看權重矩陣
weight = model.coef_[0]
#print(model.coef_)
# 取出截距
bias = model.intercept_[0]
k = -weight[0] / weight[1]
b = -bias / weight[1]
# 獲取支持向量
support_vector = model.support_vectors_
# 畫出支持向量
for i in support_vector:
plt.scatter(i[0], i[1], marker=',', c='b')
# 畫出超平面
xx = np.linspace(4, 7, 10)
yy = k * xx + b
plt.plot(xx, yy)
plt.legend()
plt.show()
if __name__ == '__main__':
SVM()sklearn.svm.SVC
(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False,tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape=None,random_state=None)
參數:
C:C-SVC的懲罰參數C?默認值是1.0
C越大,相當於懲罰鬆弛變量,希望鬆弛變量接近0,即對誤分類的懲罰增大,趨向於對訓練集全分對的情況,這樣對訓練集測試時準確率很高,但泛化能力弱。C值小,對誤分類的懲罰減小,允許容錯,將他們當成噪聲點,泛化能力較強。
kernel :核函數,默認是rbf,可以是『linear』, 『poly』, 『rbf』, 『sigmoid』, 『precomputed』
– 線性:u'v
– 多項式:(gammau'v + coef0)^degree
– RBF函數:exp(-gamma|u-v|^2)
– sigmoid:tanh(gammau'v + coef0)
degree :多項式poly函數的維度,默認是3,選擇其他核函數時會被忽略。
gamma : 『rbf』,『poly』 和『sigmoid』的核函數參數。默認是』auto』,則會選擇1/n_features
coef0 :核函數的常數項。對於『poly』和 『sigmoid』有用。
probability :是否採用概率估計?.默認為False
shrinking :是否採用shrinking heuristic方法,默認為true
tol :停止訓練的誤差值大小,默認為1e-3
cache_size :核函數cache緩存大小,默認為200
class_weight :類別的權重,字典形式傳遞。設置第幾類的參數C為weight*C(C-SVC中的C)
verbose :允許冗餘輸出?
max_iter :最大迭代次數。-1為無限制。
decision_function_shape :『ovo』, 『ovr』 or None, default=None3
random_state :數據洗牌時的種子值,int值
主要調節的參數有:C、kernel、degree、gamma、coef0。有收穫給我點個讚吧!歡迎關注我的公眾號《江大白玩AI》!