sklearn中支持向量机部分

来源:互联网 发布:sm3算法是对称算法吗? 编辑:程序博客网 时间:2024/06/05 14:37

写在开头:英文原文http://scikit-learn.org/stable/modules/svm.html。

只是对原文做了简单的翻译,主要自己学习,能给大家提供帮助就再好不过了。

************************************我是分割线************************************************

1.4支持向量机(Support Vector Machine

支持向量机主要用于分类(classification)、回归(regression)、异常检测(outliers detection)的监督分类方法。

支持向量机的优点:

能有效的作用于高维数据;

能有效的作用于数据样本小于数据维数时;

高效利用内存,使用训练集的几个点作为支持向量;

核函数,将输入空间变换到新的特征空间。

支持向量机的一些缺点:

不能很好的处理特征数远大于样本数的数据集;

不能提供概率估计。

sklearn中的svm可支持密向量集合稀疏向量集

 

1.4.1分类(classification

 

▲SVCNuSVC以及LinearSVC可解决多类问题,三种分类器的表现如下



▲SVCNuSVC是相识的模型,但是在参数集和数学模型上略微不同。LinearSVC是一种线性核的分类方法,LinearSVC不接收kernel参数,为线性核。SVCNuSVC以及LinearSVC以两个数组(array)作为输入:训练数据集X[n_samples,n_feature],标签(string/integersY[n_samples]

>>> 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)训练完成后,可用于预测新的值>>> 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]...)

1.4.1.1多类分类(Multi-classclassification

 

▲SVCNuSVC采用一对一方法实现多类分类。如果n_class是分类的个数,那么将会构造n_class*(n_class-1)/2个分类器,每个训练数据将会有被分为两类To provide a consistent interface withother classifiers, the decision_function_shape option allows to aggregate theresults of theone-against-one classifiers to a decision function of shape (n_samples, n_classes):

>>> X = [[0], [1], [2], [3]]>>> Y = [0, 1, 2, 3]>>> clf = svm.SVC(decision_function_shape='ovo')#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 = 66>>> clf.decision_function_shape = "ovr"#ovr 一对多>>> dec = clf.decision_function([[1]])>>> dec.shape[1] # 4 classes4

▲LinearSVC利用一对多的方法实现多类分类,因此只需训练n个模型。


>>> 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提供了多种多分类决策,可通过multi_class = ‘crammer_singer’实现,该方法对one-vs-rest分类不适用。在实际中,首选one-vs-rest分类。

▲对于“one-vs-rest”的LinearSVC的属性coef_([n_class,n_features])和intercept_([n_class])。

1.4.1.2 分值与概率(Scores andProbabilities)

▲SVC中decis_function模式给每种分类一个分数。当参数probability设置为True时,将会使用概率估计方法(predict_proba和predict_log_proba设定)。在二分问题中,概率校准使用普拉特缩放,对支持向量机的分值采用logistic回归,通过交叉验证进行拟合。

1.4.1.3 不平衡问题(Unbalancedproblems)

▲在某些问题中我们会更加重视一些类或者一些样本,可使用class_weight和sample_weight来实现

▲SVC中在fit方法中通过关键字class_weight来实现。字典形式({class_label : value}),每个value大于0。下图为线性SVM权值的作用。


相关代码:

# -*- coding: utf-8 -*-"""Created on Mon Jan  2 10:26:15 2017@author: ZQ"""import numpy as npimport matplotlib.pyplot as pltfrom sklearn import svmrng = np.random.RandomState(0)n_samples_1 = 1000n_samples_2 = 100X = np.r_[1.5*rng.randn(n_samples_1,2),         0.5*rng.randn(n_samples_2,2) + [2,2]]y = [0] * (n_samples_1)+[1]*(n_samples_2)#拟合模型,并获得超平面clf = svm.SVC(kernel = 'linear',C = 1.0)clf.fit(X,y)w = clf.coef_[0]a = -w[0] / w[1]xx = np.linspace(-5,5)yy = a*xx - clf.intercept_[0]/w[1]wclf = svm.SVC(kernel = 'linear',class_weight = {1:10})wclf.fit(X,y)ww = wclf.coef_[0]wa = -ww[0]/ww[1]wyy = wa*xx - wclf.intercept_[0]/ww[1]h0 = plt.plot(xx,yy,'k-',label = 'no weights')h1 = plt.plot(xx,wyy,'k--',label = 'with weights')plt.scatter(X[:,0],X[:,1],c = y,cmap = plt.cm.Paired)plt.legend()plt.axis('tight')plt.show()

▲SVCNuSVCSVRNuSVR以及OneClassSVM同样可在fit方法中,使用samp_weight参数对个别样本权重进行赋值。如下图,左边无权重,右边有权重。



相关代码:

# -*- coding: utf-8 -*-"""Created on Mon Jan  2 11:10:48 2017@author: ZQ"""import numpy as npimport matplotlib.pyplot as pltfrom sklearn import svmdef plot_decision_function(classifier,sample_weight,axis,title):    xx,yy = np.meshgrid(np.linspace(-4,5,500),np.linspace(-4,5,500))        Z = classifier.decision_function(np.c_[xx.ravel(),yy.ravel()])    Z = Z.reshape(xx.shape)        axis.contourf(xx,yy,Z,alpha = 0.75,cmap = plt.cm.bone)    axis.scatter(X[:,0],X[:,1],c=y,s=100*sample_weight,alpha = 0.9,                 cmap = plt.cm.bone)    axis.axis('off')    axis.set_title(title)    np.random.seed(0)X = np.r_[np.random.randn(10,2)+[1,1],np.random.randn(10,2)]y = [1]*10+[-1]*10sample_weight_last_ten = abs(np.random.randn(len(X)))sample_weight_constant = np.ones(len(X))sample_weight_last_ten[15:] *= 5sample_weight_last_ten[9] *= 15clf_weights = svm.SVC()clf_weights.fit(X,y,sample_weight = sample_weight_last_ten)clf_no_weights = svm.SVC()clf_no_weights.fit(X,y)fig,axes = plt.subplots(1,2,figsize = (14,6))plot_decision_function(clf_no_weights,sample_weight_constant,axes[0],'Constant weights')plot_decision_function(clf_weights,sample_weight_last_ten,axes[1],'Modified weights')plt.show()

1.4.2回归(regression

支持向量分类方法,还可以扩展为支持向量回归。

支持向量分类只是取决于训练集的部分数据,因为成本函数只是关心间隔上的数据。类似地,支持向量回归也是利用部分训练数据集,成本函数同样会忽略接近预测模型的训练数据集。

提供了三种不同的支持向量回归:SVRNuSVR以及LinearSVR。线性SVR比非线性的快。

▲fit方法需要Xy参数,只有在这个例子中y是浮点类型。

>>> 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])

