当前位置:   article > 正文

支持向量机代码实现_sklearn实现支持向量机

支持向量 图代码

需要用到的函数

  • 引入sklearn自带数据集:sklearn.datasets.make_blobs(n_samples=100, n_features=2, centers=3, cluster_std=1.0, center_box=(-10.0, 10.0), shuffle=True, random_state=None)
  • sklearn.datasets.samples_generator.make_circles() 引入圆形数据集
n_samples: 待生成的样本的总数。
centers: 要生成的样本中心(类别)数,或者是确定的中心点。
cluster_std: 每个类别的方差,例如我们希望生成2类数据,其中一类比另一类具有更大的方差,可以将cluster_std设置为[1.0,3.0]。
  • 径向基函数sklearn.svm.SVC()
model=svm.SVC() #引入分类器
model.fit(X,y) #训练并生成模型

代码

首先做一个简单的线性可分的例子,这里直接用的sklearn中的数据集。
利用 sklearn.datasets.make_blobs生成数据

  1. from sklearn.datasets.samples_generator import make_blobs #生成数据集
  2. X,y=make_blobs(n_samples=50,centers=2,random_state=0,cluster_std=0.6) #n_samples=50意思取50个点,centers=2意思是将数据分为两
  3. plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn') #将图像展示出来
  4. plt.show()

8aa7379f36788304a7d6c0e01aa73f55.png


画出决策边界。

  1. xfit = np.linspace(-1, 3.5)
  2. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  3. plt.plot(xfit, xfit+0.65, '-k')
  4. plt.plot(xfit, 0.5*xfit+1.6, '-k')
  5. plt.plot(xfit, -0.2*xfit+2.9, '-k')
  6. plt.xlim(-1, 3.5)
  7. plt.show()

eb34e6e9df00972f01e6eec0d7fe7010.png


接下来就是训练一个SVM模型

  1. from sklearn.svm import SVC # "Support vector classifier" #支持向量机分类器
  2. model = SVC(kernel='linear', C=1E10)
  3. model.fit(X, y)

构造出支持向量机

  1. def plot_svc_decision_function(model, ax=None, plot_support=True):
  2. """Plot the decision function for a 2D SVC"""
  3. if ax is None:
  4. ax = plt.gca()
  5. xlim = ax.get_xlim()
  6. ylim = ax.get_ylim()
  7. x = np.linspace(xlim[0], xlim[1], 30)
  8. y = np.linspace(ylim[0], ylim[1], 30)
  9. Y, X = np.meshgrid(y, x)
  10. xy = np.vstack([X.ravel(), Y.ravel()]).T
  11. P = model.decision_function(xy).reshape(X.shape)
  12. ax.contour(X, Y, P, colors='k',levels=[-1, 0, 1], alpha=0.5,linestyles=['--', '-', '--'])
  13. if plot_support:
  14. ax.scatter(model.support_vectors_[:, 0],model.support_vectors_[:, 1],s=300, linewidth=1, facecolors='none');
  15. ax.set_xlim(xlim)
  16. ax.set_ylim(ylim)
  17. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  18. plot_svc_decision_function(model);
  19. plt.show()

ff3cf437a500206fc4737313e17f6304.png


其中在边界上的两个红点和一个黄点在决策边界上,是支持向量,其α值不为0。这三个点的坐标可以由model.support_vectors_ 得出。

这个分类器的成功的关键在于:为了拟合,只有支持向量的位置是重要的;任何远离边距的点,都不会影响拟合。边界之外的点无论有多少都不会对其造成影响,下面来对比一下数据为60和120时的区别。

  1. def plot_svm(N=10, ax=None):
  2. X, y = make_blobs(n_samples=200, centers=2,
  3. random_state=0, cluster_std=0.60)
  4. X = X[:N]
  5. y = y[:N]
  6. model = SVC(kernel='linear', C=1E10)
  7. model.fit(X, y)
  8. ax = ax or plt.gca()
  9. ax.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  10. ax.set_xlim(-1, 4)
  11. ax.set_ylim(-1, 6)
  12. plot_svc_decision_function(model, ax)
  13. fig, ax = plt.subplots(1, 2, figsize=(16, 6))
  14. fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
  15. for axi, N in zip(ax, [60, 120]):#左侧的数据60个样本点,右侧的数据为120样本点。
  16. plot_svm(N, axi)
  17. axi.set_title('N = {0}'.format(N))
  18. plt.show()

15208fcb96998b9f3e465f13a1a15252.png


由上图可以看出它们的样本密度不一样,但是它们的决策边界却是一模一样的。这就意味着样本多和样本少没什么差别,这主要是因为没有引入新得支持向量,意思就是说只要边界上的点不变就不会对决策边界造成影响。

