日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SVM 复盘总结

發(fā)布時間:2024/9/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SVM 复盘总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 1. 硬間隔最大化:
    • 上述問題如何求解?
      • 引入Lagrange function:
        • 原始問題:
        • 對偶優(yōu)化問題:
        • 對偶問題求最最優(yōu):
        • 根據(jù)KKT條件,求得$w^*$ 和$b^*$:
  • 2. 軟間隔最大化
    • 轉(zhuǎn)化為對偶問題:
        • 根據(jù)KKT條件,求得$w^*$ 和$b^*$:
  • 3. Hinge Loss
    • 軟間隔
    • Hinge Loss
  • 4. 核函數(shù)
  • 5. SMO算法
    • SMO算法要解如下凸二次規(guī)劃的對偶問題:
    • SMO算法的基本思想
      • 求解兩個變量二次規(guī)劃的解析方法
    • 變量的選擇方法
      • 1.第1個變量的選擇
      • 2.第2個變量的選擇
      • 3.計算閾值$b$和差值$E_i$
  • SMO實現(xiàn):
      • 數(shù)據(jù)集:
  • Reference:

1. 硬間隔最大化:


怎么得到的?自己推導(dǎo),可參考下圖推:

上述問題如何求解?

引入Lagrange function:


一系列推導(dǎo)之后,自己推導(dǎo):

原始問題:

對偶優(yōu)化問題:

對偶問題求最最優(yōu):

怎么求的SMO算法如何實現(xiàn),先等著?

對α的解為:

根據(jù)KKT條件,求得w?w^*w?b?b^*b?

KKT條件:

關(guān)注互補對偶條件如何得到的?
根據(jù)KKT條件,求得w?w^*w?b?b^*b?

如何推導(dǎo),自己推(選擇一個αj?\alpha_j^*αj?? > 0)

2. 軟間隔最大化

轉(zhuǎn)化為對偶問題:


推導(dǎo)之后:


進一步轉(zhuǎn)化:

看到?jīng)]?硬的和軟的對偶函數(shù)之間區(qū)別,只在于αi\alpha_iαi?的區(qū)域,但是轉(zhuǎn)換為原目標最優(yōu)還需要滿足KKT條件。
對α的解為:

根據(jù)KKT條件,求得w?w^*w?b?b^*b?

KKT條件:

w?w^*w? 比較好求?

如何求b?b^*b?

找一個0<αj?\alpha_j^*αj??<C,則ξj?\xi_j^*ξj?? = 0:

由于:

對b的解并不唯一,所以實際計算時可以取在所有符合條件的樣本點上的平均值。
這句話的理解:ξi?\xi_i^*ξi??是松弛因子,允許有些點在margin之內(nèi),0=<ξi?\xi_i^*ξi??,μi?\mu_i^*μi??=0,即αi?\alpha_i^*αi?? =C。
αi?\alpha_i^*αi?? =C是有l(wèi)oss的。
需要分割盡量開,同時允許有一些異常點,異常點發(fā)生在αi?\alpha_i^*αi?? =C的點,0<αi?\alpha_i^*αi?? <C的點都是支持向量,因為有αi?\alpha_i^*αi?? =C的點存在,導(dǎo)致b有多個解,所以b要取所有b的均值,αi?\alpha_i^*αi?? =0的點沒有用。

3. Hinge Loss

軟間隔

Hinge Loss


Hinge Loss就相當于松弛因子ξ?\xi^*ξ?
對于間距大于一定程度的點,就沒有l(wèi)oss,就不用松弛。
正則化的作用相當于把分類的距離拉大。

4. 核函數(shù)

沒啥東西,目標函數(shù)暴走,目標函數(shù)只需要比較對象的距離,而不是其本身,利用目標函數(shù)的這個弱點使用了kernel trick。

5. SMO算法

SMO算法要解如下凸二次規(guī)劃的對偶問題:


