如何用Python实现支持向量机(SVM)?

SVM支持向量机是建立于统计学习理论上的一种分类算法,适合与处理具备高维特征的数据集。

SVM算法的数学原理相对比较复杂,好在由于SVM算法的研究与应用如此火爆,CSDN博客里也有大量的好文章对此进行分析,下面给出几个本人认为讲解的相当不错的:

支持向量机通俗导论(理解SVM的3层境界):http://blog.csdn.net/v_july_v/article/details/7624837

JULY大牛讲的是如此详细,由浅入深层层推进,以至于关于SVM的原理,我一个字都不想写了。。强烈推荐。

还有一个比较通俗的简单版本的:手把手教你实现SVM算法:

http://mp.weixin.qq.com/s?__biz=MzA3MDg0MjgxNQ==&mid=206941003&idx=1&sn=dbf43d9e2aea20574f513e36994d4435#rd

SVN原理比较复杂,但是思想很简单,一句话概括,就是通过某种核函数,将数据在高维空间里寻找一个最优超平面,能够将两类数据分开。

针对不同数据集,不同的核函数的分类效果可能完全不一样。可选的核函数有这么几种:

线性函数:形如K(x,y)=x*y这样的线性函数;

多项式函数:形如K(x,y)=[(x·y)+1]^d这样的多项式函数;

径向基函数:形如K(x,y)=exp(-|x-y|^2/d^2)这样的指数函数;

Sigmoid函数:就是上一篇文章中讲到的Sigmoid函数。

我们就利用之前的几个数据集,直接给出Python代码,看看运行效果:

测试1:身高体重数据

[python] view plaincopy

  1. # -*- coding: utf-8 -*-  
  2. import numpy as np  
  3. import scipy as sp  
  4. from sklearn import svm  
  5. from sklearn.cross_validation import train_test_split  
  6. import matplotlib.pyplot as plt  
  7.   
  8. data   = []  
  9. labels = []  
  10. with open("data\\1.txt") as ifile:  
  11.         for line in ifile:  
  12.             tokens = line.strip().split(' ')  
  13.             data.append([float(tk) for tk in tokens[:-1]])  
  14.             labels.append(tokens[-1])  
  15. x = np.array(data)  
  16. labels = np.array(labels)  
  17. y = np.zeros(labels.shape)  
  18. y[labels=='fat']=1  
  19. x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.0)  
  20.   
  21. h = .02    
  22. # create a mesh to plot in  
  23. x_min, x_max = x_train[:, 0].min() - 0.1, x_train[:, 0].max() + 0.1  
  24. y_min, y_max = x_train[:, 1].min() - 1, x_train[:, 1].max() + 1  
  25. xx, yy = np.meshgrid(np.arange(x_min, x_max, h),  
  26.                      np.arange(y_min, y_max, h))  
  27.   
  28. ''''' SVM '''  
  29. # title for the plots  
  30. titles = ['LinearSVC (linear kernel)',  
  31.           'SVC with polynomial (degree 3) kernel',  
  32.           'SVC with RBF kernel',  
  33.           'SVC with Sigmoid kernel']  
  34. clf_linear  = svm.SVC(kernel='linear').fit(x, y)  
  35. #clf_linear  = svm.LinearSVC().fit(x, y)  
  36. clf_poly    = svm.SVC(kernel='poly', degree=3).fit(x, y)  
  37. clf_rbf     = svm.SVC().fit(x, y)  
  38. clf_sigmoid = svm.SVC(kernel='sigmoid').fit(x, y)  
  39.   
  40. for i, clf in enumerate((clf_linear, clf_poly, clf_rbf, clf_sigmoid)):  
  41.     answer = clf.predict(np.c_[xx.ravel(), yy.ravel()])  
  42.     print(clf)  
  43.     print(np.mean( answer == y_train))  
  44.     print(answer)  
  45.     print(y_train)  
  46.   
  47.     plt.subplot(22, i + 1)  
  48.     plt.subplots_adjust(wspace=0.4, hspace=0.4)  
  49.       
  50.     # Put the result into a color plot  
  51.     z = answer.reshape(xx.shape)  
  52.     plt.contourf(xx, yy, z, cmap=plt.cm.Paired, alpha=0.8)  
  53.       
  54.     # Plot also the training points  
  55.     plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=plt.cm.Paired)  
  56.     plt.xlabel(u'身高')  
  57.     plt.ylabel(u'体重')  
  58.     plt.xlim(xx.min(), xx.max())  
  59.     plt.ylim(yy.min(), yy.max())  
  60.     plt.xticks(())  
  61.     plt.yticks(())  
  62.     plt.title(titles[i])  
  63.       
  64. plt.show()  

运行结果如下:
如何用Python实现支持向量机(SVM)?_第1张图片

 

可以看到,针对这个数据集,使用3次多项式核函数的SVM,得到的效果最好。

测试2:影评态度

下面看看SVM在康奈尔影评数据集上的表现:(代码略)

SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='linear', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.814285714286


SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='poly', max_iter=-1, probability=False, random_state=None,  shrinking=True, tol=0.001, verbose=False)
0.492857142857


SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='rbf', max_iter=-1, probability=False, random_state=None,  shrinking=True, tol=0.001, verbose=False)
0.492857142857


SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='sigmoid', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.492857142857
可见在该数据集上,线性分类器效果最好。

测试3:圆形边界

最后我们测试一个数据分类边界为圆形的情况:圆形内为一类,原型外为一类。看这类非线性的数据SVM表现如何:

测试数据生成代码如下所示:

[python] view plaincopy

  1. ''''' 数据生成 '''  
  2. h = 0.1  
  3. x_min, x_max = -11  
  4. y_min, y_max = -11  
  5. xx, yy = np.meshgrid(np.arange(x_min, x_max, h),  
  6.                      np.arange(y_min, y_max, h))  
  7. n = xx.shape[0]*xx.shape[1]  
  8. x = np.array([xx.T.reshape(n).T, xx.reshape(n)]).T  
  9. y = (x[:,0]*x[:,0] + x[:,1]*x[:,1] < 0.8)  
  10. y.reshape(xx.shape)  
  11.   
  12. x_train, x_test, y_train, y_test\  
  13.     = train_test_split(x, y, test_size = 0.2)  

测试结果如下:

SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='linear', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.65
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='poly', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.675
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='rbf', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.9625
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='sigmoid', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.65

如何用Python实现支持向量机(SVM)?_第2张图片
可以看到,对于这种边界,径向基函数的SVM得到了近似完美的分类结果。而其他的分类器显然束手无策。

 

你可能感兴趣的:(支持向量机,python,机器学习)