核函数

接下来引入核函数,来看看核函数的威力,真的感觉好厉害!
引入一个线性不可分的数据集。

  1. from sklearn.datasets.samples_generator import make_circles
  2. X, y = make_circles(100, factor=.1, noise=.1)
  3. clf = SVC(kernel='linear').fit(X, y)
  4. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  5. plot_svc_decision_function(clf, plot_support=False);
  6. plt.show()

f3cfc5e1a4a8e84853979d7ce4d9b418.png


可以看出来用线性分类无论怎么画线也不可能分好。所以要使用核变换来分类,进行核变换之前,先看一看在数据在高维空间下的映射:

  1. from mpl_toolkits import mplot3d
  2. r=np.exp(-(X**2).sum(1))
  3. def plot_3D(elev=30, azim=30, X=X, y=y):
  4. ax = plt.subplot(projection='3d')
  5. ax.scatter3D(X[:, 0], X[:, 1], r, c=y, s=50, cmap='autumn')
  6. ax.view_init(elev=elev, azim=azim)
  7. ax.set_xlabel('x')
  8. ax.set_ylabel('y')
  9. ax.set_zlabel('z')
  10. plot_3D(elev=45,azim=45,X=X,y=y)
  11. plt.show()

b266cdd23815f084d31637436529c5e1.png


见证核变换威力的时刻到了:
引入径向基函数,进行核变换

  1. clf = SVC(kernel='rbf', C=1E6) #引入径向基 函数
  2. clf.fit(X, y)
  3. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  4. plot_svc_decision_function(clf)
  5. plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
  6. s=300, lw=1, facecolors='none');
  7. plt.show()

效果如下:

d3d812134dc6ab350b79553494e70362.png


可以清楚的看出来效果要比刚才好的多,将线性不可分的两堆数据分割开来。

调节参数-软间隔问题

SVM模型有两个非常重要的参数C与gamma。其中 C是惩罚系数,即对误差的宽容度。c越高,说明越不能容忍出现误差,容易过拟合。C越小,容易欠拟合。C过大或过小,泛化能力变差
gamma是选择RBF函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多。

分别调节C和gamma来看一下对结果的影响:

调节参数C

C趋近于无穷大时,意味着分类严格不能有错误。C趋于很小时,意味着可以有更大的容忍。
引入一个离散度较大的数据集:

  1. X, y = make_blobs(n_samples=100, centers=2,
  2. random_state=0, cluster_std=0.8) #将离散度改为0.8
  3. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn');
  4. plt.show()

c69f56e551cb11b2c3fc3a305aab17f2.png


接下来比较一下C的大小对结果的影响

  1. X, y = make_blobs(n_samples=100, centers=2,random_state=0, cluster_std=0.8)
  2. fig, ax = plt.subplots(1, 2, figsize=(16, 6))
  3. fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
  4. for axi, C in zip(ax, [20, 0.2]): #将C分别设定为200.2,看其对结果的影响。
  5. model = SVC(kernel='linear', C=C).fit(X, y)
  6. axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  7. plot_svc_decision_function(model, axi)
  8. axi.scatter(model.support_vectors_[:, 0],model.support_vectors_[:, 1],s=300, lw=1, facecolors='none');
  9. axi.set_title('C = {0:.1f}'.format(C), size=14)
  10. plt.show()

效果如下:

898879ba0843e6e3ec60156aa79071fc.png


左边这幅图C值比较大,要求比较严格,不能分错东西,隔离带中没有进入任何一个点,但是隔离带的距离比较小,泛化能力比较差。右边这幅图C值比较小,要求相对来说比较松一些,隔离带较大,但是隔离带中进入了很多的黄点和红点。那么C大一点好还是小一点好呢?这需要考虑实际问题,可以进行K折交叉验证来得出最合适的C值。

调节参数gamma

  1. X, y = make_blobs(n_samples=100, centers=2,random_state=0, cluster_std=1.1)
  2. fig, ax = plt.subplots(1, 2, figsize=(16, 6))
  3. fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
  4. for axi, gamma in zip(ax, [20, 0.1]): #比较了一下gamma为200.1对结果的影响
  5. model = SVC(kernel='rbf', gamma=gamma).fit(X, y)
  6. axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  7. plot_svc_decision_function(model, axi)
  8. axi.scatter(model.support_vectors_[:, 0],model.support_vectors_[:, 1],s=300, lw=1, facecolors='none');
  9. axi.set_title('gamma = {0:.1f}'.format(gamma), size=14)
  10. plt.show()

5839755227725239b187916fdee6bc2f.png


