SVM sklearn python实现小示例

来源:互联网 发布:诺基亚x6软件 编辑:程序博客网 时间:2024/05/18 22:55

示例说明

本示例是一个简单的试验,甚至连数据集都不用额外准备,旨在加深对SVM和核函数的理解,并看看如何利用 scikit-learn 中的svm,
编译环境是 jupyter notebook, 可以通过安装 Anaconda,导入 scikit-learn 库可以很容易实现,github示例代码。本例中变没有用外部数据集,而是随机生成的点,大家在理解算法和 scikit-learn 熟练使用后,可以尝试导入有具体意义的数据集,看看SVM的效果。

概述

SVM_demo_with_sklearn.ipynb代码中主要分为两个部分
* 线性 SVM 分类器
* SVM 与核函数

Section 1: 线性 SVM 分类器

首先导入依赖包

%matplotlib inlineimport numpy as npimport matplotlib.pyplot as pltimport seaborn; from sklearn.linear_model import LinearRegressionfrom scipy import statsimport pylab as plseaborn.set()

支持向量机是解决分类和回归问题非常强大的有监督学习算法。简单说来,linear的SVM做的事情就是在不同类别的“数据团”之间划上一条线,对线性可分集,总能找到使样本正确划分的分界面,而且有无穷多个,哪个是最优? 必须寻找一种最优的分界准则,SVM试图找到一条最健壮的线,什么叫做最健壮的线?其实就是离2类样本点最远的线。

from sklearn.datasets.samples_generator import make_blobsX, y = make_blobs(n_samples=50, centers=2,                  random_state=0, cluster_std=0.60)xfit = np.linspace(-1, 3.5)plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='spring')# 其实随意给定3组参数,就可以画出3条不同的直线,但它们都可以把图上的2类样本点分隔开for m, b, d in [(1, 0.65, 0.33), (0.5, 1.6, 0.55), (-0.2, 2.9, 0.2)]:    yfit = m * xfit + b    plt.plot(xfit, yfit, '-k')    plt.fill_between(xfit, yfit - d, yfit + d, edgecolor='none', color='#AAAAAA', alpha=0.4)plt.xlim(-1, 3.5);
from sklearn.svm import SVCclf = SVC(kernel='linear')clf.fit(X, y)def plot_svc_decision_function(clf, ax=None):    """Plot the decision function for a 2D SVC"""    if ax is None:        ax = plt.gca()    x = np.linspace(plt.xlim()[0], plt.xlim()[1], 30)    y = np.linspace(plt.ylim()[0], plt.ylim()[1], 30)    Y, X = np.meshgrid(y, x)    P = np.zeros_like(X)    for i, xi in enumerate(x):        for j, yj in enumerate(y):            P[i, j] = clf.decision_function([xi, yj])    # plot the margins    ax.contour(X, Y, P, colors='k',               levels=[-1, 0, 1], alpha=0.5,               linestyles=['--', '-', '--'])
  • 分隔超平面:上述将数据集分割开来的直线叫做分隔超平面。
  • 超平面:如果数据集是N维的,那么就需要N-1维的某对象来对数据进行分割。该对象叫做超平面,也就是分类的决策边界。
  • 间隔:一个点到分割面的距离,称为点相对于分割面的距离。数据集中所有的点到分割面的最小间隔的2倍,称为分类器或数据集的间隔。
  • 最大间隔:SVM分类器是要找最大的数据集间隔。
  • 支持向量:离分割超平面最近的那些点

sklearn的SVM里面会有一个属性support_vectors_,标示“支持向量”,也就是样本点里离超平面最近的点,组成的。
咱们来画个图,把超平面和支持向量都画出来。

plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='spring')plot_svc_decision_function(clf)plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],            s=200, facecolors='none');

可以用IPython的 interact 函数来看看样本点的分布,会怎么样影响超平面:

from IPython.html.widgets import interactdef plot_svm(N=100):    X, y = make_blobs(n_samples=200, centers=2,                      random_state=0, cluster_std=0.60)    X = X[:N]    y = y[:N]    clf = SVC(kernel='linear')    clf.fit(X, y)    plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='spring')    plt.xlim(-1, 4)    plt.ylim(-1, 6)    plot_svc_decision_function(clf, plt.gca())    plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],                s=200, facecolors='none')interact(plot_svm, N=[10, 200], kernel='linear');

Section 2: SVM 与 核函数

对于非线性可切分的数据集,要做分割,就要借助于核函数了简单一点说呢,核函数可以看做对原始特征的一个映射函数,
不过SVM不会傻乎乎对原始样本点做映射,它有更巧妙的方式来保证这个过程的高效性。
下面有一个例子,你可以看到,线性的kernel(线性的SVM)对于这种非线性可切分的数据集,是无能为力的。