线性和非线性SVR例子,对同一数据,其结果如下:


从中可看出基于高斯核的拟合效果最好。

相关代码:


# -*- coding: utf-8 -*-"""Created on Mon Jan  2 16:09:49 2017@author: ZQ"""import numpy as npfrom sklearn.svm import SVRimport matplotlib.pyplot as plt#generate sample dataX = np.sort(5 * np.random.rand(40,1),axis = 0)y = np.sin(X).ravel()#Add noise to targetsy[::5] += 3*(0.5 - np.random.rand(8))#fit regression model拟合回归模型svr_rbf = SVR(kernel = 'rbf',C = 1e3,gamma = 0.1)svr_lin = SVR(kernel = 'linear',C = 1e3)svr_poly = SVR(kernel = 'poly',C = 1e3,degree = 2)y_rbf = svr_rbf.fit(X,y).predict(X)y_lin = svr_lin.fit(X,y).predict(X)y_poly = svr_poly.fit(X,y).predict(X)#result 结果lw = 2plt.scatter(X,y,color = 'r',label = 'data')#When hold is True, subsequent plot commands will be added to the current axes. When hold is False, the current axes and figure will be cleared on the next plot command.plt.hold('on')plt.plot(X,y_rbf,color = 'navy',lw = lw,label = 'RBF model')plt.plot(X,y_lin,color = 'c',lw = lw,label = 'Linear model')plt.plot(X,y_poly,color = 'blue',lw = lw,label = 'Polynomial model')plt.xlabel('data')plt.ylabel('target')plt.title('SVR')plt.legend()plt.show()

1.4.3 密度估计,异常检测(Density estimation,novelty detection)

▲ 一种类型的SVM模型可以用于新类型检测,该模型可以检测出数据集的软边界,从而识别新的点是否属于该类型。该情况属于无监督学习,只使用X数组作为拟合数据的输入,无标签。


相关代码:

# -*- coding: utf-8 -*-"""Created on Mon Jan  2 16:58:07 2017@author: ZQ"""import numpy as npimport matplotlib.pyplot as pltimport matplotlib.font_managerfrom sklearn import svmxx,yy = np.meshgrid(np.linspace(-5,5,500),np.linspace(-5,5,500))#generate train dataX = 0.3*np.random.rand(100,2)X_train = np.r_[X + 2,X - 2]#generate some regular novel observationsX = 0.3*np.random.rand(20,2)X_test = np.r_[X + 2,X - 2]X_outliers = np.random.uniform(low = -4,high = 4,size = (20,2))#fit the modelclf = svm.OneClassSVM(nu = 0.1,kernel = 'rbf',gamma = 0.1)clf.fit(X_train)y_pred_train = clf.predict(X_train)y_pred_test = clf.predict(X_test)y_pred_outliers = clf.predict(X_outliers)n_error_train = y_pred_train[y_pred_train == -1].sizen_error_test = y_pred_test[y_pred_test == -1].sizen_error_outliers = y_pred_outliers[y_pred_outliers == 1].sizeZ = clf.decision_function(np.c_[xx.ravel(),yy.ravel()])Z = Z.reshape(xx.shape)plt.title('Novelty Detection')plt.contourf(xx,yy,Z,levels = np.linspace(Z.min(),0,7),cmap = plt.cm.PuBu)a = plt.contour(xx,yy,Z,levels = [0],linewidths = 2,colors = 'darkred')plt.contourf(xx,yy,Z,levels = [0,Z.max()],color = 'palevioletred')s = 40b1 = plt.scatter(X_train[:,0],X_train[:,1],c = 'white',s = s)b2 = plt.scatter(X_test[:,0],X_test[:,1], c = 'blueviolet', s = s)c = plt.scatter(X_outliers[:,0],X_outliers[:,1],c = 'gold',s = s)plt.axis('tight')plt.xlim((-5,5))plt.ylim((-5,5))plt.legend([a.collections[0], b1, b2, c],           ["learned frontier", "training observations",            "new regular observations", "new abnormal observations"],           loc="upper left",           prop=matplotlib.font_manager.FontProperties(size=11))plt.xlabel(    "error train: %d/200 ; errors novel regular: %d/40 ; "    "errors novel abnormal: %d/40"    % (n_error_train, n_error_test, n_error_outliers))plt.show()

1.4.4  复杂性(complexity)

▲虽然支持向量机是强有力的工具,但是其时间和空间复杂度会随着训练集的增加而快速的增加。SVM的核心是二次规划问题,从训练数据中把支持向量分离出来。如果数据集很稀疏时需要注意相关问题(这感觉不能太好的解释)(http://scikit-learn.org/stable/modules/svm.html#unbalanced-problems)。此外,还要说明一点,LinearSVC比基于libsvm的SVC更高效。

1.4.5 实际运用中的一些技巧(Tips on practical use)

▲ 避免复制数据(Avoiding data copy):对于SVC,SVR,NuSVC以及NuSVR,如果数据在传递到这些方法时,使用的数据不是C语言格式的连续区域以及双精度的话,那么在调用底层C语言实现之前,数据会被拷贝。

     对于LinearSVC(LogisticRegres)任何以numpy中array数组形式的数据将会转变为稀疏矩阵表示(liblinearinternal sparse data representation。如果不想转换,建议使用SGDClassifier。

▲核缓存大小(Kernel cache size):对于SVC,SVR,nuSVC和NuSVR,核缓存的大小将会解决大问题的时间。如果有足够的内存,可以通过cache_size参数提高核内存。

▲设置C参数(Setting C):默认值为1,在噪声较多的情况下可以适当的降低。

▲增加数据(Scale data)

▲在NuSVC/OneClassSVM/NuSVR中,参数nu几乎接近训练误差和支持向量的比值

▲在SVC中,如果数据分类不平衡,设置class_weight = 'balanced' 或者使用不同的参数C

▲在拟合LinearSVC模型时,采用随机生产数的方式去选择特征。因此对于相同的数据可能有不同的结果,可减小tol参数避免

▲略。。。。

1.4.6 核方法(kernel functions)

▲核方法有如下几种:

线性核(linear):<x,x'>

多项式核(polynomial):(r<x,x'>+r)d 其中d由degree参数指定,r由参数coef0指定

高斯核(rbf):exp(-r|x - x'|^2).r由参数gamma指定,必须大于0

sigmod核(tanh(r<x,x'>+r)),r由参数coef指定

▲初始化时核关键字指定不同的核方法

>>> linear_svc = svm.SVC(kernel='linear')>>> linear_svc.kernel'linear'>>> rbf_svc = svm.SVC(kernel='rbf')>>> rbf_svc.kernel'rbf'





1 0
原创粉丝点击