左边的图边界比较复杂,这也意味着泛化能力更弱,右边的图比较精简,泛化能力较强。一般会选择泛化能力较强的。

完整代码

  1. # 导入标准库
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from scipy import stats
  5. from sklearn.datasets.samples_generator import make_blobs
  6. #导入数据集
  7. X,y=make_blobs(n_samples=50,centers=2,random_state=0,cluster_std=0.6) #n_samples=50意思取50个点,centers=2意思是将数据分为两
  8. plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')
  9. #绘制决策边界
  10. xfit = np.linspace(-1, 3.5)
  11. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  12. plt.plot(xfit, xfit+0.65, '-k')
  13. plt.plot(xfit, 0.5*xfit+1.6, '-k')
  14. plt.plot(xfit, -0.2*xfit+2.9, '-k')
  15. plt.xlim(-1, 3.5)
  16. #构造支持向量机
  17. from sklearn.svm import SVC # "Support vector classifier"
  18. model = SVC(kernel='linear', C=1E10)
  19. model.fit(X, y)
  20. def plot_svc_decision_function(model, ax=None, plot_support=True):
  21. """Plot the decision function for a 2D SVC"""
  22. if ax is None:
  23. ax = plt.gca()
  24. xlim = ax.get_xlim()
  25. ylim = ax.get_ylim()
  26. x = np.linspace(xlim[0], xlim[1], 30)
  27. y = np.linspace(ylim[0], ylim[1], 30)
  28. Y, X = np.meshgrid(y, x)
  29. xy = np.vstack([X.ravel(), Y.ravel()]).T
  30. P = model.decision_function(xy).reshape(X.shape)
  31. # 绘制决策边界
  32. ax.contour(X, Y, P, colors='k',
  33. levels=[-1, 0, 1], alpha=0.5,
  34. linestyles=['--', '-', '--'])
  35. if plot_support:
  36. ax.scatter(model.support_vectors_[:, 0],model.support_vectors_[:, 1],s=300, linewidth=1, facecolors='none');
  37. ax.set_xlim(xlim)
  38. ax.set_ylim(ylim)
  39. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  40. plot_svc_decision_function(model);
  41. #引入核函数
  42. from sklearn.datasets.samples_generator import make_circles
  43. X, y = make_circles(100, factor=.1, noise=.1)
  44. clf = SVC(kernel='linear').fit(X, y)
  45. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  46. plot_svc_decision_function(clf, plot_support=False);
  47. #高维空间下数据的可视化
  48. from mpl_toolkits import mplot3d
  49. r=np.exp(-(X**2).sum(1))
  50. def plot_3D(elev=30, azim=30, X=X, y=y):
  51. ax = plt.subplot(projection='3d')
  52. ax.scatter3D(X[:, 0], X[:, 1], r, c=y, s=50, cmap='autumn')
  53. ax.view_init(elev=elev, azim=azim)
  54. ax.set_xlabel('x')
  55. ax.set_ylabel('y')
  56. ax.set_zlabel('z')
  57. plot_3D(elev=45,azim=45,X=X,y=y)
  58. # 引入径向基函数
  59. clf = SVC(kernel='rbf', C=1E6)
  60. clf.fit(X, y)
  61. plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  62. plot_svc_decision_function(clf)
  63. plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],s=300, lw=1, facecolors='none');
  64. #调C参数和gamma参数
  65. #C参数
  66. X, y = make_blobs(n_samples=100, centers=2,random_state=0, cluster_std=0.8)
  67. fig, ax = plt.subplots(1, 2, figsize=(16, 6))
  68. fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
  69. for axi, C in zip(ax, [20, 0.2]):
  70. model = SVC(kernel='linear', C=C).fit(X, y)
  71. axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  72. plot_svc_decision_function(model, axi)
  73. axi.scatter(model.support_vectors_[:, 0],model.support_vectors_[:, 1],s=300, lw=1, facecolors='none');
  74. axi.set_title('C = {0:.1f}'.format(C), size=14)
  75. #gamma参数
  76. X, y = make_blobs(n_samples=100, centers=2,random_state=0, cluster_std=1.1)
  77. fig, ax = plt.subplots(1, 2, figsize=(16, 6))
  78. fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
  79. for axi, gamma in zip(ax, [20, 0.1]):
  80. model = SVC(kernel='rbf', gamma=gamma).fit(X, y)
  81. axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
  82. plot_svc_decision_function(model, axi)
  83. axi.scatter(model.support_vectors_[:, 0],model.support_vectors_[:, 1],s=300, lw=1, facecolors='none');
  84. axi.set_title('gamma = {0:.1f}'.format(gamma), size=14)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/53364
推荐阅读
相关标签
  

闽ICP备14008679号