SVM算法


本文主要介紹支持向量機理論推導及其工程應用。

1 基本介紹

支持向量機算法是一個有效的分類算法,可用於分類、回歸等任務,在傳統的機器學習任務中,通過人工構造、選擇特征,然后使用支持向量機作為訓練器,可以得到一個效果很好的base-line訓練器。

支持向量機具有如下的優缺點,

優點:

  1. 高維空間有效;
  2. 維度大於樣本數量的情況下,依然有效;
  3. 預測時使用訓練樣本的子集(也即支持向量),節省內存;
  4. 可以使用不同的核函數用於決策;

缺點:

  1. 如果特征的數目遠遠大於樣本的數目,性能將會降低;
  2. 不能直接提供概率估計,需要通過5-fold 交叉驗證來獲得;

2 理論推導

2.1 間隔與支持向量

划分超平面,\(\mathbf{w}^{T} * \mathbf{x} + b = 0 \ (1)\)

樣本空間中任意一個樣本 \(\mathbf{x}\) 到超平面的距離為 \(r = \frac{||\mathbf{w}^{T} * \mathbf{x} + b||}{||\mathbf{w}||} \ (2)\)

假設超平面能將樣本正確分類,即對樣本 \((\mathbf{x}_{i},y_{i})\)

\(y_{i} = +1\) ,則 \(\mathbf{w}^{T} * \mathbf{x}_{i} + b > 0\)
\(y_{i} = -1\) ,則 \(\mathbf{w}^{T} * \mathbf{x}_{i} + b < 0\)

令,

\(\mathbf{w}^{T} * \mathbf{x}_{i} + b \ge +1, \ y_{i} = +1 \ \ \ (3)\)

\(\mathbf{w}^{T} * \mathbf{x}_{i} + b \le -1, \ y_{i} = -1\)

距離超平面最近的幾個訓練樣本點,使上式的等號成立,則它們稱為支持向量;

兩個異類支持向量到超平面的距離之和為

\(r = \frac{2}{||\mathbf{w}||} \ \ \ (4)\)

欲找到最大間隔的划分超平面,也就是找到 \(\mathbf{w}\) 和b,使得r最大,即

\(max_{\mathbf{w},b} \frac{2}{||\mathbf{w}||} \ \ \ (5)\)

\(s.t.\ \ y_{i}(\mathbf{w}^{T} * \mathbf{x}_{i} + b) \ge 1,\ \ i = 1,2...,m\)

等價於,

\(min_{\mathbf{w},b}\frac{1}{2}||\mathbf{w}||^{2} \ \ \ (6)\)

\(s.t.\ \ y_{i}(\mathbf{w}^{T} * \mathbf{x}_{i} + b) \ge 1,\ \ i = 1,2...,m\)

希望求解式(6),來得到最大間隔划分超平面所對應的模型,

\(f(\mathbf{x})=\mathbf{w}^{T} * \mathbf{x} + b \ \ \ (7)\)

2.2 對偶問題

對上述公式使用拉格朗日乘子法,可得其對偶問題,具體就是對上述公式的每個約束添加拉格朗日乘子 \(\alpha_{i} \ge 0\) ,則拉格朗日函數可寫為,

\(L(\mathbf{w},b,\mathbf{\alpha})=\frac{1}{2}||\mathbf{w}||^{2} + \sum_{i=1}^{m}\alpha_{i} * (1 - y_{i} * (\mathbf{w}^{T} * \mathbf{x}_{i} + b)) \ \ \ (8)\)

其中, \(\mathbf{\alpha} = (\alpha_{1};\alpha_{2};...;\alpha_{m})\),令\(L(\mathbf{w},b,\mathbf{\alpha})\) 分別對 \(\mathbf{w}\) 和b求偏導,可得,

\(\mathbf{w} = \sum_{i=1}^{m}\alpha_{i} * y_{i} * \mathbf{x}_{i} \ \ \ (9)\)

\(0 = \sum_{i=1}^{m}\alpha_{i} * y_{i} \ \ \ (10)\)

