计算机系统应用教程网站

网站首页 > 技术文章 正文

机器学习 | 算法笔记(三)- 支持向量机算法以及代码实现

btikc 2024-11-19 02:03:50 技术文章 2 ℃ 0 评论

概述

上一篇讲述了《机器学习|算法笔记(二)线性回归算法以及代码实现》,本篇讲述机器学习算法支持向量机,内容包括模型介绍及代码实现。

支持向量机(SVM)

支持向量机(Support Vector Machine,常简称为SVM)是一种监督式学习的方法,可广泛地应用于统计分类以及回归分析。支持向量机属于一般化线性分类器,这种分类器的特点是他们能够同时最小化经验误差与最大化几何边缘区,因此支持向量机也被称为最大边缘区分类器。

如上图所示,SVM的目的是寻找一个最优分割面,使得分类分类间隔最大化。而最优分割面求解原则可以大致归纳如下:

最优决策面能够容忍更多噪声—>所有样本与分割超平面的距离尽可能远—>最差的样本(离分割超平面最近的样本)与分割超平面的距离要尽可能远。

边际(margin)是什么?

边际就是某一条线距离它两侧最近的点的距离之和。

SVM 将会寻找可以区分两个类别并且能使边际(margin)最大的超平面(hyper plane),即划分超平面。

所有坐落在边际超平面上的点被称作支持向量(support vectors)

支持向量(support vector)就是刚好贴在边际所在的平面上的点,它们是用来定义边际的,是距离划分超平面最近的点。

作用: 支持向量因为支撑了边际区域,并且用于建立划分超平面。

注意: 支持向量可能不止一侧一个,有可能一侧有多个点都贴在边际平面上。

在线性不可分的情况下,数据集在空间中对应的向量无法被一个超平面区分开,如何处理?

两个步骤来解决:

  • 利用一个非线性的映射把原数据集中的向量点转化到一个更高维度的空间中(比如下图将二维空间中的点映射到三维空间)
  • 在这个高维度的空间中找一个线性的超平面来根据线性可分的情况处理

比如想要将红点和蓝点变成线性可分的,那么就将映射 y=x 变成映射 y=x^2,这样就线性可分了。



支持向量机(SVM)特性

(1)训练好的模型的算法复杂度是由支持向量的个数决定的,而不是由数据的维度决定的。所以 SVM 不太容易产生 overfitting。

(2)SVM 训练出来的模型完全依赖于支持向量,即使训练集里面所有非支持向量的点都被去除,重复训练过程,结果仍然会得到完全一样的模型。

(3)一个 SVM 如果训练得出的支持向量个数比较少,那么SVM 训练出的模型比较容易被泛化。

代码实现

SVM.py

print(__doc__)

# 导入相关的包
import numpy as np
import pylab as pl  # 绘图功能
from sklearn import svm

# 创建 40 个点
np.random.seed(0) # 让每次运行程序生成的随机样本点不变
# 生成训练实例并保证是线性可分的
# np._r表示将矩阵在行方向上进行相连
# random.randn(a,b)表示生成 a 行 b 列的矩阵,且随机数服从标准正态分布
# array(20,2) - [2,2] 相当于给每一行的两个数都减去 2
X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]
# 两个类别 每类有 20 个点,Y 为 40 行 1 列的列向量
Y = [0] * 20 + [1] * 20

# 建立 svm 模型
clf = svm.SVC(kernel='linear')
clf.fit(X, Y)

# 获得划分超平面
# 划分超平面原方程:w0x0 + w1x1 + b = 0
# 将其转化为点斜式方程,并把 x0 看作 x,x1 看作 y,b 看作 w2
# 点斜式:y = -(w0/w1)x - (w2/w1)
w = clf.coef_[0]  # w 是一个二维数据,coef 就是 w = [w0,w1]
a = -w[0] / w[1]  # 斜率
xx = np.linspace(-5, 5)  # 从 -5 到 5 产生一些连续的值(随机的)
# .intercept[0] 获得 bias,即 b 的值,b / w[1] 是截距
yy = a * xx - (clf.intercept_[0]) / w[1]  # 带入 x 的值,获得直线方程

# 画出和划分超平面平行且经过支持向量的两条线(斜率相同,截距不同)
b = clf.support_vectors_[0] # 取出第一个支持向量点
yy_down = a * xx + (b[1] - a * b[0])
b = clf.support_vectors_[-1] # 取出最后一个支持向量点
yy_up = a * xx + (b[1] - a * b[0])

# 查看相关的参数值
print("w: ", w)
print("a: ", a)
print("support_vectors_: ", clf.support_vectors_)
print("clf.coef_: ", clf.coef_)

# 在 scikit-learin 中,coef_ 保存了线性模型中划分超平面的参数向量。形式为(n_classes, n_features)。若 n_classes > 1,则为多分类问题,(1,n_features) 为二分类问题。

# 绘制划分超平面,边际平面和样本点
pl.plot(xx, yy, 'k-')
pl.plot(xx, yy_down, 'k--')
pl.plot(xx, yy_up, 'k--')
# 圈出支持向量
pl.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
           s=80, facecolors='none')
pl.scatter(X[:, 0], X[:, 1], c=Y, cmap=pl.cm.Paired)

pl.axis('tight')
pl.show()

运行结果展示

总结

SVM优点

- 可用于线性/非线性分类,也可以用于回归,泛化错误率低,也就是说具有良好的学习能力,且学到的结果具有很好的推广性。

- 可以解决小样本情况下的机器学习问题,可以解决高维问题,可以避免神经网络结构选择和局部极小点问题。

- SVM是最好的现成的分类器,现成是指不加修改可直接使用。并且能够得到较低的错误率,SVM可以对训练集之外的数据点做很好的分类决策。

SVM缺点

- 对参数调节和和函数的选择敏感。

本篇主要讲述机器学习算法支持向量机以及代码实现,下一篇讲述机器学习算法决策树,欢迎关注。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表