MCPcopy Index your code
hub / github.com/Dod-o/Statistical-Learning-Method_Code / getAlphaJ

Method getAlphaJ

SVM/SVM.py:188–242  ·  view source on GitHub ↗

SMO中选择第二个变量 :param E1: 第一个变量的E1 :param i: 第一个变量α的下标 :return: E2,α2的下标

(self, E1, i)

Source from the content-addressed store, hash-verified

186 return gxi - self.trainLabelMat[i]
187
188 def getAlphaJ(self, E1, i):
189 '''
190 SMO中选择第二个变量
191 :param E1: 第一个变量的E1
192 :param i: 第一个变量α的下标
193 :return: E2,α2的下标
194 '''
195 #初始化E2
196 E2 = 0
197 #初始化|E1-E2|为-1
198 maxE1_E2 = -1
199 #初始化第二个变量的下标
200 maxIndex = -1
201
202 #这一步是一个优化性的算法
203 #实际上书上算法中初始时每一个Ei应当都为-yi(因为g(xi)由于初始α为0,必然为0)
204 #然后每次按照书中第二步去计算不同的E2来使得|E1-E2|最大,但是时间耗费太长了
205 #作者最初是全部按照书中缩写,但是本函数在需要3秒左右,所以进行了一些优化措施
206 #--------------------------------------------------
207 #在Ei的初始化中,由于所有α为0,所以一开始是设置Ei初始值为-yi。这里修改为与α
208 #一致,初始状态所有Ei为0,在运行过程中再逐步更新
209 #因此在挑选第二个变量时,只考虑更新过Ei的变量,但是存在问题
210 #1.当程序刚开始运行时,所有Ei都是0,那挑谁呢?
211 # 当程序检测到并没有Ei为非0时,将会使用随机函数随机挑选一个
212 #2.怎么保证能和书中的方法保持一样的有效性呢?
213 # 在挑选第一个变量时是有一个大循环的,它能保证遍历到每一个xi,并更新xi的值,
214 #在程序运行后期后其实绝大部分Ei都已经更新完毕了。下方优化算法只不过是在程序运行
215 #的前半程进行了时间的加速,在程序后期其实与未优化的情况无异
216 #------------------------------------------------------
217
218 #获得Ei非0的对应索引组成的列表,列表内容为非0Ei的下标i
219 nozeroE = [i for i, Ei in enumerate(self.E) if Ei != 0]
220 #对每个非零Ei的下标i进行遍历
221 for j in nozeroE:
222 #计算E2
223 E2_tmp = self.calcEi(j)
224 #如果|E1-E2|大于目前最大值
225 if math.fabs(E1 - E2_tmp) > maxE1_E2:
226 #更新最大值
227 maxE1_E2 = math.fabs(E1 - E2_tmp)
228 #更新最大值E2
229 E2 = E2_tmp
230 #更新最大值E2的索引j
231 maxIndex = j
232 #如果列表中没有非0元素了(对应程序最开始运行时的情况)
233 if maxIndex == -1:
234 maxIndex = i
235 while maxIndex == i:
236 #获得随机数,如果随机数与第一个变量的下标i一致则重新随机
237 maxIndex = int(random.uniform(0, self.m))
238 #获得E2
239 E2 = self.calcEi(maxIndex)
240
241 #返回第二个变量的E2值以及其索引
242 return E2, maxIndex
243
244 def train(self, iter = 100):
245 #iterStep:迭代次数,超过设置次数还未收敛则强制停止

Callers 1

trainMethod · 0.95

Calls 1

calcEiMethod · 0.95

Tested by

no test coverage detected