397
汽車大全
支持向量機分類實戰
更多深度文章,請關注雲計算頻道:https://yq.aliyun.com/cloud
支持向量機(SVM)是一個非常強大和靈活的機器學習模型,能夠執行線性或非線性的分類,回歸,甚至異常值檢測。它是機器學習中最受歡迎的有監督學習模式之一,任何對ML感興趣的人都應該對其有所了解,並且能夠掌握其使用方法。SVM特別適用於複雜但數據集屬於中小型的分類。
SVM主要的思想可以概括為兩點:
1ï¼ 它是針對線性可分情況進行分析,對於線性不可分的情況,通過使用非線性映射算法將低維輸入空間線性不可分的樣本轉化為高維特征空間使其線性可分,從而使得高維特征空間采用線性算法對樣本的非線性特征進行線性分析成為可能。
2ï¼ 它基於結構風險最小化理論之上在特征空間中構建最優超平麵,使得學習器得到全局最優化,並且在整個樣本空間的期望以某種概率滿足一定上界。
在這篇文章中,我們將探討如何用Python實現分類的SVM模型。
線性SVM
假設我們有兩類數據,我們要使用SVM進行分類,如圖所示:
這兩個類數據可以用直線(線性分離)輕鬆分離。左圖顯示了2個可能的線性分類器的決策邊界。SVM模型其實就是關於生成正確的分界線(在較高維度稱為Hyperplane)。在左圖中,我們可以看到數據分類非常好,盡管紅線對數據進行了分類,但在新的數據實例中可能無法很好地執行。我們可以畫出許多對這些數據進行分類的線,但是在所有這些線中,藍線可以分隔最多的數據。如果將相同的藍線顯示在右圖,這條線(超平麵)不僅分離了兩個類,而且還保持了最遠的相近的訓練實例的距離。我們稱之為大間距分類器(Large Margin Classification)。
這個最好的決策邊界是由位於分界線邊緣的實例確定(或“支持”)的。這些實例稱為支持向量兩條線邊緣之間的距離稱為邊距。
軟間距分類器(soft Margin Classification)
如果我們嚴格把我們所用的例子放在這兩條虛線上(如下圖),並且在正確的一邊,這就是所謂的硬間距分類,硬間距分類有2個問題。
1)隻有數據線性分離才有效。
2)對異常值非常敏感。
在上麵的數據類中,有一個藍色的異常值。如果我們對該數據集應用硬間距分類器,我們將獲得左邊圖所示的小邊距的決策邊界。為了避免這些問題,最好使用更靈活的模型。目的是在保持兩條線之間距離盡可能大的情況下找到一個良好的平衡,並限製邊際違規(即,最終在兩條線中間的距離甚至錯誤的一麵的情況),這稱為軟間距分類器。如果我們對該數據集應用軟間距分類,我們將獲得比硬間距分類更大的確定邊界,這在右圖中顯示。
雖然線性SVM分類器是有效的,並且在許多情況下令人驚奇地工作,但是許多數據集是不能接近線性分離。處理非線性數據集的一個簡單方法是添加更多的特征,例如多項式特征,有時這可以導致線性可分離的數據集。通過生成多項式特征,我們將具有一個新特征矩陣,該特征矩陣由具有小於或等於指定度數的特征的所有多項式組合組成。以下圖像是使用多項式特征進行SVM的示例。
內核是計算兩個向量X,Y的點積的一種方法和在某些(可能非常高的維度)特征空間中,這就是為什麼內核函數有時被稱為“廣義點積分”。假設我們有一個映射:φ:Rn→Rm,這使我們的矢量在Rn到某些特征空間Rm。然後數量積X,Y在這個空間裏麵是 φ(x)Tφ(y)。一個內核是一個函數K相當於數量積:k(x,y)=φ(x)Tφ(y)。內核提供了一種方法來計算某些特征空間中的點積,甚至不知道這個空間是什麼。
添加多項式特征非常簡單。但是低度多項式不能處理複雜的數據集,並且具有較高的多項式度將會產生大量的特征,使得模型太慢。在這種情況下,我們可以使用多項式內核來避免這個問題。多項式內核具有以下格式:
這裏的D是多項式的次數。
高斯RBF(徑向基函數)是SVM模型中使用的另一種流行的內核方法。高斯內核具有以下格式:
k (x,y)= e- γ| x - y |2,γ> 0
如果我們有如下的數據集,則RBF內核非常有用。
在SVM模型中有2個重要的超參數:
1.C參數
C參數決定SVM分類器的邊距寬度,而且它的分類器嚴格,因此邊緣寬度較小。對於值大的C,如果該超平麵更好地將所有訓練點歸類正確,則該模型將選擇較小餘量的超平麵。相反,C的非常小的值將導致模型尋找更大的邊緣從而分離超平麵。對於非常小的C值,你應該得到錯誤分類的例子,通常即使你的訓練數據是線性分離的。
2.γ參數
這個γ參數定義了每個訓練示例,γ參數對於scikit-learning中的線性內核是無效的。
在這部分中,我們將使用scikit學習來實現SVM,我們將使用人工數據集。
import numpy as np
import pandas as pd
from matplotlib import style
from sklearn.svm import SVC
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (12, 6)
style.use('ggplot')
# Import Dataset
data = pd.read_csv('data.csv', header=None)
X = data.values[:, :2]
y = data.values[:, 2]
# A function to draw hyperplane and the margin of SVM classifier
def draw_svm(X, y, C=1.0):
# Plotting the Points
plt.scatter(X[:,0], X[:,1], c=y)
# The SVM Model with given C parameter
clf = SVC(kernel='linear', C=C)
clf_fit = clf.fit(X, y)
# Limit of the axes
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# Creating the meshgrid
xx = np.linspace(xlim[0], xlim[1], 200)
yy = np.linspace(ylim[0], ylim[1], 200)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
# Plotting the boundary
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1],
alpha=0.5, linestyles=['--', '-', '--'])
ax.scatter(clf.support_vectors_[:, 0],
clf.support_vectors_[:, 1],
s=100, linewidth=1, facecolors='none')
plt.show()
# Returns the classifier
return clf_fit
clf_arr = []
clf_arr.append(draw_svm(X, y, 0.0001))
clf_arr.append(draw_svm(X, y, 0.001))
clf_arr.append(draw_svm(X, y, 1))
clf_arr.append(draw_svm(X, y, 10))
for i, clf in enumerate(clf_arr):
# Accuracy Score
print(clf.score(X, y))
pred = clf.predict([(12, 32), (-250, 32), (120, 43)])
print(pred)
0.992907801418
[1 0 1]
0.992907801418
[1 0 1]
1.0
[1 0 1]
1.0
[1 0 1]
你可以看到具有不同邊距寬度的相同超平麵,這取決於C超參數。
import numpy as np
import pandas as pd
from matplotlib import style
from sklearn.svm import SVC
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (12, 6)
style.use('ggplot')
data = pd.read_csv('polydata2.csv', header=None)
X = data.values[:, :2]
y = data.values[:, 2]
def draw_svm(X, y, C=1.0):
plt.scatter(X[:,0], X[:,1], c=y)
clf = SVC(kernel='poly', C=C)
clf_fit = clf.fit(X, y)
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
xx = np.linspace(xlim[0], xlim[1], 200)
yy = np.linspace(ylim[0], ylim[1], 200)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1],
alpha=0.5, linestyles=['--', '-', '--'])
ax.scatter(clf.support_vectors_[:, 0],
clf.support_vectors_[:, 1],
s=100, linewidth=1, facecolors='none')
plt.show()
return clf_fit
clf = draw_svm(X, y)
score = clf.score(X, y)
pred = clf.predict([(-130, 110), (-170, -160), (80, 90), (-280, 20)])
print(score)
print(pred)

