scikit-learn中的SVM

主要参考资料: http://scikit-learn.org/stable/modules/svm.html#


SVM优点:

       高维空间有效性;

       数据维度远大于样本数量时的有效性;

       决策函数实际使用训练集的子集(也叫支持向量),内存使用高效;

       多样性:核函数可选,也可自己定义。

 

SVM缺点:

       特征数大于样本数,SVM方法不太适用了。

       没有直接提供误差估计,计算需花很大代价;

 

scikit-learn中的SVM输入支持诸如numpy.ndarray (或者可以转化为numpy.asarray形式) 的密集数据及类似scipy.sparse的稀疏数据。然而,用SVM给稀疏数据做预测,需要有合适的数据。最好是,密集数据用numpy.ndarrsy形式,稀疏数据用scipy.sparse.csr_matrix形式,数据格式均用dtype=float64。

 

SVC和NuSVC是相似的方法,但是输入参数和数学公式不一样。另一方面,LinearSVC是另一种线性核的SVM方法。注意,LinearSVC不用给定参数kernel,从命名可以看出其默认为linear核,对比SVC和NuSVC,缺少support_参数。

 

SVC, NuSVC和linearSVC接受两个数组为输入,X大小为[ n_samples, n_features],是训练样本;y的大小是 [n_samples],是类标签,可以是strings或者integers。

 

>>> from sklearn import svm

>>> X= [[0,0], [1,1]]

>>> y= [0,1]

>>> clf= svm.SVC()

>>> clf.fit(X, y) 

SVC(C=1.0, cache_size=200,class_weight=None, coef0=0.0,

   decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',

   max_iter=-1, probability=False, random_state=None, shrinking=True,

   tol=0.001, verbose=False)

 

在fiitted之后,模型就能进行预测了。

>>> clf.predict([[2.,2.]])
array([1])

 

SVMs的决策函数依赖于训练集的子集,称之为支持向量。这些支持向量的属性能在成员support_vectors, support_和n_support中看到:

>>> # get support vectors
>>> clf.support_vectors_
array([[ 0.,  0.],
       [ 1.,  1.]])
>>> # get indices of support vectors
>>> clf.support_
array([0, 1]...)
>>> # get number of support vectors for each class
>>> clf.n_support_
array([1, 1]...)

 

SVC和NuSVC在处理多分类问题上采用的是“1 vs 1”的策略。若n_class是类别数,那需要训练的模型数量就是 n_class*(n_class-1)/2 ,每次训练使用两个类别的数据。为了提供跟其他分类器类似的接口,decision_funxtion_shape选项能将 “1 vs 1”分类器的结果组合成形如(n_samples, n_classes)的决策器。

>>> X= [[0], [1], [2], [3]]
>>> Y= [0,1,2,3]
>>> clf= svm.SVC(decision_function_shape='ovo')
>>> clf.fit(X, Y) 
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovo', degree=3, gamma='auto', kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001, verbose=False)
>>> dec= clf.decision_function([[1]])
>>> dec.shape[1]# 4 classes: 4*3/2 = 6
6
>>> clf.decision_function_shape="ovr"
>>> dec= clf.decision_function([[1]])
>>> dec.shape[1]# 4 classes
4

 

另一方面,LinearSVC采用的是“1vs 其他”多分类策略,所以训练n_class 个模型即可。如果只有两类,那只需要训练一个模型:

>>> lin_clf= svm.LinearSVC()
>>> lin_clf.fit(X, Y) 
LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
     intercept_scaling=1, loss='squared_hinge', max_iter=1000,
     multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
     verbose=0)
>>> dec= lin_clf.decision_function([[1]])
>>> dec.shape[1]
4

 

注意LinearSVC配置了多分类策略,也就是所谓的Crammer和Singer公式中的所分类SVM方法,实现中使用参数multi_class=’crammer_singer’。这种方法是固定的,但是不太适用于“1 vs其他”的情况。实践中,“1vs其他”分类适用较多,因为结果简单,运行周期短。

 

在“1 vs其他”情况下,LinearSVC的coef_和intercept_属性的大小分别是[n_class, n_features]和 [n_class],系数矩阵的每一行是“1 vs其他”中的一个分类器,顺序与类别的顺序相同。

 

