iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
AI & Data

數據分析方法研究和理解演算法系列 第 15

DAY15支持向量機演算法(續四)

  • 分享至 

  • xImage
  •  

昨天介紹完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

上一篇
DAY14支持向量機演算法(續三)
下一篇
DAY16支持向量機演算法(續五)
系列文
數據分析方法研究和理解演算法30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言