但执行速度慢。Platt SMO算法中的外循环确定要优化的最佳alpha对。而简化版却会跳过这一部 分,首先在数据集上遍历每一个8也^ , 然后在剩下的3妙 3集合中随机选择另一个3妙 3’从而构 建alpha对。这里有一点相当重要,就是我们要同时改变两个3中1^ 。之所以这样做是因为我们有 一个约束条件:
[a , ■ label(,) = 0
由于改变一个邮^ 可能会导致该约束条件失效,因此我们总是同时改变两个3中 ^ 。
① John C. Platt, “Using Analytic QP and Sparseness to Speed Training of Support Vector Machines” \nAdvances in Neural Information Processing Systems 11,M. S. Kearns, S. A. Solla, D. A. Cohn, eds(MIT Press, 1999), 557~63.
6.3 S M O
高效优化算法95
96
第6
章 支 持 向 量 机6,3 S M O
高效优化算法97
98
第6
章 支 持 向 量 机需要退出^ ^循环的当前迭代过程。该过程对真实SMO算法进行了简化处理。如果& £1为0,那么 计算新的3 1 ? 1 ^鬥]就比较麻烦了,这里我们就不对此进行详细的介绍了。有需要的读者可以阅 读朽故的原文来了解更多的细节。现实 中 ,这种情况并不常发生,因此忽略这一部分通常也无伤 大雅 。于 是 ,可以计算出一个新的&均1 ^ [幻 ,然后利用程序清单6 - l中的辅助函数以及L与H值对 其进行调整。
然 后 ,就 是 需 要 检 查
31£^3[
」]
是 否 有 轻 微 改 变 。如 果 是 的 话 ,就退出化匸循环。然 后 ,31
卩匕3[1]
和319
匕3[
」]
同样进行改变,虽然改变的大小一样,但 是改变的方向正好相反(即如果 一个增 加 ,那么 另外 一个减少)€1
。在对3191^[1]
和31
口1^[
」]
进行优化之后,给这两个31
。匕3
值设置一个常数项b © o
最 后 ,在优化过程结束的同时,必须确保在合适的时机结束循环。如果程序执行到££^ 循 环 的 最 后 一 行 都 不 执 行
<^
址^
此 语 句 ,那 么 就 已 经 成 功 地 改 变 了 一 对&
中匕,同 时 可 以 增 加alphaPairsChanged
的值。在卩01^|
环 之 外 ,需要检査8
如1^
值 是否做了更新,如果有更新则将 丄七6 3 5
为0
后继续运行程序。只有在所有数据集上遍历maxIter
次 ,且不再发生任何3
丨?仏修改之 后 ,程序才会停止并退出^^116
循 环 。为了解实际效果,可以运行如下命令:
>>> b , a l p h a s = s v m M L i A . s m o S i m p l e (dataArr, labe l A r r , 0 . 6, 0.001, 40)
运行后输出类似如下结果:
i t e r a t i o n n u m b e r : 29 j n o t m o v i n g e n o u g h i t e r a t i o n n u m b e r : 30
i t e r : 30 i:17, p a i r s c h a n g e d 1 j n o t m o v i n g e n o u g h
i t e r a t i o n n u m b e r : 0 j n o t m o v i n g e n o u g h i t e r a t i o n n u m b e r : 1
上述运行过程需要几分钟才会收敛。一旦运行结束,我们可以对结果进行观察:
>>> b
m a t r i x ( [ [ - 3 . 8 4 0 6 4 4 1 3 ] ] )
我们可以直接观察&咕“ 矩阵本 身,但是其中的零元素太多。为了观察大于0的元素的数量,可以
输入如下命令: ,
>>> a l p h a s [alphas>0]
m a t r i x ( [[ 0 . 1 2 7 3 5 4 1 3 , 0 . 2 4 1 5 4 7 9 4 , 0 . 3 6 8 9 0 2 0 8 ] ] )
由 于
8^«)
算 法 的 随 机 性 ,读 者 运 行 后 所 得 到 的 结 果 可 能 会 与 上 述 结 果 不 同 。alphas [31
口1^3>0]
命 令 是 数 组 过 滤 (arrayfiltering)
的一个实例,而且它只对1^
通?7
类型 有 用 , 却并不适用于口>^0)1
中 的 正 则 表(regular list )0
如果输人3
如1 ^ > 0 ,
那么就会得到一个布尔数组,并且在不等式成立的情况下,其对应值为正确的。于 是 ,在将该布尔数组应用到原始的矩阵当中 时 ,就会得到一个灿
0
办 矩 阵 ,并且其中矩阵仅仅包含大于0
的值。为了得到支持向量的个数,输 人 :
6 . 4
利 用 完 整Platt SM O
算法加速优化99
>>> s h a p e ( a l p h a s [alphas>0])
为了解哪些数据点是支持向量,输 入 :
>>> f o r i in r a n g e (100) :
... if a l p h a s [i]> 0 . 0 : p r i n t d a t a A r r [ i ] ,labe l A r r [ i ]
得到的结果类似如下:
[ 4 . 6 5 8 1 9 1 0 0 0 0 0 0 0 0 0 4 , 3 . 507396] -1.0
[ 3 . 4 5 7 0 9 5 9 9 9 9 9 9 9 9 9 9 , - 0 . 0 8 2 2 1 5 9 9 9 9 9 9 9 9 9 9 9 7 ] -1.0 [ 6 . 0 8 0 5 7 3 0 0 0 0 0 0 0 0 0 2 , 0 . 4 1 8 8 8 5 9 9 9 9 9 9 9 9 9 9 8 ] 1.0
在原始数据集上对这些支持向量画圈之后的结果如图
6-4
所 示 。用 圆 圈 标 记 的 支 持 向 量
图
6 - 4
示例数据集上运行简化版8 ^ »
算法后得到的结果,包括画圈的支持向量与分隔超平面 利用前面的设置,我运行了10
次程序并取其平均时间。结 果 是 ,这个过程在一台性能较差的 笔记本上需要14.5
秒 。虽然结果看起来并不是太差,但是别忘了这只是一个仅有100
个点的小规 模数据集而已。在更大的数据集上,收敛时间会变得更长。在 下 一 节 中’
我们将通过构建完整3
厘0
算法来加快其运行速度。6 . 4 利用完整卩丨3 « 3 " 0 算法加速优化
在几百个点组成的小规模数据集上,简化版
S M O
算法的运行是没有什么问题的,但是在更大 的数据集上的运行速度就会变慢。刚才巳经讨论了简化版S M O
算 法 ,下面我们就讨论完整版的PlattSMO
算 法 。在这两个版本中,实现&1
沖3
的更改和代数运算的优化环节一模一样。在优化过 程 中 ,唯一的不同就是选择31?1^
的方式。完整版的Plat t S M O
算法应用了一些能够提速的启发方 法 。或许读者已经意识到,上一节的例子在执行时存在一定的时间提升空间。Platt 3
厘0
算法是通过一个外循环来选择第一个&4 ^
值 的 ,并且其选择过程会在两种方式之 间进行交替:一种方式是在所有数据集上进行单遍扫描,另一种方式则是在非边界3
化^中实 现单100
第6
章 支 持 向 量 机6 . 4
利 用 完 整 ?13« 8
\ « ) 算 法 加 速 优 化101
首 要 的 事 情 就 是 建 立 一 个 数 据 结 构 来 保 存 所 有 的 重 要 值 ,而 这 个 过 程 可 以 通 过 一 个 对 象 来 完 成 。这 里 使 用 对 象 的 目 的 并 不 是 为 了 面 向 对 象 的 编 程 ,而 只 是 作 为 一 个 数 据 结 构 来 使 用 对 象 。在 将 值 传 给 函 数 时 ,我 们 可 以 通 过 将 所 有 数 据 移 到 一 个 结 构 中 来 实 现 ,这 样 就 可 以 省 掉 手 工 输 人 的 麻 烦 了 。 而 此 时 ,数 据 就 可 以 通 过 一 个 对 象 来 进 行 传 递 。 实 际 上 , 当 完 成 其 实 现 时 ,可 以 很 容 易 通 过 ? 7 出011的 字 典 来 完 成 。 但 是 在 访 问 对 象 成 员 变 量 时 ,这 样 做 会 有 更 多 的 手 工 输 人 操 作 ,对 比 一 下 1 ^ 0 紀 6 ^ 乂和0 ^ 0 的 6 < ^ [ 1 ,]就 可 以 知 道 这 一 点 。为 达 到 这 个 目 的 ,需 要 构 建 一 个 仅 包 含 土1 ^ 七 方 法 的 0 ^ ^ 3 七1 ^ 比 _ 。 该 方 法 可 以 实 现 其 成 员 变 量 的 填 充 。 除 了 增 加 了 一 个 0 ^ 2 的 矩 阵 成 员 变 量 0 0 & 池 6 之 外 0 , 这 些 做 法 和 简 化 版 S M O — 模 一 样 。 6 0 3 比 6 的 第 一 列 给 出 的 是 6 0 3 比 6 是 否 有 效 的 标 志 位 , 而 第 二 列 给 出 的 是 实 际 的 £ 值 。