我們的解要滿足的KKT條件的對偶互補條件為:αi?(yi(wTxi+b)?1+ξi?)=0\alpha_{i}^{*}(y_i(w^Tx_i + b) - 1 + \xi_i^{*}) = 0αi??(yi?(wTxi?+b)?1+ξi??)=0
根據(jù)這個KKT條件的對偶互補條件,我們有:αi?=0?yi(w???(xi)+b);≥1\alpha_{i}^{*} = 0 \Rightarrow y_i(w^{*} \bullet \phi(x_i) + b);\geq1 αi??=0?yi?(w???(xi?)+b);1 0&lt;=αi?&lt;=C?yi(w???(xi)+b)=10&lt;=\alpha_{i}^{*}&lt;= C \Rightarrow y_i(w^{*} \bullet \phi(x_i) + b)=1 0<=αi??<=C?yi?(w???(xi?)+b)=1 αi?=C?yi(w???(xi)+b)≤1\alpha_{i}^{*}=C \Rightarrow y_i(w^{*} \bullet \phi(x_i) + b)\leq 1αi??=C?yi?(w???(xi?)+b)1
由于w?=∑j=1mαj?yj?(xj)w^{*} = \sum\limits_{j=1}^{m}\alpha_j^{*}y_j\phi(x_j)w?=j=1m?αj??yj??(xj?),我們令g(x)=w???(x)+b=∑j=1mαj?yjK(x,xj)+b?g(x) = w^{*} \bullet \phi(x) + b =\sum\limits_{j=1}^{m}\alpha_j^{*}y_jK(x, x_j)+ b^{*}g(x)=w???(x)+b=j=1m?αj??yj?K(x,xj?)+b?,則有: αi?=0?yig(xi)≥1\alpha_{i}^{*} = 0 \Rightarrow y_ig(x_i)\geq1 αi??=0?yi?g(xi?)1 0&lt;αi?&lt;C?yig(xi)=10 &lt; \alpha_{i}^{*}&lt; C \Rightarrow y_ig(x_i)=1 0<αi??<C?yi?g(xi?)=1 αi?=C?yig(xi)≤1\alpha_{i}^{*}=C \Rightarrow y_ig(x_i)\leq 1αi??=C?yi?g(xi?)1

SMO算法的基本思想

SMO算法是一種啟發(fā)式算法,其基本思路是:如果所有變量的解都滿足此最優(yōu)化問題的KKT條件(Karush-Kuhn-Tuckerconditions),那么這個最優(yōu)化問題的解就得到了。
整個SMO算法包括兩個部分:求解兩個變量二次規(guī)劃的解析方法***和***選擇變量的啟發(fā)式方法

求解兩個變量二次規(guī)劃的解析方法

子問題如下:


由于只有兩個變量 [α1\alpha_{1}α1?,α2\alpha_{2}α2?] ,約束可以用二維空間中的圖形表示(如圖所示)。

左圖:

右圖:

簡化理解:


沿著約束方向未經(jīng)剪輯時的解是:


經(jīng)剪輯后的解是:

變量的選擇方法

SMO算法在每個子問題中選擇兩個變量優(yōu)化,其中至少一個變量是違反KKT條件的。

1.第1個變量的選擇

SMO稱選擇第1個變量的過程為外層循環(huán)。外層循環(huán)在訓(xùn)練樣本中選取違反KKT條件最嚴重的樣本點,并將其對應(yīng)的變量作為第1個變量。具體地,檢驗訓(xùn)練樣本點支持向量機(xix_ixi?,yiy_iyi?)是否滿足KKT條件,即
αi?=0?yig(xi)≥1\alpha_{i}^{*} = 0 \Rightarrow y_ig(x_i)\geq1 αi??=0?yi?g(xi?)1 0&lt;αi?&lt;C?yig(xi)=10 &lt; \alpha_{i}^{*}&lt; C \Rightarrow y_ig(x_i)=1 0<αi??<C?yi?g(xi?)=1 αi?=C?yig(xi)≤1\alpha_{i}^{*}=C \Rightarrow y_ig(x_i)\leq 1αi??=C?yi?g(xi?)1
該檢驗是在支持向量機ξ\xiξ范圍內(nèi)進行的。在檢驗過程中,外層循環(huán)首先遍歷所有滿足條件0&lt;αi?&lt;C0 &lt; \alpha_{i}^{*}&lt; C0<αi??<C支持向量機的樣本點,即在間隔邊界上的支持向量點,檢驗它們是否滿足KKT條件。如果這些樣本點都滿足KKT條件,那么遍歷整個訓(xùn)練集,檢驗它們是否滿足KKT條件。
如何選擇違反KKT條件最嚴重的樣本點?

