支持向量机(SVM)

关于SVM求解最佳解我们有一系列的矩阵运算,还有拉格朗日算子,比较复杂,下面只说如何使用,不深究算数推导。

我们看下面这个图:
在这里插入图片描述
虽然这三个不同的分割器都能完美地判别这些样本,但是选择不同的分 割线,可能会让新的数据点(例如图 5-54 中的“X”点)分配到不同的标签。显然,“画一条分割不同类型的直线”还不够,我们需要进一步思考。
支持向量机提供了改进这个问题的方法,它直观的解释是:不再画一条 细线来区分类型,而是画一条到最近点边界、有宽度的线条。具体形式 如下面的示例所示:
在这里插入图片描述
来看看这个数据的真实拟合结果:用 Scikit-Learn 的支持向量机分 类器在数据上训练一个 SVM 模型。这里用一个线性核函数,并将 参数 C 设置为一个很大的数(C很大说明边界很硬,不允许有错误的点分类):

from sklearn.svm import SVC # "Support vector classifier" 
model = SVC(kernel='linear', C=1E10) 
model.fit(X, y) 
Out[5]: SVC(C=10000000000.0, cache_size=200, class_weight=None, coef0=0.0, decision_function_shape=None, degree=3, gamma='auto', kernel='linear', max_iter=-1, probability=False, random_state=None, shrinking=True, tol=0.001, verbose=False)

为了实现更好的可视化分类效果,创建一个辅助函数画出 SVM 的 决策边界:

def plot_svc_decision_function(model, ax=None, plot_support=True): 
   if ax is None: 
      ax = plt.gca() 
   xlim = ax.get_xlim() 
   ylim = ax.get_ylim() # 创建评估模型的网格 
   x = np.linspace(xlim[0], xlim[1], 30) 
   y = np.linspace(ylim[0], ylim[1], 30) 
   Y, X = np.meshgrid(y, x) xy = np.vstack([X.ravel(), Y.ravel()]).T 
   P = model.decision_function(xy).reshape(X.shape)
    # 画决策边界和边界        
   ax.contour(X, Y, P, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--']) # 画支持向量 
   if plot_support: 
      ax.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1], s=300, linewidth=1, facecolors='none'); 
      ax.set_xlim(xlim) 
      ax.set_ylim(ylim) 
 plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
 plot_svc_decision_function(model)                

在这里插入图片描述
这就是两类数据间隔最大的分割线。你会发现有一些点正好就在边 界线上,在图 5-56 中用黑圆圈表示。这些点是拟合的关键支持 点,被称为支持向量,支持向量机算法也因此得名。在 Scikit- Learn 里面,支持向量的坐标存放在分类器的 support_vectors_ 属性中.
分类器能够成功拟合的关键因素,就是这些支持向量的位置——任 何在正确分类一侧远离边界线的点都不会影响拟合结果!从技术角度解释的话,是因为这些点不会对拟合模型的损失函数产生任何影响,所以只要它们没有跨越边界线,它们的位置和数量就都无关紧要.
这种对远离边界 的数据点不敏感的特点正是 SVM 模型的优点之一。
2、核函数的使用
将 SVM 模型与核函数组合使用,功能会非常强大。我们在 5.6 节 介绍基函数回归时介绍过一些核函数。那时,我们将数据投影到多 项式和高斯基函数定义的高维空间中,从而实现用线性分类器拟合 非线性关系。 在 SVM 模型中,我们可以沿用同样的思路。为了应用核函数,引 入一些非线性可分的数据。

例如,一种简单的投影方法就是计算一个 以数据圆圈(middle clump)为中心的径向基函数:
r = np.exp(-(X ** 2).sum(1))
在这里插入图片描述
这种策略的问题是,如果将 N 个数据点投影到 N 维空间,当 N 不 断增大的时候就会出现维度灾难,计算量巨大。但由于核函数技巧 提供的小程序可以隐式计算核变换数据的拟合,也就是说,不需要建立完全的 N 维核函数投影空间!这个核函数技巧内置在 SVM 模型中,是使 SVM 方法如此强大的充分条 件。
在 Scikit-Learn 里面,我们可以应用核函数化的 SVM 模型将线性核 转变为 RBF(径向基函数)核,设置 kernel 模型超参数即可

clf = SVC(kernel='rbf', C=1E6) #超参数改为rbf
clf.fit(X, y) 
Out[14]: SVC(C=1000000.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) 
In[15]: 
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn') plot_svc_decision_function(clf) 
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=300, lw=1, facecolors='none');

在这里插入图片描述
3、SVM优化:软化边界
到目前为止,我们介绍的模型都是在处理非常干净的数据集,里面 都有非常完美的决策边界。但如果你的数据有一些重叠该怎么办 呢?例如,有如下所示一些数据
在这里插入图片描述
在这里插入图片描述
4、总结
前面已经简单介绍了支持向量机的基本原则。支持向量机是一种强大的 分类方法,主要有四点理由。
模型依赖的支持向量比较少,说明它们都是非常精致的模型,消耗内存少
一旦模型训练完成,预测阶段的速度非常快
由于模型只受边界线附近的点的影响,因此它们对于高维数据的学习效果非常好——即使训练比样本维度还高的数据也没有问题,而这是其他算法难以企及的。
核函数方法的配合极具通用性,能够适用不同类型的数据。

但是,SVM 模型也有一些缺点。
随着样本量 N 的不断增加,最差的训练时间复杂度会达到 [N3]; 经过高效处理后,也只能达到 [N2]。因此,大样本学习的计算成 本会非常高。 训练效果非常依赖于边界软化参数 C 的选择是否合理。这需要通过 交叉检验自行搜索;当数据集较大时,计算量也非常大。
预测结果不能直接进行概率解释。这一点可以通过内部交叉检验进 行评估(具体请参见 SVC 的 probability 参数的定义),但是评估过程的计算量也很大。

由于这些限制条件的存在,我通常只会在其他简单、快速、调优难度小的方法不能满足需求时,才会选择支持向量机。但是,如果你的计算资源足以支撑 SVM 对数据集的训练和交叉检验,那么用它一定能获得极好的效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值