將式(9)帶入(8)中,可將\(L(\mathbf{w},b,\mathbf{\alpha})\) 中的 \(\mathbf{w}\) 和b消去,再考慮式(10)的約束,可得式(6)的對偶問題,

\(max_{\mathbf{\alpha}}\sum_{i=1}^{m}\alpha_{i} - \frac{1}{2}\sum_{i=1}^{m}\sum_{j=1}^{m}\alpha_{i} * \alpha_{j} * y_{i} * y_{j} * \mathbf{x}_{i}^{T} * \mathbf{x}_{j} \ \ \ (11)\)

\(s.t.\ \ \sum_{i=1}^{m}\alpha_{i} * y_{i} = 0\)

\(\alpha_{i} \ge 0 \ \ i = 1,2...,m\)

解出 \(\mathbf{\alpha}\) 后,求出 \(\mathbf{w}\) 和b,即可得到模型,

\(f(\mathbf{x})=\mathbf{w}^{T} * \mathbf{x} + b = \sum_{i=1}^{m}\alpha_{i} * y_{i} * \mathbf{x}_{i}^{T} * \mathbf{x}_{j} + b\ \ \ (12)\)

式(11)中解出的 \(\alpha_{i}\) 是式(8)中的拉格朗日乘子,恰好對應着樣本 \((\mathbf{x}_{i},y_{i})\),注意到式(6)中有不等式約束,因此上述過程滿足KKT條件,即,

\(\alpha_{i} \ge 0\ \ \ (13)\)

\(y_{i} * f(\mathbf{x}_{i}) - 1 \ge 0\)

\(\alpha_{i} * (y_{i} * f(\mathbf{x}_{i}) - 1) = 0\)

對於訓練樣本 \((\mathbf{x}_{i},y_{i})\),總有 \(\alpha_{i} = 0\) 或者 \(y_{i} * f(\mathbf{x}_{i}) = 1\)

\(\alpha_{i} = 0\) ,則該樣本不會在式(12)中的求和中出現,也就不會對 \(f(\mathbf{x})\) 有任何影響;

\(\alpha_{i} \ge 0\) ,則必有 \(y_{i} * f(\mathbf{x}_{i}) = 1\) ,所對應樣本點位於最大分割邊界上,是一個支持向量;

2.3 核函數

如果訓練樣本不能線性可分,可將樣本從原始空間映射到更高維的特征空間,使得樣本在這個特征空間內線性可分;

\(\phi(\mathbf{x})\) 表示為 \(\mathbf{x}\) 映射后的特征向量,於是,在特征空間中划分超平面所對應的模型可表示為 \(f(\mathbf{x})=\mathbf{w}^{T}\phi(\mathbf{x}) + b\ \ \ (14)\)

其中, \(\mathbf{w}\) 和b是模型參數,類似於式(6)有,

\(min_{\mathbf{w},b}\frac{1}{2}||\mathbf{w}||^{2} \ \ \ (15)\)

\(s.t.\ \ y_{i}(\mathbf{w}^{T} * \phi(\mathbf{x}_{i}) + b) \ge 1,\ \ i = 1,2...,m\)

對偶問題為,

\(max_{\mathbf{\alpha}}\sum_{i=1}^{m}\alpha_{i} - \frac{1}{2}\sum_{i=1}^{m}\sum_{j=1}^{m}\alpha_{i} * \alpha_{j} * y_{i} * y_{j} * \phi(\mathbf{x}_{i})^{T} * \phi(\mathbf{x}_{j}) \ \ \ (16)\)

\(s.t.\ \ \sum_{i=1}^{m}\alpha_{i} * y_{i} = 0\)

\(\alpha_{i} \ge 0 \ \ i = 1,2...,m\)

由於樣本 \(\mathbf{x}_{i},\mathbf{x}_{j}\) 映射到特征空間之后,特征空間的維數可能很高,甚至是無窮維,因此直接計算 \(\phi(\mathbf{x}_{i})^{T} * \phi(\mathbf{x}_{j})\) 通常很困難,可以設想這樣一個函數,