SVC中的“1 vs 1”模式在属性中有点差异。当核函数选择Linear时,coef_和intercept_的数值与LinearSVC中相同,但是coef_的大小是 [n_class*(n_class-1)]/2, n_features],对应于二分类器。分类器的顺序是“0 vs 1”,“0 vs 2”……“0 vs n”,“1 vs 2”,“1 vs 3”……

“n-1 vs n”。

 

Deal_coef_的大小是 [n_class-1, n_SV],支持向量的列在任意一个“1 vs 1”分类器中,每个支持向量都在n_class-1个分类器中使用到了。


【scores 和 probabilities】
SVC方法decision_function会给每个样本一个属于某个类别的概率。如果构造器probability=True,则会启用类成员概率估计(用predict_proba或者predict_log_proba)。二分类情况下,概率通过Platt-scalling校准,比如用svm分数进行线性回归,用额外的训练集的十字交叉验证法实现。


不用说,Platt-scalling校准中的十字交叉验证在大数据集下是个费时费力的操作。另外,用scores做的概率估计是不稳定的,参数argmax并不是概率的argmax。Platt方法也存在理论问题,如果要求可信的scores,但不必要是概率,那可以设probability=False,而且用decision_function来代替predict_proba。


【unbalabced problems】
如果要更加关注类别和参数,可以使用参数class_weight和sample_weight。


SVC(注意不是NuSVC)的fit方法中有个很重要的关键字class_weight,是字典类型{class_label : value},其中value是>0的浮点类型,那么此时class_label的C参数就成了C*value。


SVC、NuSVC、SVR、NuSVR和OneClassSVM同样也有通过参数sample_weight给单个样本添加权重,此时类别class_label的C参数就成了C*value。


【回归】
SVM方法同样可以做回归,此时叫做SVR。


如上所述,SVM模型的建立只与训练数据中的一部分子集有关,因为建立模型的代价函数不关心远离超平面的训练点。类似的,SVR模型也只与训练集的一部分有关,因为代价函数忽略训练集中靠近模型预测的点。


SVR有三种不同的实现方式,SVR、NuSVR和LinearSVR,其中LinearSVR的实现比SVR更快,但是只支持线性核,NuSVR的实现使用明显不同于SVR和LinearSVR的公式,可在官网查看细节。


>>> from sklearn import svm
>>> X = [[0, 0], [2, 2]]
>>> y = [0.5, 2.5]
>>> clf = svm.SVR()
>>> clf.fit(X, y) 
SVR(C=1.0, cache_size=200, coef0=0.0, degree=3, epsilon=0.1, gamma='auto',
    kernel='rbf', max_iter=-1, shrinking=True, tol=0.001, verbose=False)
>>> clf.predict([[1, 1]])
array([ 1.5])


【scores 和 probabilities】
SVC方法decision_function会给每个样本一个属于某个类别的概率。如果构造器probability=True,则会启用类成员概率估计(用predict_proba或者predict_log_proba)。二分类情况下,概率通过Platt-scalling校准,比如用svm分数进行线性回归,用额外的训练集的十字交叉验证法实现。


不用说,Platt-scalling校准中的十字交叉验证在大数据集下是个费时费力的操作。另外,用scores做的概率估计是不稳定的,参数argmax并不是概率的argmax。Platt方法也存在理论问题,如果要求可信的scores,但不必要是概率,那可以设probability=False,而且用decision_function来代替predict_proba。


【unbalabced problems】
如果要更加关注类别和参数,可以使用参数class_weight和sample_weight。


SVC(注意不是NuSVC)的fit方法中有个很重要的关键字class_weight,是字典类型{class_label : value},其中value是>0的浮点类型,那么此时class_label的C参数就成了C*value。


SVC、NuSVC、SVR、NuSVR和OneClassSVM同样也有通过参数sample_weight给单个样本添加权重,此时类别class_label的C参数就成了C*value。


【回归】
SVM方法同样可以做回归,此时叫做SVR。


如上所述,SVM模型的建立只与训练数据中的一部分子集有关,因为建立模型的代价函数不关心远离超平面的训练点。类似的,SVR模型也只与训练集的一部分有关,因为代价函数忽略训练集中靠近模型预测的点。


SVR有三种不同的实现方式,SVR、NuSVR和LinearSVR,其中LinearSVR的实现比SVR更快,但是只支持线性核,NuSVR的实现使用明显不同于SVR和LinearSVR的公式,可在官网查看细节。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sophia_xw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值