摘要: | 本文介绍了svm的一种online learning算法pegasos,并基于pegasoso算法实现了一个数字手写识别脚本。 |
本文参考了博文Online Learning in Clojure和论文Pegasos: Primal Estimated sub-GrAdient SOlver for SVM(PDF)
online learning
Online learning的算法结构是非常简单的,下面的描述是监督的online learning算法框架,其中有经验损失函数$L$,样本流$S$,样本的格式为$(x,y)$:
Initialise a starting model w
While there are more examples in S
Get the next feature vector x
Predict the label y' for x using the model w
Get the true label y for x and incur a penaly L(y,y')
Update the model w if y ≠ y'
一般来是,训练出来的模型都是一个与样本相同维度的向量。对应二分的分类器,往往涉及到的是计算内积$\langle w,x \rangle$,模型的更新是沿着损失函数的梯度下降方向的。
Pegasos
论文Pegasos: Primal Estimated sub-GrAdient SOlver for SVM是一种svm的online learning算法。
首先来看svm的经验合页损失函数:
上面式子中,$k$是训练集$S$的大小,$h()$是the hinge loss(合页损失函数),$\langle w, x\rangle$表示$w,x$的内积,$\lambda$是正则化项。
在《统计学习方法》这本书的7.2.4证明了合页损失函数与引入松弛变量后的损失函数是等价的,并证明了$\lambda$与惩罚系数$C$是成反比的。引入松弛变量后的损失函数为:
训练过程中,如果遇到了一个预测错误的样本$(x,y)$, 对模型的更新方法如下:
其中$t$表示已经训练过的样本个数,$ {w_{t + \frac{1}{2}}}$表示训练过$t$个的样本后的模型,${w_{t + \frac{1}{2} }}$ 表示新模型。 根据pegasos算法,新模型的$l_2$范数如果超出了以 $\frac{1}{ {\sqrt \lambda } }$ 为半径的超球面,那么需要将新模型投射到这个超球面上。即:
为什么需要讲新的模型投射到以$\frac{1}{ {\sqrt \lambda } }$为半径的超球面上呢?论文证明了svm的最优解是在下面这个集合中的:
而且在pegasos算法的推导,以及模型初始化$w$的时候,都使用了条件
由上面模型的更新公式可以简单分析一下正则化参数$\lambda$的作用,它决定了训练过程中,后面出现的预测错误的样本,对应模型的修正程度。$\lambda$越大,修正程度越小,$\lambda$越小,修正程度越大。同时$\lambda$与惩罚系数$C$是成反比的,所以也可理解为,在训练过称中,出现预测错误样本时,对模型的惩罚程度。$\lambda$越大,惩罚越小,$\lambda$越小,惩罚越大。
Pegasos的算法描述在论文”Pegasos: Primal Estimated sub-GrAdient SOlver for SVM”也是给出了的,可以参考。
但实际上pegasos是一个线性的svm,而且还是一个没有bias的svm,训练出来的线性函数是$y=\langle w,x \rangle$,在上面的论文中的Extensions小节中也讲到了,目前pegasos还没有证明可应用于线性模型$y=\langle w,x \rangle + b$或者是非线性svm模型。
Pegasos的实现例子
前面的博客基于SVM的手写数字识别,实现了一个基于SMO算法的svm,今天就来基于Pegasos实现数字手写识别。svm用于多分类,还是一对多的方式,手写数据还是来自“Machine Learning in Action”的第二章的数据。下面是实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
|
训练出来的模型测试结果如下:
right= 849
wrong= 46
can_not_classify= 72
total= 946
一共有946个测试样本,其中46个分类错误,72个没有找到分类,849个正确分类,正确分类率89.7%。$\lambda$取值为0.5。我也没有仔细调整$\lambda$的取值,不过看来结果还是慢不错的。但比起SMO算法实现的svm效果要差一些。但是pegasos的优势是快啊,同样的1934个训练样本,基于SMO的svm,花了3、4个小时训练,而pegasos算法只用了30多秒,逆天了。
实现例子的代码和数据可以在github上下载。pegasos有两个版本,pegasos2.py是pegasos.py的升级版,用了numpy库,使得代码更精简好看,同时运行效率更高。这个目录下还包含了论文的pdf文档Pegasos.pdf。
PS:发现numpy和scipy、matplotlib真是好东西啊,python数学运算离不开。另外发现了一个讲numpy/scipy文档翻译为中文的网站用Python做科学计算,好东西啊。
还发现了一个和机器学习相关的网站http://hunch.net/,有很不多不错的学术方面的东西。