【sklearn第九讲】支持向量机之分类篇

机器学习训练营——机器学习爱好者的自由交流空间(qq 群号:696721295)

支持向量机(Support Vector Machines, 简称SVM)是一套有监督学习的方法集,经常用于分类、回归和异常点检测。SVM的优势主要体现在:

  • 在高维空间很有效;

  • 在特征数超过样本数的情况下仍然是有效的;

  • 在决策函数里使用了一个训练点子集,因此存储也是有效的;

  • 在决策函数里可以使用不同的核函数。

SVM的劣势包括:

  • 如果特征数远超样本数,为了避免过度拟合(over-fitting), 核函数和正则项的选择至关重要;

  • SVM不直接提供概率估计,而是使用5倍交叉验证来计算它们。

在scikit-learn里,SVM支持稠密的样本(numpy.ndarray, numpy.asarray)和稀疏的样本(scipy.sparse)作为输入向量。然而,为了使用SVM预测稀疏数据,必须在稀疏数据上作拟合。这样,为了最佳的表现,使用numpy.ndarray模块(稠密样本)、或者scipy.sparse.csr_matrix、参数dtype=float64模块(稀疏样本)。

分类

SVC, NuSVC, LinearSVC能够在一个数据集上作多类别的分类问题。

这里写图片描述

支持向量分类执行类。请注意,LinearSVC不接受关键词kernel, 因为它被假设是线性的。LinearSVC也没有像support_这样的成员函数。SVC, NuSVC, LinearSVC取两个数组作为输入。一个是大小为[n_samples, n_features]的数组X, 装载训练样本;另一个是大小为[n_samples]的类标签数组y, 类标签为字符串或整数。

from sklearn import svm
X = [[0, 0], [1, 1]]
y = [0, 1]
clf = svm.SVC()
clf.fit(X, y)

这里写图片描述

拟合后的模型可以用来预测新值。

clf.predict([[2., 2.]])

这里写图片描述

SVM决策函数依赖于训练数据的子集,这个子集称支持向量。这些支持向量的属性能在成员函数support_vectors_, support_ and n_support里找到。

# get support vectors
clf.support_vectors_

这里写图片描述

# get indices of support vectors
clf.support_

这里写图片描述

# get number of support vectors for each class
clf.n_support_

这里写图片描述

多类别分类

对于多类别的分类问题,类SVC, NuSVC执行一个one-against-one方法。如果参数n_class是类别数,那么创建n_class * (n_class - 1) / 2个分类器,每一个分类器作为两类别分类器训练数据。为了向其它分类器提供一致的接口,decision_function_shape选项允许将“one-against-one”分类器的所有结果汇总给形如(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)

这里写图片描述

```{python}
dec = clf.decision_function([[1]])
dec.shape[1] # 4 classes: 4*3/2 = 6

这里写图片描述

clf.decision_function_shape = "ovr"
dec = clf.decision_function([[1]])
dec.shape[1] # 4 classes

这里写图片描述

另一方面,LinearSVC执行“one-vs-the-rest”多类别策略,这样训练n_class模型。如果仅有两个类,那么只有一个模型被训练。

lin_clf = svm.LinearSVC()
lin_clf.fit(X, Y) 

这里写图片描述

dec = lin_clf.decision_function([[1]])
dec.shape[1]

这里写图片描述

注意到LinearSVC也能执行多类策略,通过设置参数multi_class='crammer_singer'.在实际应用中,one-vs-rest分类通常是首选,虽然结果近似,但运行时间要快得多。

对于“one-vs-rest”, LinearSVC属性coef_, intercept_各自有形状[n_class, n_features], [n_class]. 系数的每一行对应很多“one-vs-rest”分类器n_class之一,而常数项相似。

在“one-vs-one” SVC的例子里,属性的表示方式有点复杂。在有一个线性核的情况下,coef_, intercept_与上述的LinearSVC相似,只是coef_的形状是[n_class * (n_class - 1) / 2, n_features], 对应很多二值分类器。类0到n的顺序是“0 vs 1”, “0 vs 2” , … “0 vs n”, “1 vs 2”, “1 vs 3”, “1 vs n”, … “n-1 vs n”.

dual_coef_的形状是[n_class-1, n_SV], 这有点难理解。其中的列对应n_class * (n_class - 1) / 2个“one-vs-one”分类器的支持向量。每一个支持向量被用在n_class - 1个分类器里。每一行里的n_class - 1项对应这些分类器的双重系数。举个例子说明:

考虑一个三类的分类问题。类0有3个支持向量 v 0 0 , v 0 1 , v 0 2 , 类1, 类2各有2个支持向量 v 1 0 , v 1 1 , v 2 0 , v 2 1 . 对于每一个支持向量 v i j , 都有两个双重系数。在分类器里,我们记在类 i , K 之间的支持向量 v i j 的系数为 α i , k j , 那么dual_coef_看起来像下面这样:

这里写图片描述

SVC方法decision_function对每个样本给出属于每个类的分数(per-class scores). 当构造器参数probability的值设置为True时,能够得到类成员的概率估计(来自方法predict_proba, predict_log_proba)。在二值分类的情况下,概率进一步由Platt scaling校正。Platt scaling校正,是在SVM分数上使用logistic回归,经训练集上的交叉验证拟合。对于大数据集,我们知道交叉验证是很费时的,可以用置信分数代替,建议设置probability=False, 使用decision_function代替predict_proba.

不平衡问题

在有的分类问题里,如果想要重视某些特殊的类,或者是样本,可以使用关键词class_weight, sample_weight. SVC在fit方法里执行class_weight, 它是一个{class_label : value}形式的字典,其中的value是一个大于0的浮点数,设置类class_label的参数C为C * value. 分类结果如下图所示:

这里写图片描述

SVC, NuSVC, SVR, NuSVR and OneClassSVM也在fit方法里通过关键词sample_weight对样本加权。类似class_weight, 它们设置第i个例子的参数C为C * sample_weight[i].

这里写图片描述

阅读更多精彩内容,请关注微信公众号:统计学习与大数据

猜你喜欢

转载自blog.csdn.net/wong2016/article/details/80694164
今日推荐