python大战机器学习——支持向量机
支持向量机(Support Vector Machine,SVM)的基本模型是定义在特征空间上间隔最大的线性分类器。它是一种二类分类模型,当采用了核技巧之后,支持向量机可以用于非线性分类。
1)线性可分支持向量机(也称硬间隔支持向量机):当训练数据线性可分是,通过硬间隔最大化,学得一个线性可分支持向量机
2)线性支持向量机(也称为软间隔支持向量机):当训练数据近似线性可分时,通过软间隔最大化,学得一个线性支持向量机
3)非线性支持向量机:当训练数据不可分时,通过使用核技巧以及软间隔最大化,学得一个非线性支持向量机。
1、线性可分支持向量机
输入:线性可分训练数据集T
输出:最大几何间隔的分离超平面和分类决策函数
算法步骤:
1)构造并且求解约束优化问题,求得最优解w*,b*
2)由此得到分离超平面,以及分类决策函数
若训练数据集T线性可分,最大间隔分离超平面存在且唯一
下面是线性可分支持向量机学习算法的对偶算法:
输入:线性可分训练数据集T
输出:最大集合间隔的分离超平面和分类决策函数
算法步骤:
1)构造并且求解约束最优化问题,求得最优解α*
2)计算w*,同时选择α*的一个正的分量αj*>0,计算b*
3)由此得到最大集合间隔分离超平面和分类决策函数
2、线性支持向量机
对于线性不可分训练数据,线性支持向量机不再适用,但可以将它扩展到线性不可分问题
线性支持向量机学习算法的对偶算法:
输入:训练数据集T,惩罚参数C>0
输出:软间隔最大化分离超平面和分类决策函数
算法步骤:
1)求解约束优化问题,求得最优解α*
2)计算w*,b*
3)由此得到软间隔最大化分离超平面以及分类决策函数\
实验代码:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 from sklearn import datasets,linear_model,cross_validation,svm 4 5 def load_data_regression(): 6 diabetes=datasets.load_diabetes() 7 return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) 8 9 def load_data_classfication(): 10 iris=datasets.load_iris() 11 X_train=iris.data 12 Y_train=iris.target 13 return cross_validation.train_test_split(X_train,Y_train,test_size=0.25,random_state=0,stratify=Y_train) 14 15 def test_LinearSVC(*data): 16 X_train,X_test,Y_train,Y_test=data 17 cls=svm.LinearSVC() 18 cls.fit(X_train,Y_train) 19 print("Coefficients:%s,intercept %s"%(cls.coef_,cls.intercept_)) 20 print("Score:%.2f"%cls.score(X_test,Y_test)) 21 22 X_train,X_test,Y_train,Y_test=load_data_classfication() 23 test_LinearSVC(X_train,X_test,Y_train,Y_test)
实验结果:
在测试集上的预测准确率达到了0.97,还是非常高的
3、非线性支持向量机
核函数将输入空间中的任意两个向量x,z映射为特征空间中对应的向量之间的内积。在给定核函数K(x,z)的情况下,可以利用求解线性分类问题的方法求解非线性分类问题的支持向量机。
在实际应用中,往往依赖经验直接选择核函数,然后验证该核函数确实是有效的核函数。常用的核函数如下:
1)多项式核函数 2)高斯核函数 3)sigmoid核函数
输入:训练数据集T,惩罚参数C
输出:分类决策函数
算法步骤:
1)选择适当的核函数K,求解约束最优化问题,求得最优解α*
2)计算w*和b*
3)构造分类决策函数
实验代码:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 from sklearn import datasets,linear_model,cross_validation,svm 4 5 def load_data_regression(): 6 diabetes=datasets.load_diabetes() 7 return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) 8 9 def load_data_classfication(): 10 iris=datasets.load_iris() 11 X_train=iris.data 12 Y_train=iris.target 13 return cross_validation.train_test_split(X_train,Y_train,test_size=0.25,random_state=0,stratify=Y_train) 14 15 def test_LinearSVC(*data): 16 X_train,X_test,Y_train,Y_test=data 17 cls=svm.LinearSVC() 18 cls.fit(X_train,Y_train) 19 print("Coefficients:%s,intercept %s"%(cls.coef_,cls.intercept_)) 20 print("Score:%.2f"%cls.score(X_test,Y_test)) 21 22 def test_SVC_linear(*data): #non-linear svm,kernel is linear 23 X_train,X_test,Y_train,Y_test=data 24 cls=svm.SVC(kernel="linear") 25 cls.fit(X_train,Y_train) 26 print("Score:%.2f"%cls.score(X_test,Y_test)) 27 X_train,X_test,Y_train,Y_test=load_data_classfication() 28 #test_LinearSVC(X_train,X_test,Y_train,Y_test) 29 test_SVC_linear(X_train,X_test,Y_train,Y_test)
实验结果:
可以看到线性核要比线性分类支持向量机LinearSVC的预测效果更佳,对测试集的预测全部正确
4、支持向量回归(Support Vector Regression,SVR)
(1)线性回归SVR
实验代码:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 from sklearn import datasets,linear_model,cross_validation,svm 4 5 def load_data_regression(): 6 diabetes=datasets.load_diabetes() 7 return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) 8 9 def test_LinearSVR(*data): 10 X_train,X_test,Y_train,Y_test=data 11 regr=svm.LinearSVR() 12 regr.fit(X_train,Y_train) 13 print("Score:%.2f"%regr.score(X_test,Y_test)) 14 15 X_train,X_test,Y_train,Y_test=load_data_regression() 16 test_LinearSVR(X_train,X_test,Y_train,Y_test)
实验结果:
可以看到线性回归支持向量机的预测性能较差,score值为负值。
(2)非线性回归SVR
实验代码:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 from sklearn import datasets,linear_model,cross_validation,svm 4 5 def load_data_regression(): 6 diabetes=datasets.load_diabetes() 7 return cross_validation.train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0) 8 9 def test_SVR_linear(*data): 10 X_train, X_test, Y_train, Y_test = data 11 regr = svm.SVR(kernel="linear") 12 regr.fit(X_train, Y_train) 13 print("Score:%.2f" % regr.score(X_test, Y_test)) 14 15 X_train,X_test,Y_train,Y_test=load_data_regression() 16 test_SVR_linear(X_train,X_test,Y_train,Y_test)
实验结果:
线性核要比线性回归支持向量机LinearSVR的预测效果更好,但是依然是负值。并且采用poly、rbf、sigmoid函数,以及采用不同的参数,发现其预测的准确率都不是很高,峰值大概在0.6左右。可见支持向量机在回归问题上的表现并不突出
5、SVM的优缺点
SVM本质上是非线性方法,在样本量很少时,容易抓住数据和特征之间的非线性关系,因此可以解决非线性问题、可以避免神经网络结构选择和局部极小点问题、可以提高泛化性能、可以解决高维问题
SVM对缺失数据敏感,对非线性问题没有通用解决方案,必须谨慎选择核函数来处理,计算复杂度高。