# 接下來需要選擇違反KKT條件最嚴重的那個alphas[i]# 滿足KKT條件的三種情況# 1.yi*f(i)>=1 且 alpha=0,樣本點落在最大間隔外(分類完全正確的那些樣本)# 2.yi*f(i)==1 且 alpha<C,樣本點剛好落在最大間隔邊界上# 3.yi*f(i)<=1 且 alpha==C,樣本點落在最大間隔內(nèi)部# 情況2,3中的樣本點也叫做支持向量# 違背KKT條件的三種情況(與上面相反)# 因為 y[i]*Ei = y[i]*f(i) - y[i]^2 = y[i]*f(i) - 1, 因此# 1.若yi*f(i)<0,則y[i]*f(i)<1,如果alpha<C,那么就違背KKT(alpha==C 才正確)# 2.若yi*f(i)>0,則y[i]*f(i)>1,如果alpha>0,那么就違背KKT(alpha==0才正確)# 3.若yi*f(i)==0,那么y[i]*f(i)==1,此時,仍滿足KKT條件,無需進行優(yōu)化

2.第2個變量的選擇

SMO稱選擇第2個變量的過程為內(nèi)層循環(huán)。假設(shè)在外層循環(huán)中已經(jīng)找到第1個變量α1\alpha_1α1?,現(xiàn)在要在內(nèi)層循環(huán)中找第2個變量α2\alpha_2α2?。第2個變量選擇的標準是希望能使α2\alpha_2α2?有足夠大的變化。

第二個變量α2new\alpha_2^{new}α2new?的選擇標準是讓|E1E_1E1??E2E_2E2?|有足夠大的變化。由于α1\alpha_1α1?定了的時候,E1E_1E1?也確定了,所以要想|E1E_1E1??E2E_2E2?|最大,只需要在E1E_1E1?為正時,選擇最小的EiE_iEi?作為E2E_2E2?, 在E1E_1E1?為負時,選擇最大的EiE_iEi?作為E2E_2E2?,可以將所有的EiE_iEi?保存下來加快迭代。

如果內(nèi)存循環(huán)找到的點不能讓目標函數(shù)有足夠的下降, 可以采用遍歷支持向量點來做α2\alpha_2α2?,直到目標函數(shù)有足夠的下降, 如果所有的支持向量做α2\alpha_2α2?都不能讓目標函數(shù)有足夠的下降,可以跳出循環(huán),重新選擇α1\alpha_1α1?.

3.計算閾值bbb和差值EiE_iEi?

