分类问题第二弹来袭:支持向量机(Support Vector Machine)

Posted 炸猪排的机器学习入门

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分类问题第二弹来袭:支持向量机(Support Vector Machine)相关的知识,希望对你有一定的参考价值。

大家记不记得上一期炸猪排演示过用逻辑回归(Logistic Regression)来解决分类问题,然后提出有没有其他方法来对事物进行分类,那么今天就要给大家带来一个解决分类问题的秘密武器:支持向量机(Support Vector Machine)。


“支持向量机”是什么?

支持向量机(简称SVM)是在分类与回归问题中分析数据的监督式学习模型与相关的学习算法。给定一组训练实例,每个训练实例被标记为属于两个类别中的一个或另一个,SVM训练算法创建一个将新的实例分配给两个类别之一的模型,使其成为非概率二元线性分类器。如下图所示,SVM模型是将实例表示为空间中的点,这样映射就使得两种类别的实例被尽可能宽的间隔的分隔开,也就是说对每个类别最近的实例距离最远。下图中黑色的线可以将两种不同类的实例被尽可能宽的间隔分开,而灰色的线并不是最优解。然后,将新的实例映射到同一空间,并基于它们落在间隔的哪一侧来预测所属类别。

支持向量机应用实例

首先,我们要做的第一件事就是看一个简单的二维数据集如何用线性支持向量机(SVM)进行分类,线性支持向量机(SVM)是如何通过改变参数C值来提高分类精确度。


调用sklearn包中的SVM,

from sklearn import svm

先试一下C=1,看看会出现什么结果。

svc = svm.LinearSVC(C=1, loss='hinge', max_iter=1000)

svc.fit(data[['X1', 'X2']], data['y']) svc.score(data[['X1', 'X2']], data['y'])

大家可以测试一下以上代码,炸猪排跑出来的结果是0.98,并不是完全正确分类。那么,我们试着改变C的值,看看能不能达到100%分类正确。注意,参数C的值越大越容易出现“过拟合”现象,反之越容易“欠拟合”现象。

svc2 = svm.LinearSVC(C=100, loss='hinge', max_iter=1000) 

svc2.fit(data[['X1', 'X2']], data['y']) svc2.score(data[['X1', 'X2']], data['y']) data['SVM 1 Confidence'] = svc.decision_function(data[['X1', 'X2']])

这下我们可以看到结果为1 了,这样我们就对上图有明显边界的数据进行了二元分类。


支持向量机处理文本信息

除了普通的二元线性分类,支持向量机还经常应用于文本和图像信息分类上,尤其是处理自然语言,例如区分垃圾邮件和非垃圾邮件。在处理自然语言时,我们一般选择单词的出现频率或者单词是否出现来作为分类的特征值,这些特征值用向量来表示,这样我们就可以把文本转化为数据了。

接下来,我们来看一下如何用SVM构建垃圾邮件过滤器。 

我们首先要对邮件文本进行预处理(即将单词映射到dictionary中的一个ID,html删除,词干化,规范化等),以便将数据转换为适合SVM处理的格式。这些预处理步骤就不重现了,而是直接跳到机器学习任务,包括从预处理的列车中构建分类器,并将垃圾邮件和非垃圾邮件组成的测试数据集转换为单词发送向量。

spam_train = loadmat('C:/machine learning/ex6/data/spamTrain.mat')  

spam_test = loadmat('C:/machine learning/ex6/data/spamTest.mat')

spam_train  

X = spam_train['X']  

Xtest = spam_test['Xtest']  

y = spam_train['y'].ravel()  

ytest = spam_test['ytest'].ravel()

X.shape, y.shape, Xtest.shape, ytest.shape 

每个文档已被转换为与1,899个词汇相对应的1,899个词汇的向量。这些值是二进制的,表示文档中是否存在该单词。在这一点上,训练和评估只是用于拟合分类测试的。

最后我们来测试一下该筛选器的精确度,可以跑一下以下代码。

svc = svm.SVC()  

svc.fit(X, y)  

print('Test accuracy = {0}%'.format(np.round(svc.score(Xtest, ytest) * 100, 2)))


看到这里,大家有没有发现支持向量机的一些局限性呢,比如使用前必须对数据进行标记,每次只能进行二元分类(如果你要使用SVM处理分为4类的分类问题,需要使用one-vs-all策略训练4次 ,每次把一个类当成正类,其他的类当作负类,然后学习出4个模型,对新数据取函数值最大的那个类作为预测类别,是不是听起来就很麻烦),只能分类线性可分的数据等。那么对于没有标记的数据怎么分类呢,想把更方便地把数据分成N多类怎么办呢,之后炸猪排会慢慢更新~~~


炸猪排

以上是关于分类问题第二弹来袭:支持向量机(Support Vector Machine)的主要内容,如果未能解决你的问题,请参考以下文章

机器学习之支持向量机(Support Vector Machine)(更新中...)

支持向量机(SVM:support vector machine)

R构建径向核支持向量机分类器实战代码(Radial kernel Support Vector Classifier)

应用支持向量机 (Support Vector Machine) 做垃圾邮件分类

支持向量机

吐血整理:C++编程语言资源汇总丨第二弹