昨天介紹完SMO算法第四步,今天就要來寫這個方法在迭代中的限制,
基本上每次在計算完Ei之後就要看Ei的值有沒有超過每單位的y-->所以我們會設定一個可容選誤差ei
如果ei太大就要用之前講的SMO算法去更新ai使得Ei下降
所以程式如下:
#設定容許值
mis=0.001
#因為y為+1和-1
if (y[i]*Ei < -mis) or (y[i]*Ei > mis):
pass
並且設定如果aj和之前變化太小,就不更新
學習率小於等於0也不更新
L=H也不更新
所以程式會寫成
if K <= 0:
print("K<=0");
continue
if L==H:
print("L==H")
continue
if (abs(a[0][j] - a_j) < 0.00001):
print("aj變化太小")
continue
最後在設定迭代次數上限(這邊設定40),整個程式就會變成:
#合併資料
full_label_data=np.vstack((label1_data,label2_data))
#取出x特徵
full_label_data_x=np.mat(full_label_data[:,[0,1]])
#取出y特徵
y=np.array([full_label_data[i][2] for i in range(len(full_label_data))])
#初始a,b
a=np.zeros((1,20))
b=0
#設定a上界C
C=0.6
#設定容許值
mis=0.001
#設定最大上限
maxIter=40
#迭代次數
iter_num = 0
while (iter_num < maxIter):
#a被優化次數初始化
alphaPairsChanged = 0
#第一步:計算誤差Ei
for i in range(len(full_label_data)):
fXi = float(np.multiply(a,y)*(full_label_data_x*full_label_data_x[i,:].T)) + b
# print("第",i+1,"筆fXi:",fXi)
Ei = fXi - float(y[i])
# print("第",i+1,"筆Ei:",Ei)
#因為y為+1和-1
if (y[i]*Ei < -mis) or (y[i]*Ei > mis):
#第二步:計算上下界(每個i都要做)
j=select_J(i,len(full_label_data))
#保留舊的ai和aj
a_i = copy.deepcopy(a[0][i])
a_j = copy.deepcopy(a[0][j])
#不同邊
if (y[i] != y[j]):
L = max(0, a[0][j] - a[0][i])
H = min(C, C + a[0][j] - a[0][i])
#同邊
else:
L = max(0, a[0][j] + a[0][i] - C)
H = min(C, a[0][j] + a[0][i])
# print("第",i+1,"筆H:",H)
# print("第",i+1,"筆L:",L)
#第三步:計算K(學習率)和並算出限制aj
K = -2.0 * full_label_data_x[i,:]*full_label_data_x[j,:].T + full_label_data_x[i,:]*full_label_data_x[i,:].T + full_label_data_x[j,:]*full_label_data_x[j,:].T
# print("第",i+1,"筆K:",K)
if K <= 0:
print("K<=0");
continue
#算j點誤差
fXj = float(np.multiply(a,y)*(full_label_data_x*full_label_data_x[j,:].T)) + b
Ej = fXj - float(y[j])
# print("第",i+1,"筆Ej:",Ej)
#帶回公式
a[0][j] += y[j]*(Ei - Ej)/K
# print("第",i+1,"筆a:",a[0][j])
#限制範圍L和H
if a[0][j] > H:
a[0][j] = H
elif L > a[0][j]:
a[0][j] = L
if L==H:
print("L==H")
continue
# print("第",i+1,"筆經過限制a:",a[0][j])
if (abs(a[0][j] - a_j) < 0.00001):
print("aj變化太小")
continue
#步骤6:更新ai
a[0][i] += y[j]*y[i]*(a_j - a[0][j])
# print("第",i+1,"個ai:",a[0][i])
#更新b1和b2
b1 = b - Ei- y[i]*(a[0][i]-a_i)*full_label_data_x[i,:]*full_label_data_x[i,:].T - y[j]*(a[0][j]-a_j)*full_label_data_x[i,:]*full_label_data_x[j,:].T
b2 = b - Ej- y[i]*(a[0][i]-a_i)*full_label_data_x[i,:]*full_label_data_x[j,:].T - y[j]*(a[0][j]-a_j)*full_label_data_x[j,:]*full_label_data_x[j,:].T
# print("第",i+1,"個b1:",b1)
# print("第",i+1,"個b2:",b2)
#更新b,C為之前所說上界-->那時候帶入為0.6
if (0 < a[0][i]) and (C > a[0][i]):
b = b1
elif (0 < a[0][j]) and (C > a[0][j]):
b = b2
else:
b = (b1 + b2)/2
# print("第",i+1,"個b:",b)
alphaPairsChanged += 1
if (alphaPairsChanged == 0):
iter_num += 1
else:
iter_num = 0
print("迭代次數: %d" % iter_num)
print("最後b:",b)
print("最後a:",a)
最後求出a和b就會長:
最後b: [[-4.00488047]]
最後a: [[0. 0. 0. 0. 0.00710502 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.00416361
0. 0.0028869 ]]
好,今天支持SMO算法算出a,b算是完成了,明天就算出w和做繪圖
當男人正與狐狸對峙時,男孩還在不斷奔跑,跑著跑著,他突然看見一座士兵的雕像,雕像手裡拿著狙擊槍正瞄準地面上作出射擊的動作,男孩在經過時,突然雕像開始往地面射擊,男孩嚇到趴在地上發抖,終於槍聲停了,地面被射出了一個大洞,男孩驚魂未定地站起來,突然男孩聽到洞裡傳來跟之前一樣的歌聲,男孩在好奇心驅使下,往洞裡面看了過去
--|我需要你,這次我不會放手|-- MS.CM