\(k(\mathbf{x}_{i},\mathbf{x}_{j}) = <\phi(\mathbf{x}_{i}),\phi(\mathbf{x}_{j})> = \phi(\mathbf{x}_{i})^{T} * \phi(\mathbf{x}_{j}) \ \ \ (17)\)

則式(16)可重寫為,

\(max_{\mathbf{\alpha}}\sum_{i=1}^{m}\alpha_{i} - \frac{1}{2}\sum_{i=1}^{m}\sum_{j=1}^{m}\alpha_{i} * \alpha_{j} * y_{i} * y_{j} * k(\mathbf{x}_{i},\mathbf{x}_{j}) \ \ \ (18)\)

\(s.t.\ \ \sum_{i=1}^{m}\alpha_{i} * y_{i} = 0\)

\(\alpha_{i} \ge 0 \ \ i = 1,2...,m\)

求解即可得到模型,

\(f(\mathbf{x})=\mathbf{w}^{T} * \phi(\mathbf{x}) + b = \sum_{i=1}^{m}\alpha_{i} * y_{i} * \phi(\mathbf{x}_{i})^{T} * \phi(\mathbf{x}_{j}) + b = \sum_{i=1}^{m}\alpha_{i} * y_{i} * k(\mathbf{x}_{i},\mathbf{x}_{j}) + b\ \ \ (19)\)

其中,\(k(.,.)\) 就是核函數;

常見的核函數有,

線性核,\(k(\mathbf{x}_{i},\mathbf{x}_{j}) = \mathbf{x}_{i}^{T} * \mathbf{x}_{j}\)

多項式核,\(k(\mathbf{x}_{i},\mathbf{x}_{j}) = (\mathbf{x}_{i} * \mathbf{x}_{j})^d,d \ge 1\) ,為多項式的次數;

高斯核,\(k(\mathbf{x}_{i},\mathbf{x}_{j}) = exp(-\frac{||\mathbf{x}_{i} - \mathbf{x}_{j}||^{2}}{2 * \sigma^{2}}),\sigma > 0\)

拉普拉斯核,\(k(\mathbf{x}_{i},\mathbf{x}_{j}) = exp(-\frac{||\mathbf{x}_{i} - \mathbf{x}_{j}||}{\sigma}).\sigma > 0\)

Sigmoid核,\(k(\mathbf{x}_{i},\mathbf{x}_{j}) = tanh(\beta * \mathbf{x}_{i}^{T} * \mathbf{x}_{j} + \theta),\beta > 0,\theta < 0\)

2.4 軟間隔

前面介紹的支持向量機形式要求所有樣本滿足約束條件(3),即所有樣本都必須划分正確,也即“硬划分”,而軟間隔則是允許某些樣本不滿足約束

\(y_{i} * (\mathbf{w}^{T} * \mathbf{x}_{i} + b) \ge 1\ \ \ (20)\)

在最大化間隔的同時,不滿足約束的樣本應該盡可能少,於是,優化目標可寫為,

\(min_{\mathbf{w},b} \frac{1}{2}||\mathbf{w}||^{2} + C * \sum_{i=1}^{m}\ell_{0/1}(y_{i} * (\mathbf{w}^{T} * \mathbf{x}_{i} + b) - 1)\ \ \ (21)\)

其中C > 0, \(\ell_{0/1}\) 是“0-1損失函數”,

\(\ell = 1,\ if \ z < 0\ \ \ (22)\)

\(\ell = 0,otherwise\)

如果C為無窮大,則式(21)迫使所有樣本均滿足約束(20),於是式(21)等價與式(6);

如果C取有限值,式(21)允許一些樣本不滿足約束(20);

由於 \(\ell_{0/1}\) 非凸,非連續,因此可以選用其它函數代替它,如hinge-loss,exponential-loss,logistic-loss等損失函數。

若采用hinge-loss函數,則式(21)變為,

\(min_{\mathbf{w},b} \frac{1}{2}||\mathbf{w}||^{2} + C * \sum_{i=1}^{m}max(0, 1 - y_{i} * (\mathbf{w}^{T} * \mathbf{x}_{i} + b))\ \ \ (23)\)