from sklearn.datasets.samples_generator import make_circlesX, y = make_circles(100, factor=.1, noise=.1)clf = SVC(kernel='linear').fit(X, y)plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='spring')plot_svc_decision_function(clf);

然后强大的高斯核/radial basis function就可以大显身手了:

r = np.exp(-(X[:, 0] ** 2 + X[:, 1] ** 2))from mpl_toolkits import mplot3ddef plot_3D(elev=30, azim=30):    ax = plt.subplot(projection='3d')    ax.scatter3D(X[:, 0], X[:, 1], r, c=y, s=50, cmap='spring')    ax.view_init(elev=elev, azim=azim)    ax.set_xlabel('x')    ax.set_ylabel('y')    ax.set_zlabel('r')interact(plot_3D, elev=[-90, 90], azip=(-180, 180));

你在上面的图上也可以看到,原本在2维空间无法切分的2类点,映射到3维空间以后,可以由一个平面轻松地切开了。
而带rbf核的SVM就能帮你做到这一点:

clf = SVC(kernel='rbf')clf.fit(X, y)plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='spring')plot_svc_decision_function(clf)plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],            s=200, facecolors='none');

关于SVM的总结:

  • 非线性映射是SVM方法的理论基础,SVM利用内积核函数代替向高维空间的非线性映射;
  • 对特征空间划分的最优超平面是SVM的目标,最大化分类边际的思想是SVM方法的核心;
  • 支持向量是SVM的训练结果,在SVM分类决策中起决定作用的是支持向量。因此,模型需要存储空间小,算法鲁棒性强;
  • 无任何前提假设,不涉及概率测度;
  • SVM算法对大规模训练样本难以实施
  • 用SVM解决多分类问题存在困难,经典的支持向量机算法只给出了二类分类的算法,而在数据挖掘的实际应用中,一般要解决多类的分类问题。可以通过多个二类支持向量机的组合来解决。主要有一对多组合模式、一对一组合模式和SVM决策树;再就是通过构造多个分类器的组合来解决。主要原理是克服SVM固有的缺点,结合其他算法的优势,解决多类问题的分类精度。如:与粗集理论结合,形成一种优势互补的多类问题的组合分类器。
  • SVM是O(n^3)的时间复杂度。在sklearn里,LinearSVC是可扩展的(也就是对海量数据也可以支持得不错), 对特别大的数据集SVC就略微有点尴尬了。不过对于特别大的数据集,你倒是可以试试采样一些样本出来,然后用rbf核的SVC来做做分类。

依赖的 packages

  • matplotlib
  • pylab
  • numpy
  • seaborn

欢迎关注

  • Github:https://github.com/youngxiao
  • Email: yxiao2048@gmail.com or yxiao2017@163.com
  • Blog: https://youngxiao.github.io
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 qq回执编号忘了怎么办 电脑开机要用户名和密码怎么办 电脑忘记用户名和密码怎么办 微信账号密码忘了怎么办 开发者账号密保忘记怎么办 华为账号忘记密保问题怎么办 fiyme账号忘记密保怎么办 id忘了密保问题怎么办 vivo账号密码忘记了怎么办 步步高账号密码忘了怎么办 步步高手机账号密码忘了怎么办 康佳电视通行证忘了怎么办 尚游通行证忘了怎么办 深圳免限行通行证忘了截图怎么办 电脑把管理员账号删除了怎么办 uc新浪加载失败怎么办红包还 微信忘记账号和密码怎么办 苹果手机忘记id密码怎么办 购买游戏账号被找回怎么办 交易猫账号忘了怎么办 爱奇艺账号怎么修改不了密码怎么办 论文目录显示错误未定义书签怎么办 银行账号被冻结了怎么办 哈罗单车账号被冻结怎么办 麻袋赚赚账号被冻结怎么办 网赌账号被冻结怎么办 梦想城镇账号被冻结怎么办 钱被银行冻结了怎么办 百度云账号密码忘了怎么办 微信钱包忘记密码了怎么办 word文档打开文件出错怎么办 有盘文件删不了怎么办 u盘文档严重损坏怎么办 wps文档打开是乱码怎么办 九游3083网资金冻结怎么办 阴阳师九游版禁止部分玩法怎么办 夜神模拟器游戏打不开怎么办 九游代金券锁定怎么办 被娱乐天地骗了怎么办 win8更新失败无法开机怎么办 安装英雄联盟文件损坏怎么办