机器学习:支持向量机3

本文来自同步博客。看原博客地址会有更好的体验。python

前面两篇文章介绍了支持向量机SVM的基本原理,并利用Python实践了分割超平面的求解过程。git

本篇文章将介绍SVM如何对非线性可分的数据进行分类。github

基本原理

SVM处理线性不可分数据的关键在于把低维空间中线性不可分的数据映射到高维空间使其线性可分。而后再按线性可分数据进行处理。函数

就像下方展现的内容。有圆圈和星星两种不一样的数据,在左边的一维空间中它们是没法线性分割的;而在右边二维空间中却能够用一条横线进行分割。测试

 

 

基于这个原理,很直观地,找到一个映射函数把样本向量x映射到高维空间的一个向量z。例如:对$-\vec{x}=(x_1, x_2)-$,能够有选择相似$-\vec{z}=(1,x_1,x_2,x_1^2, x_2^2, 2x_1x_2)-$的映射。利用这个映射,能够计算出每一个数据点在高维空间中对应的向量。最后用这些向量求解$-\vec{\alpha}、\vec{w}、b-$。spa

这里须要思考一个问题:这样把每一个数据都映射成另外一个向量,而后在进行计算,比线性可分模型的SVM复杂了好多好多。还有要找到这样的映射也不是一件容易的事。有没有比较好的作法?答案确定是有的,能够利用“核技巧”。3d

核技巧

实际上咱们不须要计算每一个数据在高维空间的向量。由于不管是求解$-\vec{\alpha}-$,仍是求解分割超平面的$-\vec{w}-$和$-b-$,咱们须要仅仅只有一个高维空间下对应两个向量的向量积。例若有数据点$-\vec{x_1},\vec{x_2}-$,对应的映射后的结果为$-\vec{z_1},\vec{z_2}-$,那么咱们要的仅仅是$-\vec{z_1}^{T} \vec{z_2}-$这个向量积。这种处理方式且称为核技巧,用函数$-K(x_1,x_2)-$表示向量积$-\vec{z_1}^{T} \vec{z_2}-$。code

首先,构造二次规划函数只须要$-K(x_1,x_2)-$:
$$
L(\vec{\alpha}) = \sum_{i}^{n}{\alpha_i} - \frac{1}{2}\sum_{i}{n}{\sum_{j}{n}{\alpha_i \alpha_j y_i y_j \vec{z_i}^{T} \vec{z_j}}}, \sum_{i}^{n}{\alpha_i y_i} = 0, \alpha_i,\alpha_j \ge 0, i,j = 1,2...n
$$blog

获得$-\vec{\alpha}-$向量后,能够获得$-\vec{w}-$:
$$
w = \sum_{i}^{n}{\alpha_i y_i \vec{z_i}}
$$
取其中一个支持向量(假设下标为v),可计算b,也只须要$-K(x_1,x_2)-$:
$$
b = \frac{1}{y_v} - \vec{w}^{T}\vec{z_v} = \frac{1}{y_v} - \sum_{i}^{n}{\alpha_i y_i \vec{z_i}^{T}}\vec{z_v} = \frac{1}{y_v} - \sum_{i}^{n}{\alpha_i y_i K(\vec{z_i},\vec{z_v})}
$$get

最后,对新数据的决策规则函数Rule以下,也只须要$-K(x_1,x_2)-$:
$$
Rule: sign(\sum_{i}^{n}{\alpha_i y_i K(\vec{x_i},\vec{u})} + b)
$$

经常使用核函数

1. 线性核函数

$$
K(\vec{x_1},\vec{x_2}) = \vec{x_1}^{T}\vec{x_2}
$$
这是$-\vec{x_1}^{T}\vec{x_2}-$自己,也算一个线性核函数,同时它也是下面介绍的多项式核函数的特例。

2. 多项式核函数

$$
K(\vec{x_1},\vec{x_2}) = (\vec{x_1}^{T}\vec{x_2} + c)^{d}
$$

这种核函数利用多项式展开能够了解它将把原向量映射到某个维度可数的空间内,维度数目与原向量的维度以及参数c、d有关。

3. 高斯核函数

$$
K(\vec{x_1},\vec{x_2}) = exp(-\gamma ||\vec{x_1} - \vec{x_2}||^{d}) = e^{-\gamma ||\vec{x_1} - \vec{x_2}||^{d}}
$$

高斯核函数能够利用泰勒展开,它能够把原向量映射到近乎无穷维空间。

断定核函数是否有效(高维空间是否存在)

通常状况下咱们不须要本身发明核函数,经常使用的核函数已经够用,因此“关于多维Z空间是否存在或者核函数是否有效”的证实能够忽略无论。

这里依旧罗列判断核函数是否有效的两个条件:

  1. 核函数对输入是对称的,$-K(\vec{x_1}, \vec{x_2}) = K(\vec{x_2}, \vec{x_1})-$。

$-\begin{bmatrix}
K(\vec{x_1},\vec{x_1}) & K(\vec{x_1},\vec{x_2}) & \cdots & K(\vec{x_1},\vec{x_n}) \\
\vdots & \vdots & \ddots & \vdots \\
K(\vec{x_n},\vec{x_1}) & K(\vec{x_n},\vec{x_2}) & \cdots & K(\vec{x_n},\vec{x_n}) \\
\end{bmatrix} -$矩阵是一个正半定矩阵。

使用Python展现SVM对线性不可分数据的处理过程

与前一篇文章中的例子比较,这里的代码主要增长了一个kernel函数表示$-K(\vec{x_1},\vec{x_2})-$:

# 核函数: 多项式核函数c=0,d=2
# 选择依据与测试数据有关,这样的映射应该能够把数据分隔开
# 则kernel应该返回的内积以下:
def kernel(x1, x2):
    return np.dot(x1, x2)**2

其次,在生成H矩阵的时候不是直接使用$-\vec{x_1}^{T}\vec{x_2}-$,而是使用kernel函数,以下:

# 计算H矩阵,根据样本数目应是一个len(X)xlen(X)的矩阵
H = np.array(
    [y[i] * y[j] * kernel(X[i], X[j]) for i in range(len(X)) for j in range(len(X))]
).reshape(len(X), len(X))

其余的流程几乎同样,除了绘图代码。

执行结果以下:

 

 

 

本文源码

相关文章
相关标签/搜索