小强学AI

小强学AI之 - 3支持向量机(support vector m

2017-06-02  本文已影响69人  Eric_AIPO

前记

上一篇中,我们了解了朴素贝叶斯。现在知道了,朴素贝叶斯是监督学习的一种算法。
朴素贝叶斯特殊的一点在于,这种算法非常适合文本分类。在处理文本时,常见的做法是将每个单词看作一个特征,这样就会有大量的特征。朴素贝叶斯假设各个特征之间独立的,并且算法又相对简单,使得它在文本分类应用中发挥作用。

支持向量机SVMs(support vector machines)

另一种监督分类算法支持向量机SVMs(support vector machines)。

SVMs出现的时间不久,由Vadimir Vaplik(俄罗斯人)提出。
假设我们有一些两种不同类型的数据。支持向量机就是在两类数据之间寻找分隔线(通常称之为超平面)的一种算法。

概念
margin - maximizes distance to nearest point
区分两个类的分隔线与两个类的最近点的距离。最大化这个距离,就可以提高分类的稳健性。

SVM的内部原理也是最大限度的提升结果的稳健性。
SVM总是首先考虑分类正确性,然后才考虑对间隔最大化。

异常值响应
对于异常值,SVM原则是尽量找到决策面,并允许单个异常值在决策面的另一侧。
实际上 SVM对于异常值非常健壮。在某种程度上在找出最大间隔和忽略异常值之间做了均衡 。
我们也可以通过修改SVM的参数,决定了它如何检测新的异常值。

用法
同贝叶斯差不多.

  1. 导入
    from sklearn import SVM
  2. 创建分类器
    svm.SVC()
  3. 训练(拟合)
    fit
  4. 分类
    predict

函数原型:

class sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape=None, random_state=None)[source]

各参数解释如下:

1. 核函数

SVM可以生成非常复杂的决策边界。
SVM是基于线性分隔的分类器,但由于SVM会创建新特征,使得SVM可以学习非线性决策面。
这些新特性就是借助创建SVM时传入的参数kernel来决定的。

定义

可以将低维度的输出空间(特征空间)映射到高维度空间的函数。我们称之为核函数。
通过使用这种映射,使得原来不可线性分离的内容变为可分离。
SVM将这些分类分离后,获取解并返回到原始空间。这样就得到了一个非线性分隔。
这是SVM非常重要的优点。通过在更高维度的空间使用SVM,可以很容易的找出最佳的线性分类器。或决策面。
在所有机器学习中,SVM是最主要的技巧之一。

参数kernel可选择如下几种:



当然,也可以自己定义。

C

C值越大,可以获得更多的训练点。也可以说,C越大,可以获得更复杂的决策边界。
到底是想要一条直线的决策边界,还是想要一条弯曲的边界以提高分类准确度,这就是机器学习中的艺术性所在(人们口中常说的调参狗?)。

咖玛

咖玛值有什么作用?我在linear方法下,测试了一些值(1.0, 100.0, 1000,0)没有发现明显区别。问题先保留。如果有消息再回来补充。

过拟合fitting

如果参数不合适,会导致本应很简单的决策面变得复杂。所以要避免过度拟合。
避免的方法就是指定SVM的参数,也就是调参(这就是很多人说的,机器学习的初级阶段就是调参)以防止过度拟合。

当然,也有自动检测的方法,后面会学到。

优缺点

SVM在复杂的但具有明显分隔边界的情况下,表现十分出色。
但在海量数据集中表现不太好。
因为当训练集变大时,训练时间是通常会成倍增长。
另外,噪音过多的情况下此方法效果也不好。所以如果要分类的类别之间重叠较为严重,那就需要找一些独立的特征,这时使用贝叶斯分类器会更有效。

总结

朴素贝叶斯速度通常比SVM速度快。适合文本等海量数据集。
但SVM在很多方面也很优秀,通常准确率也比贝叶斯高。
所以,选择合适的算法很重要。另外,根据选择的算法不同,还需要考虑相应的参数调整以及过拟合的可能性(特别是在你没有大量训练数据的情况下)。

调整参数的工作量很大,后面会介绍 GridCV(一种几乎能自动查找最优参数调整的优秀 sklearn 工具)。

调参!调参!调参!
我的电脑i5-4460 CPU @ 3.20GHz,训练安然邮件数据集7000多,要100秒,如果要手工调参的话,有点太耗时了。有没有更好的办法???换电脑?
望有经验的同学指点一下。谢谢了。

代码片段

### 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 ###
#features_train = features_train[:len(features_train)/100] 
#labels_train = labels_train[:len(labels_train)/100] 

print("features lenghth:",len(features_test))

from sklearn.svm import SVC

clf=SVC(kernel="rbf", C=10000.0)

t0 = time()
clf.fit(features_train, labels_train)
print "training time:", round(time()-t0, 3), "s"

t0 = time()
pred=clf.predict(features_test)
print "predict time:", round(time()-t0, 3), "s"

from sklearn.metrics import accuracy_score
print(accuracy_score(pred, labels_test))
i=0
for label in pred:
    if label == 1:
        i = i+1
print("total chris:", i)

#########################################################

参考:
Support Vector Machines-kernel functions
sklearn.svm.SVC
机器学习入门 - Udacity

上一篇 下一篇

猜你喜欢

热点阅读