在每次完成兩個變量的優(yōu)化之后,需要重新計算閾值b。當0&lt;α1new&lt;C0 &lt; \alpha_{1}^{new}&lt;C0<α1new?<C時,我們有 y1?∑i=1mαiyiKi1?b1=0y_1 - \sum\limits_{i=1}^{m}\alpha_iy_iK_{i1} -b_1 = 0 y1??i=1m?αi?yi?Ki1??b1?=0
于是新的b1newb_1^{new}b1new?為:b1new=y1?∑i=3mαiyiKi1?α1newy1K11?α2newy2K21b_1^{new} = y_1 - \sum\limits_{i=3}^{m}\alpha_iy_iK_{i1}- \alpha_{1}^{new}y_1K_{11} - \alpha_{2}^{new}y_2K_{21}b1new?=y1??i=3m?αi?yi?Ki1??α1new?y1?K11??α2new?y2?K21?
計算出E1E_1E1?為:E1=g(x1)?y1=∑i=3mαiyiKi1+α1oldy1K11+α2oldy2K21+bold?y1E_1 = g(x_1) - y_1 = \sum\limits_{i=3}^{m}\alpha_iy_iK_{i1} + \alpha_{1}^{old}y_1K_{11} + \alpha_{2}^{old}y_2K_{21} + b^{old} -y_1E1?=g(x1?)?y1?=i=3m?αi?yi?Ki1?+α1old?y1?K11?+α2old?y2?K21?+bold?y1?
可以看到上兩式都有y1?∑i=3mαiyiKi1y_1 - \sum\limits_{i=3}^{m}\alpha_iy_iK_{i1}y1??i=3m?αi?yi?Ki1?,因此可以將b1newb_1^{new}b1new?E1E_1E1?表示為:b1new=?E1?y1K11(α1new?α1old)?y2K21(α2new?α2old)+boldb_1^{new} = -E_1 -y_1K_{11}(\alpha_{1}^{new} - \alpha_{1}^{old}) -y_2K_{21}(\alpha_{2}^{new} - \alpha_{2}^{old}) + b^{old}b1new?=?E1??y1?K11?(α1new??α1old?)?y2?K21?(α2new??α2old?)+bold
同樣的,如果0&lt;α2new&lt;C0 &lt; \alpha_{2}^{new}&lt; C0<α2new?<C, 那么有:b2new=?E2?y1K12(α1new?α1old)?y2K22(α2new?α2old)+boldb_2^{new} = -E_2 -y_1K_{12}(\alpha_{1}^{new} - \alpha_{1}^{old}) -y_2K_{22}(\alpha_{2}^{new} - \alpha_{2}^{old}) + b^{old}b2new?=?E2??y1?K12?(α1new??α1old?)?y2?K22?(α2new??α2old?)+bold
最終的bnewb^{new}bnew為:bnew=b1new+b2new2b^{new} = \frac{b_1^{new} + b_2^{new}}{2}bnew=2b1new?+b2new??
得到了bnewb^{new}bnew我們需要更新EiE_iEi?:Ei=∑SyjαjK(xi,xj)+bnew?yiE_i = \sum\limits_{S}y_j\alpha_jK(x_i,x_j) + b^{new} -y_iEi?=S?yj?αj?K(xi?,xj?)+bnew?yi?
其中,S是所有支持向量xjx_jxj?的集合.

SMO實現(xiàn):

數(shù)據(jù)集:

https://pan.baidu.com/s/1_3OgMSvuUHiZAZLdL4bVUw