引入松弛變量 \(\xi_{i} \ge 0\),則式(23)重寫為,

\(min_{\mathbf{w},b,\xi_{i}} \frac{1}{2}||\mathbf{w}||^{2} + C * \sum_{i=1}^{m}\xi_{i}\ \ \ (24)\)

\(s.t.\ \ y_{i} * (\mathbf{w}^{T} * \mathbf{x}_{i} + b) \ge 1 - \xi_{i}\)

\(\xi_{i} \ge 0,\ i = 1,2,...,m\)

與式(8)類似,通過拉格朗日乘子法可得式(24)的拉格朗日函數。

\(L(\mathbf{w},b,\xi,\mu) = \frac{1}{2}||\mathbf{w}||^{2} + C * \sum_{i=1}^{m}\xi_{i} + \sum_{i=1}^{m}\alpha_{i} * (1 - \xi_{i} - y_{i} * (\mathbf{w}^{T} * \mathbf{x}_{i} + b)) - \sum_{i=1}^{m}\mu_{i} * \xi_{i}\ \ \ (25)\)

其中, \(\alpha_{i} \ge 0, \ \mu_{i} \ge 0\)是拉格朗日乘子;

\(L(\mathbf{w},b,\xi,\mu)\) 分別對 \(\mathbf{w},b,\xi_{i}\) 求偏導,可得,

\(\mathbf{w} = \sum_{i=1}^{m}\alpha_{i} * y_{i} * \mathbf{x}_{i}\ \ \ (26)\)

\(0 = \sum_{i=1}^{m}\alpha_{i} * y_{i}\ \ \ (27)\)

\(C = \alpha_{i} + \mu_{i}\ \ \ (28)\)

將式(26)-(28)代入式(25)中,可得式(24)的對偶問題,

\(max_{\mathbf{\alpha}} = \sum_{i=1}^{m}\alpha_{i} - \frac{1}{2}\sum_{i=1}^{m}\sum_{j=1}^{m}\alpha_{i} * \alpha_{j} * y_{i} * y_{j} * \mathbf{x}_{i}^{T} * \mathbf{x}_{j}\ \ \ (29)\)

\(s.t.\ \sum_{j=1}^{m}\alpha_{i} * y_{i} * \mathbf{x}_{i} = 0\)

\(0 \le \alpha_{i} \le C,i=1,2,...,m\)

對比式(29)與式(11),唯一的差別就是在於對偶變量的約束不同,前者是 \(0 \le \alpha_{i} \le C\),后者是 \(0 \le \alpha_{i}\),解法與之前一樣,引入核函數后能得到式(19)同樣的支持向量展開式;

類似於式(13),對軟間隔支持向量機,KKT條件要求。

\(C \ge \alpha_{i} \ge 0,\mu_{i} \ge 0\ \ \ (30)\)

\(y_{i} * f(\mathbf{x}_{i}) - 1 + \xi_{i} \ge 0\)

\(\alpha_{i} * (y_{i} * f(\mathbf{x}_{i}) - 1 + \xi_{i}) = 0\)

\(\xi_{i} \ge 0,\ \mu_{i} * \xi_{i} = 0\)

對任意訓練樣本 \((\mathbf{x}_{i},y_{i})\),總有 \(\alpha_{i} = 0\) 或者 \(y_{i} * f(\mathbf{x}_{i}) = 1 - \xi_{i}\)

(1) 若 \(\alpha_{i} = 0\) ,則該樣本不會對\(f(\mathbf{x})\) 有任何影響;

(2) 若 \(\alpha_{i} > 0\) ,則必有 \(y_{i} * f(\mathbf{x}_{i}) = 1 - \xi_{i}\),則該樣本為支持向量;

(2.1) 若 \(\alpha_{i} < C\) ,則 \(\mu_{i} > 0,\ \xi_{i} = 0\),必有 \(y_{i} * f(\mathbf{x}_{i}) = 1\),則該樣本位於最大間隔上;

