標籤:啟發學習法 密碼 讀取資料 更新 baidu 概述 class 位置 二分
一.svm概述
svm是一種二分類模型,學習策略是通過間隔最大化來實現分類的目的,最終轉化為了凸二次規劃求解,即:
的確我們可以單純的通過求解凸二次規劃問題來獲得答案,但是當訓練樣本量很大時,這些演算法就會變的低效,從上面的公式就可以直觀看出,有多少範例就有多少乘子,如何高效求解拉格朗日乘子成為了關鍵——smo。
瀏覽了很多博文總結一下具體的求解過程(smo):
1.尋找違背KKT條件的,即:
其中:
2.尋找第二個乘子,通過:max|E1-E2|
3.求解約束前的,公式為:
其中,,Ei=f(xi)-yi
4.對進行約束:
5.通過求解:
6.對b的更新
7.啟發學習法迭代具體方法:後續補充
二.python實現
#利用svm求解羅吉斯迴歸,然後畫圖(詳細版)import pandas as pdimport numpy as npimport matplotlib.pyplot as plt#讀取資料traindata=pd.read_csv("E:\\caffe\\study\\3_data.csv")traindata=traindata.iloc[0:100,:]#準備函數def ui(No,traindata,alpha,b):#求ui a=0 for i in range(len(traindata)): a=a+alpha[i]*traindata.iloc[i,2]*(traindata.iloc[i,0]*traindata.iloc[No,0]+traindata.iloc[i,1]*traindata.iloc[No,0]) a=a+b return adef Ei(No,traindata,alpha,b):#求Ei=ui-yi a=ui(No,traindata,alpha,b)-traindata.iloc[No,2] return adef alpha2(i,traindata,alpha,b):#找第二個alpha2在alpha向量中的位置,通過max|Ei-Ej| ei=Ei(i,traindata,alpha,b) a=0 c=0 for j in range(len(traindata)): ej=Ei(j,traindata,alpha,b) bi=abs(ei-ej) if bi>a: a=bi c=j return cdef eta(traindata,i,j):#求分母eta a=traindata.iloc[i,0]**2+traindata.iloc[i,1]**2+traindata.iloc[j,0]**2+traindata.iloc[j,1]**2-2*(traindata.iloc[i,0]*traindata.iloc[j,0]+traindata.iloc[i,1]*traindata.iloc[j,1]) return adef alpha2new(traindata, i,j,alpha,b):#求alpha2new,這裡直接做約束 a=alpha[j]+traindata.iloc[j,2]*(Ei(i,traindata,alpha,b)-Ei(j,traindata,alpha,b))/eta(traindata,i,j) if traindata.iloc[i,2]==traindata.iloc[j,2]: L=0 H=alpha[i]+alpha[j] if a>H: return H elif a<L: return L else: return a else: L=np.array([0,alpha[j]-alpha[i]]).max() if a<L: return L else: return adef alpha1new(traindata, i,j,alpha,b):#把alpha2new帶進去求alpha1new a=alpha[i]+traindata.iloc[i,2]*traindata.iloc[j,2]*(alpha[j]-alpha2new(traindata, i,j,alpha,b)) return adef bnew(traindata, i,j,alpha,b):#更新b ei=Ei(i,traindata,alpha,b) ej=Ei(j,traindata,alpha,b) yi=traindata.iloc[i,2] yj=traindata.iloc[j,2] alphai=alpha1new(traindata, i, j, alpha, b) alphaj=alpha2new(traindata, i,j,alpha,b) b1=b-ei-yi*(alphai-alpha[i])*(traindata.iloc[i,0]**2+traindata.iloc[i,1]**2)-yj*(alphaj-alpha[j])*(traindata.iloc[i,0]*traindata.iloc[j,0]+traindata.iloc[i,1]*traindata.iloc[j,1]) b2=b-ej-yi*(alphai-alpha[i])*(traindata.iloc[i,0]*traindata.iloc[j,0]+traindata.iloc[i,1]*traindata.iloc[j,1])-yj*(alphaj-alpha[j])*(traindata.iloc[j,0]**2+traindata.iloc[j,1]**2) if alphai>0: return b1 elif alphaj>0: return b2 else: return (b1+b2)/2#上面的所有函數只需要載入一下即可,重點在下面的實際運行alpha = np.zeros(len(traindata)) # 初始化alpha向量,零向量,長度為資料的長度alphav = alpha.copy()#alphav相當於經過一次更新後的alpha向量,目的在於下面啟動並執行時候會和更新前的alpha做比較b = 0 # 初始化b為0for i in range(len(alpha)): # 對所有違反kkt的alpha做更新,最後輸出alpha為更新後的alpha,中間的b也是更新好的 if (alpha[i]==0 and traindata.iloc[i,2]*ui(i,traindata,alpha,b)>=1)+(alpha[i]>0 and traindata.iloc[i,2]*ui(i,traindata,alpha,b)<=1)==0: j = alpha2(i, traindata, alpha, b) t = alpha2new(traindata, i, j, alpha, b) if t >= 0: alphav[j] = t alphav[i] = alpha1new(traindata, i, j, alpha, b) if alphav[i]!=alpha[i]: b = bnew(traindata, i, j, alpha, b) alpha = alphav#下面是用來臨時檢驗alpha和b的結果是否正確,方法是計算出w,初始化一組x,將w,b帶入計算y,看y的結果是否合理,可以和未經處理資料作圖對比 w=np.zeros(2)#初始化w for i in range(len(alpha)): w=w+alpha[i]*traindata.iloc[i,2]*np.array(traindata.iloc[i,:2]) w=list(w) x=[1,10]#初始化x y=[((-1)*b-w[0]*plot_x[0])/w[1],(b-w[0]*plot_x[1])/w[1]]#計算y
附未經處理資料:連結:http://pan.baidu.com/s/1miT3Dzi 密碼:cipe
svm+python實現