机器学习笔记8-支持向量机(3/3)

机器学习笔记8-支持向量机(3/3)

  1. scikit-learn中的SVM函数
    机器学习库scikit-learn中也集成了SVM的函数,可以方便的进行调用,可用来分类、回归和异常点检测。
    支持向量机的优点有:
    i)在高维空间效果很好
    ii)当维度数大于样本点数时,效果仍然不错
    iii)决策函数只取决于数据集中的支持向量,能够减轻内存压力
    iv)决策函数中可以选不同的核函数从而实现多种功能。可以使用现有的核函数,也可以自定义核函数。
    支持向量机的缺点有:
    i)如果特征数量比样本数量多很多,为了避免过拟合,需要谨慎选择核函数和正则化项
    ii)SVM不支持概率估计。如果需要概率估计的话,需要通过5折交叉验证的方法。
    (1)分类
    SVC、NuSVC和LinearSVC都可以用来进行多分类。SVC和NuSVC是类似的方法,只是数学形式不一样,参数设置不一样而已。LinearSVC是专门用来线性分类的,所以没有kernel这个参数。对于这三个分类器,如果想查看支持向量,可查看属性support_vectors_。
    from sklearn import svm
    X = [[0, 0], [1, 1]]
    y = [0, 1]
    clf = svm.SVC(gamma='scale')
    clf.fit(X, y) 
    clf.predict([[2., 2.]])
    clf.support_vectors_
    
    对于多分类,SVC和NuSVC默认实行的是“one-against-one”的方法。假设有n个类,就需要有n*(n-1)/2个分类器。其中每一个分类器只会训练两个类的数据。最后用decision_function_shape参数来汇总结果。还有另一种多分类方法:“one-vs-the-rest”方法,这种方法只需要n个分类器。每个分类器会训练一个类+其余类的数据。如果只有两个类,则只需要一个分类器。LinearSVC使用的就是这个方法。
    >>> X = [[0], [1], [2], [3]]
    >>> Y = [0, 1, 2, 3]
    >>> clf = svm.SVC(gamma='scale', decision_function_shape='ovo')#decision_function_shape采用的是“1vs1”模式
    >>> clf.fit(X, Y) 
    SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
    	decision_function_shape='ovo', degree=3, gamma='scale', kernel='rbf',
    	max_iter=-1, probability=False, random_state=None, shrinking=True,
    	tol=0.001, verbose=False)        #kernel是'rbf',因此这个是非线性分类器
    >>> dec = clf.decision_function([[1]])
    >>> dec.shape[1] # 有四个类,因此需要4*(4-1)/2=6个分类器
    6
    >>> clf.decision_function_shape = "ovr"   #将decision_function_shape改为“1vsR”模式
    >>> dec = clf.decision_function([[1]])
    >>> dec.shape[1]       # 此时四个类就只需要四个分类器
    4
    
    (2)回归
    支持向量分类可以用来解决回归问题,称为支持向量回归。与支持向量分类类似,支持向量回归也只跟训练数据的一小部分子集有关。不同的地方是分类的输入 y y y是个整数,而回归的输入 y y y是个浮点数。支持向量回归总共包括三个函数:SVR,NuSVR和LinearSVR。
    (3)复杂度
    SVM的时间复杂度和空间复杂度会随着训练数据的容量增加而迅速增加。SVM的核心是将支持向量从训练数据中分离,这是一个二次规划问题。它的求解利用了libsvm,复杂度在 O ( n f e a t u r e s × n s a m p l e s 2 ) O(n_{features}\times n_{samples}^2) O(nfeatures×nsamples2) O ( n f e a t u r e s × n s a m p l e s 3 ) O(n_{features}\times n_{samples}^3) O(nfeatures×nsamples3)之间。但如果是线性的SVM,它的复杂度是 O ( n f e a t u r e s × n s a m p l e s ) O(n_{features}\times n_{samples}) O(nfeatures×nsamples)
    (4)Tips
    i)核函数的大小:对于SVC、SVR等,核函数的大小会极大地影响大型数据问题的运行时间。默认的cache_size是200MB,如果内存足够,可以提升到500MB或者1000MB
    ii)惩罚参数C:C值的意义可以参看上一节的线性支持向量机。C默认为1。如果数据的噪声很大,应该减小C值。当C值很大时,LinearSVC和LinearSVR会对C值变得不敏感(预测结果也不会再改善)。而且较大的C值会增加训练的时间。
    iii)SVM算法不是尺度不变的。所以在用SVM之前,强烈建议将输入数据的每一个特征变换到[0,1]或[-1,1]之间,或将其标准化为均值为零方差为1。对于测试数据也需用到同样的尺度变换。
    iv)如果数据是不平衡的(比如很多的正实例点和极少的负实例点),建议设置class_weight=‘balanced’,并尝试设置不同的惩罚参数C值。
    v)如果有经验知道数据是线性可以拟合的,那么使用LinearSVC去分类 或者LinearSVR去回归,它们不需要我们去慢慢的调参去选择各种核函数以及对应参数, 速度也快。如果我们对数据分布没有什么经验,一般使用SVC去分类或者SVR去回归,这就需要我们选择核函数以及对核函数调参了。对于分类或回归中,函数其它参数的设置,包括核函数参数degree、核函数参数gamma、核函数参数coef0这篇博客有详尽的解释。

以下是利用SVC实现的一小段代码,数据集是sklearn中的内置数据集:

from sklearn.datasets import fetch_olivetti_faces
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.svm import SVC

faces=fetch_olivetti_faces()
x_train,x_test,y_train,y_test=train_test_split(faces['data'],faces['target'],test_size=0.25,random_state=17)
scaler=preprocessing.StandardScaler()
x_train=scaler.fit_transform(x_train)
x_test=scaler.fit_transform(x_test)

svc_linear=SVC(C=0.2,kernel='linear')
svc_linear.fit(x_train,y_train)
y_predict_train=svc_linear.predict(x_train)
y_predict_test=svc_linear.predict(x_test)
from sklearn import metrics
print(metrics.accuracy_score(y_train,y_predict_train))
print(metrics.accuracy_score(y_test,y_predict_test))

参考:
李航《统计学习方法》
https://scikit-learn.org/dev/modules/svm.html
https://www.cnblogs.com/pinard/p/6117515.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值