(2.2) 若 \(\alpha_{i} = C\) ,則 \(\mu_{i} = 0,\ \xi_{i} > 0\)

(2.2.1) 若 \(\xi_{i} \le 1\),則樣本落在最大分割內部;

(2.2.2) 若 \(\xi_{i} \ge 1\),則樣本被錯誤分類;

2.5 多分類

SVM算法最初是為二分類問題設計,當處理多分類問題時,需要構造合適的多類分類器。

1.one-versus-rest(一對多法):

訓練時,依次把某個類別的樣本歸為一類,其他剩余的樣本歸為另一類,有k個類別的樣本就構造出k個SVM;預測時,將未知樣本分類為具有最大分類函數值的那類。

缺陷:會存在數據傾斜;分類結果出現重疊(屬於多個分類器)或者不可分類(不屬於任何一個分類器)。

2.one-versus-one(一對一法):

訓練時,選擇一個類的樣本作為正樣本,負樣本則只選擇一個類,又k個類別的樣本,就構造出 \(\frac{k(k-1)}{2}\) 個分類器,雖然分類器的數組增加了,但是訓練階段所用的總時間卻比"one-versus-rest"方法少很多。預測時,每個分類器都會預測出一個結果,然后統計最后的預測結果。盡管這個方法也有分類重疊現象,但是不會有不可分類的現象,因為不可能所有類別的票數都是0。

3.DAG SVM:

類似於"one-versus-one"方法,只是在對一個樣本進行分類之前,先按照下圖的結構組織分類器(這是一個有向無環圖,因此被稱作DAG SVM),

在預測時,可以先問分類器"1 vs 5",如果回答是5,就往左走;再問分類器"2 vs 5",如果還回答5,就繼續往左走,一直問下去,就可以得到分類結果,如果有k個類別,那么只調用k-1個,分類速度快,且沒有分類重疊和不可分類現象。

缺陷:如果一開始分類器回答錯誤,那么后面的分類器是無法糾正的。

3 工程應用

使用Python機器學習開源庫scikit-learn中提供的SVM算法來進行實驗。scikit-learn中提供的SVM模型既可以支持稠密數據(numpy.ndarray),也支持稀疏數據(scipy.sparse)。如果要使用SVM模型來對稀疏數據進行預測,它必須符合這些數據類型,例如,為了獲得最優的性能,在使用C-ordered numpy.ndarray(稠密)或者scipy.sparse.csr_matrix(稀疏)這些數組時,指定數據類型dtype=float64。

example 1,畫出不同SVM分類器在iris數據集上的分界線;

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm,datasets

iris = datasets.load_iris()
X = iris.data[:,:2]
y = iris.target

h = 0.02
C = 1.0
svc = svm.SVC(kernel = 'linear',C=C).fit(X,y)
rbf_svc = svm.SVC(kernel = 'rbf',gamma = 0.7, C=C).fit(X,y)
poly_svc = svm.SVC(kernel = 'poly',degree = 3,C=C).fit(X,y)
lin_svc = svm.LinearSVC(C=C).fit(X,y)

x_min,x_max = X[:,0].min() - 1,X[:,0].max() + 1
y_min,y_max = X[:,1].min() - 1,X[:,1].max() + 1

xx,yy = np.meshgrid(np.arange(x_min,x_max,h),
                    np.arange(y_min,y_max,h))

titles = ['SVC with linear kernel',
          'LinearSVC (linear kernel)',
          'SVC with RBF kernel',
          'SVC with polynomial (degree 3) kernel']

for i ,clf in enumerate((svc,lin_svc,rbf_svc,poly_svc)):
    plt.subplot(2,2,i+1)
    plt.subplots_adjust(wspace = 0.4,hspace = 0.4)
    Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
    Z = Z.reshape(xx.shape)
    plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
    plt.xlabel('Sepal length')
    plt.ylabel('Sepal width')
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.xticks(())
    plt.yticks(())
    plt.title(titles[i])

plt.show()

