Udacity机器学习入门笔记——支持向量机(SVM)

来源:互联网 发布:学编程的游戏 编辑:程序博客网 时间:2024/05/21 11:57

原则

对他涉及的分类均最大化了最近点的距离——Margin

这里写图片描述

那么下面这个图应该是哪条线呢?
这里写图片描述
应该是下方的线
诚然,上方的线分割的更好,但是它犯了分类方面的错误
支持向量机总是将正确分类标签作为第一考虑要素,然后再对间隔进行最大化
如果我们不关注分类正确,那么会得到很多比这两个线更能使间隔最大化的线~
比方说在无穷远处~
所以对于支持向量机,你必须尽力保证分类正确。在此前提下,对间隔进行最大化

有异常的情况下

当有异常数据时,上述原则显然无法直接使用
这里写图片描述

此时可以尽力使用原则,把单个异常值标出来,svm可以实现这个功能(即忽略该异常值)
这里写图片描述

SVM编码

参考链接:http://scikit-learn.org/stable/modules/svm.html

线性SVM分类器得出非线性边界


这里写图片描述

明显在二维平面上是不可能得到一条线能够分割的,但是我们可以把输入的features从2个变成3个
这里写图片描述

我们令z为x、y的平方和,重新做个图
这里写图片描述
可以看到,在新的图上,又是线性可分的了
z其实就是原图上,圆点到红叉和蓝圈的距离~

这里的实质就是:使用一个曲线(其实就是新的平面)来划分
例如:
这里写图片描述

非圆

在这种情况下,你应该怎么选择一个新属性来进行分割呢
这里写图片描述

明显是|x|
此时会变成酱紫~
这里写图片描述
这就很易于划分了,那么换到原图中就是酱紫~
这里写图片描述

综上可得:
添加一个新的非线性特征,即可使支持向量机把红叉和蓝圈线性分割开来

那难道我们要写一大堆的新特征来实现这一点吗?

不用,支持向量机(SVM)中有个叫做核技巧的东西~

核技巧

获取低纬度输入空间或特征空间,并将其映射到极高维度空间的函数
这样,过去不可线分的问题,就变成了可分离问题
这里写图片描述

使用sklearn.svm.svc来拟定模型
链接:http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html

C 的作用是什么?一个更大的 C 会让边界更平滑还是得到更多正确的训练点?
(答案:更多正确的训练点)

有时训练集过大会使训练时间非常长,此时我们可以通过缩小训练集的方式来加快训练速度。
在训练分类器前加上这两句代码,可使训练集变为原本的1%:

features_train = features_train[:len(features_train)/100] labels_train = labels_train[:len(labels_train)/100] 

还可以预测第X个元素是属于1还是0的,此时不需要使用全部训练集
使用answer=pre[10]即可

全部代码:

import sysfrom time import timesys.path.append("../tools/")from email_preprocess import preprocess### features_train and features_test are the features for the training### and testing datasets, respectively### labels_train and labels_test are the corresponding item labelsfeatures_train, features_test, labels_train, labels_test = preprocess()############################################################ your code goes here ###from sklearn.svm import SVCclf = SVC(C=10000,kernel='rbf')features_train = features_train[:len(features_train)/100] labels_train = labels_train[:len(labels_train)/100] clf.fit(features_train,labels_train)pre = clf.predict(features_test)from sklearn.metrics import accuracy_scoreprint(accuracy_score(labels_test,pre))answer1=pre[10] print(answer1)answer1=pre[26] print(answer1)answer1=pre[50] print(answer1)

过拟合

就是你可以用一条直线分开的,结果却是一条非常奇怪的线,虽然你成功的分类了,但是产生了非常复杂的结果,此时即为过拟合
这里写图片描述

控制过拟合(Overfitting)的手段——通过控制参数(C , Gamma , Kernal)

总结:支持向量机在具有复杂领域和明显分割边界的情况下,表现十分出色。
但是,在海量数据集中,他的表现不太好,因为在这种规模的数据集中,训练时间将是立方数。(速度慢)
另外,在噪音过多的情况下,效果也不太好。(可能会导致过拟合)

所以你需要考虑你的数据集和可用特征。