手工实现:SVM with Stochastic Gradient Descent
引入
之前的两篇我们一直在搞Naive Bayes Classifier,今天我们来换一个分类器试试。
SVM(support vector machine),支持向量机,虽让从名字上看不出来,但是它确实是个分类器。如果搜索引擎搜一下SVM的话,其实已经有很多资料很详细的介绍了SVM,但是正如之前两篇一样,本篇文章会着重于直观的解释相关知识点,并以解决实际问题为导向手工实现该算法。
实际问题
我们能否基于人口普查数据建立分类器,并对收入情况进行预测?
本次试验中,我们将使用UCI的 “Adult Data Set”。该数据集包含了被调查者的年龄、受教育程度、 工作岗位、性别等信息,并且标出了被调查者的收入分类(>50K,<=50K)。
在实现过程中,我们将在训练集上建立 SVM, 在测试集上评估模型的精度。
理论知识
SVM
直观认识
首先让我们举个栗子,直观认识一下SVM。
假设我们现在有这样一个训练集:
维度有 x ( 1 ) x_{(1)} x(1)、 x ( 2 ) x_{(2)} x(2)两个;类有正类、负类两个,正类由红色表示,负类由蓝色表示。
如果我们用一个SVM分类,它将这样做:
1、使用某个函数 h ( x ) h(x) h(x),图例中为 a T X + b a^TX+b aTX+b,对所有的点进行处理,将它们投到一个新的维度( γ \gamma γ)当中。 γ \gamma γ > 0 的点被预测为正类, γ \gamma γ < 0 的点被预测为负类。
2、通过一定方法找到步骤1中分的最好的函数(cost最低的),直观上来讲,这个函数对应的那个灰色矩形平面就是我们训练出来的模型。
3、若是要预测新的点的类别,只需要用同样函数处理新来的点(粉), γ \gamma γ > 0 则被预测为正类, γ \gamma γ < 0 则被预测为负类。
什么是分的好?
作为一只有追求的分类器就想要尽量分类分的好,但是究竟什么是分的好呢?
1、是不是只要都分对了就是分的好?
并不是~ 因为除了分对以外,我们还想要分的开。
如果我们只是以分对为标准,那么 l 1 l_1 l1 和 l 2 l_2 l2 就没有什么差别。
但是实际情况并非如此。如果我们在训练集上分的不够开,那么将来就很有可能出现像紫点这样的情况。
所以我们在训练时就要考虑尽量分开这件事,即:在交线附近划一个区域,如果有离得太近的点( e 1 e_1 e1)存在,模型也要付出一丢丢代价。(当然如果本身都已经分错了的话,代价就会更高,而且错的越离谱代价越大(离分界越远,代价越大))
体现在数学上,就是我们使用 Hinge Loss 作为 cost function。在这个例子中就是:
C ( y , γ ) = m a x ( 0 , 1 − y γ ) C(y, \gamma) = max(0, 1-y \gamma) C(y,γ)=max(0,1−yγ)
其中ÿ