各個分類器的分界面如下所示,

example 2,畫出最大分割超平面;

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm

# we create 40 separable points
np.random.seed(0)
X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]
Y = [0] * 20 + [1] * 20

# fit the model
clf = svm.SVC(kernel='linear')
clf.fit(X, Y)

# get the separating hyperplane
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (clf.intercept_[0]) / w[1]

# plot the parallels to the separating hyperplane that pass through the
# support vectors
b = clf.support_vectors_[0]
yy_down = a * xx + (b[1] - a * b[0])
b = clf.support_vectors_[-1]
yy_up = a * xx + (b[1] - a * b[0])

# plot the line, the points, and the nearest vectors to the plane
plt.plot(xx, yy, 'k-')
plt.plot(xx, yy_down, 'k--')
plt.plot(xx, yy_up, 'k-.')

plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
            s=80, facecolors='none')
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired)

plt.axis('tight')
plt.show()

最大分割超平面如下所示,

example 3,針對異或類型數據,研究SVM(高斯核)中參數對分類的影響。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm

xx, yy = np.meshgrid(np.linspace(-3, 3, 500),
                     np.linspace(-3, 3, 500))
np.random.seed(0)
X = np.random.randn(300, 2)
Y = np.logical_xor(X[:, 0] > 0, X[:, 1] > 0)

CArray = [0.1,1.0,10.0,100.0]
gammaArray = [0.1,1.0,10.0,100.0]

clfList = []
for C in CArray:
    clf = svm.SVC(kernel = 'rbf',gamma = gammaArray[1], C=C).fit(X,Y)
    clfList.append(clf)

for gamma in gammaArray:
    clf = svm.SVC(kernel = 'rbf',gamma = gamma, C=CArray[1]).fit(X,Y)
    clfList.append(clf)

titles = ['C = 0.1,gamma = 1.0',
          'C = 1.0,gamma = 1.0',
          'C = 10.0,gamma = 1.0',
          'C = 100.0,gamma = 1.0',
          'C = 1.0,gamma = 0.1',
          'C = 1.0,gamma = 1.0',
          'C = 1.0,gamma = 10.0',
          'C = 1.0,gamma = 100.0',
          ]

# fit the model
for i,clf in enumerate(clfList):
    print "i = ",i
    plt.subplot(2, 4, i + 1)
    plt.subplots_adjust(wspace=0.4, hspace=0.4)
    # plot the decision function for each datapoint on the grid
    Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)


    plt.imshow(Z, interpolation='nearest',
           extent=(xx.min(), xx.max(), yy.min(), yy.max()), aspect='auto',
           origin='lower', cmap=plt.cm.PuOr_r)
    contours = plt.contour(xx, yy, Z, levels=[0], linewidths=2,
                       linetypes='--')
    plt.scatter(X[:, 0], X[:, 1], s=30, c=Y, cmap=plt.cm.Paired)
    plt.xticks(())
    plt.yticks(())
    plt.axis([-3, 3, -3, 3])
    plt.title(titles[i])
plt.show()

分類對比圖,如下所示,

上面四個圖是固定 \(\gamma\) ,選取不同的C,可以發現C越大時,允許被錯誤分類的樣本數量就越少;C越小時,允許被錯誤分類的樣本數量就可能就會越多。

下面四個圖是固定C,選取不同的 \(\gamma\)\(\gamma = \frac{1}{2*\sigma^{2}}\) 會影響高斯核函數的分布, \(\gamma\) 越大,高斯核函數分布就會越陡峭; \(\gamma\) 越小,高斯很函數分布就會越平緩; 因此當 \(\gamma\) 越大時,截取等高面時,樣本就只會在自己周圍形成分布; \(\gamma\) 越小時,截取等高面時,樣本就可以在自己周圍較大的范圍內形成分布,因此同類樣本就有可能連接在一起。

4 Reference

機器學習(周志華)

支持向量機(五)SMO算法

SVM-支持向量機詳解(四)--多類分類器

SVM的兩個參數 C 和 gamma

1.4. Support Vector Machines


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM