转自https://blog.csdn.net/sophia_xw/article/details/70738925
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])
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的公式,可在官网查看细节。