完整SMO算法外循环,与smoSimple有些类似,但这里的循环退出条件更多一些 Args: dataMatIn 数据集 classLabels 类别标签 C 松弛变量(常量值),允许有些数据点可以处于分隔面的错误一侧。 控制最大化间隔和保证大部分的函数间隔小于1.0这两个目标的权重。 可以通过调节该参数达到不同的结果。 toler 容错率 maxIter 退出前最大的循环次数 kTup 包含核函数信息的元组
(dataMatIn, classLabels, C, toler, maxIter, kTup=('lin', 0))
| 295 | |
| 296 | |
| 297 | def smoP(dataMatIn, classLabels, C, toler, maxIter, kTup=('lin', 0)): |
| 298 | """ |
| 299 | 完整SMO算法外循环,与smoSimple有些类似,但这里的循环退出条件更多一些 |
| 300 | Args: |
| 301 | dataMatIn 数据集 |
| 302 | classLabels 类别标签 |
| 303 | C 松弛变量(常量值),允许有些数据点可以处于分隔面的错误一侧。 |
| 304 | 控制最大化间隔和保证大部分的函数间隔小于1.0这两个目标的权重。 |
| 305 | 可以通过调节该参数达到不同的结果。 |
| 306 | toler 容错率 |
| 307 | maxIter 退出前最大的循环次数 |
| 308 | kTup 包含核函数信息的元组 |
| 309 | Returns: |
| 310 | b 模型的常量值 |
| 311 | alphas 拉格朗日乘子 |
| 312 | """ |
| 313 | |
| 314 | # 创建一个 optStruct 对象 |
| 315 | oS = optStruct(mat(dataMatIn), mat(classLabels).transpose(), C, toler, kTup) |
| 316 | iter = 0 |
| 317 | entireSet = True |
| 318 | alphaPairsChanged = 0 |
| 319 | |
| 320 | # 循环遍历:循环maxIter次 并且 (alphaPairsChanged存在可以改变 or 所有行遍历一遍) |
| 321 | while (iter < maxIter) and ((alphaPairsChanged > 0) or (entireSet)): |
| 322 | alphaPairsChanged = 0 |
| 323 | |
| 324 | # 当entireSet=true or 非边界alpha对没有了;就开始寻找 alpha对,然后决定是否要进行else。 |
| 325 | if entireSet: |
| 326 | # 在数据集上遍历所有可能的alpha |
| 327 | for i in range(oS.m): |
| 328 | # 是否存在alpha对,存在就+1 |
| 329 | alphaPairsChanged += innerL(i, oS) |
| 330 | # print("fullSet, iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged)) |
| 331 | iter += 1 |
| 332 | |
| 333 | # 对已存在 alpha对,选出非边界的alpha值,进行优化。 |
| 334 | else: |
| 335 | # 遍历所有的非边界alpha值,也就是不在边界0或C上的值。 |
| 336 | nonBoundIs = nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0] |
| 337 | for i in nonBoundIs: |
| 338 | alphaPairsChanged += innerL(i, oS) |
| 339 | # print("non-bound, iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged)) |
| 340 | iter += 1 |
| 341 | |
| 342 | # 如果找到alpha对,就优化非边界alpha值,否则,就重新进行寻找,如果寻找一遍 遍历所有的行还是没找到,就退出循环。 |
| 343 | if entireSet: |
| 344 | entireSet = False # toggle entire set loop |
| 345 | elif (alphaPairsChanged == 0): |
| 346 | entireSet = True |
| 347 | print("iteration number: %d" % iter) |
| 348 | return oS.b, oS.alphas |
| 349 | |
| 350 | |
| 351 | def calcWs(alphas, dataArr, classLabels): |
no test coverage detected