from numpy import * import matplotlib.pyplot as pltdef loadDataSet(fileName):dataMat = []labelMat = []fr = open(fileName)for line in fr.readlines():linArr = line.strip().split('\t')dataMat.append([float(linArr[0]), float(linArr[1])])labelMat.append(float(linArr[2]))return dataMat, labelMatdef kernelTrans(X, sampleX, kernelOp):"""計算K(train_x,x_i):param X:[n_samples, n_features] 保存訓(xùn)練樣本的矩陣:param sampleX: [1,n] 某一樣本矩陣:param kernelOp: 攜帶核信息的元組:參數(shù)一給定核的名稱;后面參數(shù)為核函數(shù)可能需要的可選參數(shù):return: K (numSamples,1)=shape(K)"""m = shape(X)[0] # 樣本數(shù)K = mat(zeros((m, 1)))if kernelOp[0] == 'linear': # 線性核K = X * sampleX.Telif kernelOp[0] == 'rbf': # 高斯核sigma = kernelOp[1]if sigma == 0: sigma = 1for i in range(m):deltaRow = X[i, :] - sampleXK[i] = exp(deltaRow * deltaRow.T / (-2.0 * sigma ** 2))else:raise NameError('Not support kernel type! You can use linear or rbf!')return Kclass SvmStruct:def __init__(self, dataMatIn, labelMat, C, toler, kernelOp):"""初始化所有參數(shù):param dataMatIn: 訓(xùn)練集矩陣:param labelMat: 訓(xùn)練集標簽矩陣:param C: 懲罰參數(shù):param toler: 誤差的容忍度:param kernelOp: 存儲核轉(zhuǎn)換所需要的參數(shù)信息"""self.train_x = dataMatInself.train_y = labelMatself.C = Cself.toler = tolerself.numSamples = shape(dataMatIn)[0] # 樣本數(shù)self.alphas = mat(zeros((self.numSamples, 1))) # 初始化待優(yōu)化的一組alphaself.b = 0self.errorCache = mat(zeros((self.numSamples, 2))) # 第1列為有效標志位(表示已經(jīng)計算),第2列為誤差值self.K = mat(zeros((self.numSamples, self.numSamples)))# 計算出訓(xùn)練集 train_x 與每個樣本X[i,:]的核函數(shù)轉(zhuǎn)換值,并按列存儲,那么共有 numSamples 列# 這樣提取存儲,方便查詢使用,避免重復(fù)性計算,提高計算效率for i in range(self.numSamples):self.K[:, i] = kernelTrans(self.train_x, self.train_x[i, :], kernelOp)def calcError(svm, k):"""計算第k個樣本的預(yù)測誤差:param k::return:"""# 不使用核函數(shù)的版本# fxk = float(multiply(svm.alphas, svm.train_y).T * (svm.train_x * svm.train_x[k, :].T)) + svm.bfxk = float(multiply(svm.alphas, svm.train_y).T * svm.K[:, k] + svm.b) # 使用核函數(shù)得出的預(yù)測值Ek = fxk - float(svm.train_y[k])return Ekdef selectJ(svm, i, Ei):"""尋找第二個待優(yōu)化的alpha,并具有最大步長:param i: 第一個alpha值的下標:param svm::param Ei:第一個alpha值對應(yīng)的Ei:return:"""maxK = 0maxStep = 0Ej = 0validEcacheList = nonzero(svm.errorCache[:, 0].A)[0] # 從誤差緩存矩陣中 得到記錄所有樣本有效標志位的列表(注:存的是索引)if (len(validEcacheList)) > 1: # 選擇具有最大步長的 jfor k in validEcacheList:if k == i:continueEk = calcError(svm, k)step = abs(Ei - Ek)if (step > maxStep): # 選擇 Ej 與 Ei 相差最大的那個 j,即步長最大maxK = kmaxStep = stepEj = Ekreturn maxK, Ejelse: # 第一次循環(huán)采用隨機選擇法l = list(range(svm.numSamples))# 排除掉已選的 iseq = l[:i] + l[i + 1:]j = random.choice(seq)Ej = calcError(svm, j)return j, Ejdef cliAlpha(alpha, L, H):"""控制alpha在L到H范圍內(nèi):param alpha: 待修正的alpha:param H: 上界:param L: 下界:return:"""if alpha > H:alpha = Hif alpha < L:alpha = Lreturn alphadef updateError(svm, k):"""第k個樣本的誤差存入緩存矩陣,再選擇第二個alpha值用到:param svm::param k: 樣本索引:return:"""Ek = calcError(svm, k)svm.errorCache[k] = [1, Ek]def innerL(svm, i):""":param i: 第一個alpha值的下標:param svm::return: 返回是否選出了一對 alpha 值"""Ei = calcError(svm, i) # 計算第一個alpha值對應(yīng)樣本的預(yù)測誤差# 接下來需要選擇違反KKT條件最嚴重的那個alphas[i]# 滿足KKT條件的三種情況# 1.yi*f(i)>=1 且 alpha=0,樣本點落在最大間隔外(分類完全正確的那些樣本)# 2.yi*f(i)==1 且 alpha<C,樣本點剛好落在最大間隔邊界上# 3.yi*f(i)<=1 且 alpha==C,樣本點落在最大間隔內(nèi)部# 情況2,3中的樣本點也叫做支持向量# 違背KKT條件的三種情況(與上面相反)# 因為 y[i]*Ei = y[i]*f(i) - y[i]^2 = y[i]*f(i) - 1, 因此# 1.若yi*f(i)<0,則y[i]*f(i)<1,如果alpha<C,那么就違背KKT(alpha==C 才正確)# 2.若yi*f(i)>0,則y[i]*f(i)>1,如果alpha>0,那么就違背KKT(alpha==0才正確)# 3.若yi*f(i)==0,那么y[i]*f(i)==1,此時,仍滿足KKT條件,無需進行優(yōu)化if ((svm.train_y[i] * Ei < -svm.toler) and (svm.alphas[i] < svm.C) or (svm.train_y[i] * Ei > svm.toler) and (svm.alphas[i] > 0)): # 選擇違反KKT條件最嚴重的alpha[i]j, Ej = selectJ(svm, i, Ei) # 選擇第二個alpha值的下標以及得到其對應(yīng)的樣本的預(yù)測誤差alphaIold = svm.alphas[i].copy() # 記錄更新前的alpha值alphaJold = svm.alphas[j].copy() # 記錄更新前的alpha值# 確定 alpha 值 的上下界if (svm.train_y[i] != svm.train_y[j]):L = max(0, alphaJold - alphaIold)H = min(svm.C, svm.C + alphaJold - alphaIold)else:L = max(0, alphaIold + alphaJold - svm.C)H = min(svm.C, alphaIold + alphaJold)if L == H: return 0# 不使用核函數(shù)版本# X_i = svm.train_x[i, :]# X_j = svm.train_x[j, :]# eta = 2.0 * X_i * X_j.T - X_i * X_i.T - X_j * X_j.T# 使用核函數(shù)版本eta = svm.K[i, i] + svm.K[j, j] - 2.0 * svm.K[i, j] # 計算eta=k_ii+k_jj-2*k_ijif eta <= 0: print("WARNING eta<=0");return 0svm.alphas[j] += svm.train_y[j] * (Ei - Ej) / eta # 計算出最優(yōu)的alpha_j,也就是第二個alpha 值svm.alphas[j] = cliAlpha(svm.alphas[j], L, H) # 得到修正范圍后的 alpha_jif abs(svm.alphas[j] - alphaJold) < 0.00001: # alpha_j 變化太小,直接返回updateError(svm, j)return 0svm.alphas[i] += svm.train_y[i] * svm.train_y[j] * (alphaJold - svm.alphas[j]) # 由 alpha_j 推出 alpha_iupdateError(svm, i) # 更新樣本 i 的預(yù)測值誤差# 不使用核函數(shù)版本# b1 = b - Ei - label_i * (alpha_i - alphaIold) * X_i * X_i.T - label_j * (alpha_j - alphaJold) * X_i * X_j.T# b2 = b - Ej - label_i * (alpha_i - alphaIold) * X_i * X_j.T - label_j * (alpha_j - alphaJold) * X_j * X_j.T# 使用核函數(shù)版本# 計算閾值b1 = - Ei - svm.train_y[i] * (svm.alphas[i] - alphaIold) * svm.K[i, i] - svm.train_y[j] * (svm.alphas[j] - alphaJold) * svm.K[i, j] + svm.bb2 = - Ej - svm.train_y[i] * (svm.alphas[i] - alphaIold) * svm.K[i, j] - svm.train_y[j] * (svm.alphas[j] - alphaJold) * svm.K[j, j] + svm.bif (0 < svm.alphas[i]) and (svm.alphas[i] < svm.C): # alpha_i 不在邊界上,b1有效svm.b = b1elif (0 < svm.alphas[j]) and (svm.alphas[j] < svm.C): # alpha_j 不在邊界上,b2有效svm.b = b2else: # alpha_j、alpha_j 都在邊界上,閾值取中點svm.b = (b1 + b2) / 2updateError(svm, j)updateError(svm, i)return 1 # 一對alphas值已改變else:return 0def smoP(dataSet, classLabels, C, toler, maxIter, KTup=('linear', 1.0)):svm = SvmStruct(mat(dataSet), mat(classLabels).T, C, toler, KTup)iter = 0entireSet = True # 是否遍歷所有alphaalphaPairsChanged = 0while (iter < maxIter) and ((alphaPairsChanged > 0) or (entireSet)):alphaPairsChanged = 0if entireSet: # 對整個訓(xùn)練集遍歷for i in range(svm.numSamples):alphaPairsChanged += innerL(svm, i)print('---iter:%d entire set, alpha pairs changed:%d' % (iter, alphaPairsChanged))else: # 對非邊界上的alpha遍歷(即約束在0<alpha<C內(nèi)的樣本點)nonBoundIs = nonzero((svm.alphas.A > 0) * (svm.alphas.A < svm.C))[0]for i in nonBoundIs:alphaPairsChanged += innerL(svm, i)print('---iter:%d non boundary, alpha pairs changed:%d' % (iter, alphaPairsChanged))iter += 1if entireSet:entireSet = Falseelif (alphaPairsChanged == 0):entireSet = Truereturn svmdef calcWs(alphas, dataArr, labelArr):"""計算W:param alphas: 大部分為0,非0的alphas對應(yīng)的樣本為支持向量:param dataArr::param classLabels::return:"""X = mat(dataArr)labelMat = mat(labelArr).Tm, n = shape(X)w = zeros((n, 1))for i in range(m): ## alphas[i]=0的無貢獻w += multiply(alphas[i] * labelMat[i], X[i, :].T)return wdef plotSVM():dataMat, labelMat = loadDataSet('testSet.txt')svm = smoP(dataMat, labelMat, 0.6, 0.001, 50)classified_pts = {'+1': [], '-1': []}for point, label in zip(dataMat, labelMat):if label == 1.0:classified_pts['+1'].append(point)else:classified_pts['-1'].append(point)fig = plt.figure()ax = fig.add_subplot(111)for label, pts in classified_pts.items():pts = array(pts)ax.scatter(pts[:, 0], pts[:, 1], label=label)supportVectorsIndex = nonzero(svm.alphas.A > 0)[0]for i in supportVectorsIndex:plt.plot(svm.train_x[i, 0], svm.train_x[i, 1], 'oy')w = calcWs(svm.alphas, dataMat, labelMat)x1 = min(array(dataMat)[:, 0])x2 = max(array(dataMat)[:, 0])a1, a2 = wy1, y2 = (-float(svm.b) - a1 * x1) / a2, (-float(svm.b) - a1 * x2) / a2ax.plot([x1, x2], [y1, y2])plt.show()plotSVM()def testSVMWithLinearKernel():dataArr, labelArr = loadDataSet('testSet.txt')svm = smoP(dataArr, labelArr, 0.6, 0.001, 50)dataMat = mat(dataArr)labelMat = mat(labelArr).TsvInd = nonzero(svm.alphas.A > 0)[0]sVs = dataMat[svInd]labelSv = labelMat[svInd]print("there are %d Support Vector" % shape(sVs)[0])m, n = shape(dataMat)errorCount = 0for i in range(m):kernelEval = kernelTrans(sVs, dataMat[i, :], ('linear', 1.0))predict = kernelEval.T * multiply(labelSv, svm.alphas[svInd]) + svm.bif sign(predict) != sign(labelArr[i]): errorCount += 1print("the training error rate is : %f" % (errorCount / m))# testSVMWithLinearKernel()# dataMat, train_y = loadDataSet('testSet.txt') # b, alphas = smoP(dataMat, train_y, 0.6, 0.001, 50) # ws = calcWs(alphas, dataMat, train_y) # errorCount = 0 # for i in range(shape(dataMat)[0]): # a = mat(dataMat)[i] * mat(ws) + b # if sign(a) != train_y[i]: # errorCount += 1 # print("the training error rate is : %f" % (errorCount / shape(dataMat)[0]))# print(a) # 預(yù)測的值 a>0 ==1 a<0 -1# print(train_y[0])def testRbf(k1=1.3):dataArr, labelArr = loadDataSet('testSetRBF.txt')svm = smoP(dataArr, labelArr, 200, 0.0001, 100, ('rbf', k1))dataMat = mat(dataArr)labelMat = mat(labelArr).TsvInd = nonzero(svm.alphas.A > 0)[0]sVs = dataMat[svInd]labelSv = labelMat[svInd]print("there are %d Support Vector" % shape(sVs)[0])m, n = shape(dataMat)errorCount = 0for i in range(m):kernelEval = kernelTrans(sVs, dataMat[i, :], ('rbf', k1))predict = kernelEval.T * multiply(labelSv, svm.alphas[svInd]) + svm.bif sign(predict) != sign(labelArr[i]): errorCount += 1 print("the training error rate is : %f" % (errorCount / m))

Reference:

https://blog.csdn.net/u013534680/article/details/80371680
http://www.hankcs.com/ml/support-vector-machine.html#h3-3

總結(jié)

以上是生活随笔為你收集整理的SVM 复盘总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。