原则
对他涉及的分类均最大化了最近点的距离——Margin
那么下面这个图应该是哪条线呢?
应该是下方的线
诚然,上方的线分割的更好,但是它犯了分类方面的错误
支持向量机总是将正确分类标签作为第一考虑要素,然后再对间隔进行最大化
如果我们不关注分类正确,那么会得到很多比这两个线更能使间隔最大化的线~
比方说在无穷远处~
所以对于支持向量机,你必须尽力保证分类正确。在此前提下,对间隔进行最大化
有异常的情况下
当有异常数据时,上述原则显然无法直接使用
此时可以尽力使用原则,把单个异常值标出来,svm可以实现这个功能(即忽略该异常值)
SVM编码
参考链接:http://scikit-learn.org/stable/modules/svm.html
线性SVM分类器得出非线性边界
圆
![这里写图片描述](https://img-blog.csdn.net/20171113111541438?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhuaW5nMTJM/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
明显在二维平面上是不可能得到一条线能够分割的,但是我们可以把输入的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 sys
from time import time
sys.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 labels
features_train, features_test, labels_train, labels_test = preprocess()
#########################################################
### your code goes here ###
from sklearn.svm import SVC
clf = 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_score
print(accuracy_score(labels_test,pre))
answer1=pre[10]
print(answer1)
answer1=pre[26]
print(answer1)
answer1=pre[50]
print(answer1)
过拟合
就是你可以用一条直线分开的,结果却是一条非常奇怪的线,虽然你成功的分类了,但是产生了非常复杂的结果,此时即为过拟合
控制过拟合(Overfitting)的手段——通过控制参数(C , Gamma , Kernal)
总结:支持向量机在具有复杂领域和明显分割边界的情况下,表现十分出色。
但是,在海量数据集中,他的表现不太好,因为在这种规模的数据集中,训练时间将是立方数。(速度慢)
另外,在噪音过多的情况下,效果也不太好。(可能会导致过拟合)
所以你需要考虑你的数据集和可用特征。