1.0
[0 1 0 1]
import numpy as np
import pandas as pd
from matplotlib import style
from sklearn.svm import SVC
from sklearn.datasets import make_classification, make_blobs, make_moons
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (12, 6)
style.use('ggplot')
X, y = make_moons(n_samples=200)
# Auto gamma equals 1/n_features
def draw_svm(X, y, C=1.0, gamma='auto'):
plt.scatter(X[:,0], X[:,1], c=y)
clf = SVC(kernel='rbf', C=C, gamma=gamma)
clf_fit = clf.fit(X, y)
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
xx = np.linspace(xlim[0], xlim[1], 200)
yy = np.linspace(ylim[0], ylim[1], 200)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1],
alpha=0.5, linestyles=['--', '-', '--'])
ax.scatter(clf.support_vectors_[:, 0],
clf.support_vectors_[:, 1],
s=100, linewidth=1, facecolors='none')
plt.show()
return clf_fit
clf_arr = []
clf_arr.append(draw_svm(X, y, 0.01))
clf_arr.append(draw_svm(X, y, 0.1))
clf_arr.append(draw_svm(X, y, 1))
clf_arr.append(draw_svm(X, y, 10))
for i, clf in enumerate(clf_arr):
print(clf.score(X, y))
0.83
0.9
1.0
1.0
import numpy as np
import pandas as pd
from matplotlib import style
from sklearn.svm import SVC
from sklearn.datasets import make_gaussian_quantiles
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (12, 6)
style.use('ggplot')
X, y = make_gaussian_quantiles(n_samples=200, n_features=2, n_classes=2, cov=3)
# Auto gamma equals 1/n_features
def draw_svm(X, y, C=1.0, gamma='auto'):
plt.scatter(X[:,0], X[:,1], c=y)
clf = SVC(kernel='rbf', C=C, gamma=gamma)
clf_fit = clf.fit(X, y)
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
xx = np.linspace(xlim[0], xlim[1], 200)
yy = np.linspace(ylim[0], ylim[1], 200)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1],
alpha=0.5, linestyles=['--', '-', '--'])
ax.scatter(clf.support_vectors_[:, 0],
clf.support_vectors_[:, 1],
s=100, linewidth=1, facecolors='none')
plt.show()
return clf_fit
clf_arr = []
clf_arr.append(draw_svm(X, y, 0.1))
clf_arr.append(draw_svm(X, y, 1))
clf_arr.append(draw_svm(X, y, 10))
clf_arr.append(draw_svm(X, y, 100))
for i, clf in enumerate(clf_arr):
print(clf.score(X, y))
0.965
0.97
0.985
0.995
γ參數對RBF SVM模型非常重要。在第一個例子中,γ的低值導致非線性分類幾乎接近線性分類。
如果你對此感興趣,你可以查看此Github Repo代碼示例和數據集。
本文由北郵@愛可可-愛生活 老師推薦,阿裏雲雲棲社區組織翻譯。
文章原標題《Support Vector Machines for Classification》
作者:Mubaris NK
譯者:虎說八道,審校。
文章為簡譯,更為詳細的內容,請查看原文。
最後更新:2017-10-17 23:03:36