支持向量机
算法思想
支持向量机(SVM)旨在在一堆样本数据中从低纬空间映射到高维空间中,使得原空间中线性不可分的问题,变成一个线性可分问题。如下图所示
而这时就需要找到一个决策边界来划分数据样本所属不同的类。找到这样一个超平面,使得所有的方块位于这个超平面的一侧,而所有的圆圈位于它的另一侧,但是这个超平面却可能有无穷多个。如下图
进一步探究便得到支持向量机中最核心的问题,就是支持向量机中选择的决策边界要将数据样本分对,
B
1
:
w
⋅
x
+
b
=
0
B_1:w·x+b=0
B1:w⋅x+b=0为决策边界,而值得注意的是
w
w
w和
x
x
x是内积运算。
但是支持向量机中,不但要使得决策边界能将数据样本分类清楚,还需要使得决策平面边缘最大化,所以模型中将决策边界向两边平移直至决策边界任意一个数据样本(支持向量)重合时停止,得到一个决策平面,如下图所示:
要注意以上只是支持向量机的基本思想,到实际建模时还需要考虑松弛变量,惩罚系数,以及非线性分类和核函数等知识的引入。
建立模型
由上面的算法思想知道,支持向量机中,不但要使得决策边界能将数据样本分类清楚,还需要使得决策平面边缘最大化。
决策边界
如果想要将数据样本分类,需要满足下列条件:
y
=
{
w
⋅
x
i
+
b
≥
1
if y=1
w
⋅
x
i
+
b
≤
1
if y=-1
y= \begin{cases} w·x_i + b≥1& \text{if y=1}\\ w·x_i + b≤1& \text{if y=-1} \end{cases}
y={w⋅xi+b≥1w⋅xi+b≤1if y=1if y=-1
将上式化简得:
y
i
(
w
⋅
x
i
+
b
)
≥
1
y_i(w·x_i + b)≥1
yi(w⋅xi+b)≥1
边缘最大化
设
x
0
x_0
x0是决策边缘
b
11
b_{11}
b11上的点,那么算得
x
0
x_0
x0与决策边缘
b
11
b_{11}
b11的距离再乘以2,就可得到决策平面的距离
d
d
d,由点到直线的距离公式可以知道
d
=
2
∣
w
⋅
x
0
+
b
∣
∣
∣
w
∣
∣
d =2 \frac{|w·x_0 + b|}{||w||}
d=2∣∣w∣∣∣w⋅x0+b∣
其中
b
11
:
w
⋅
x
0
+
b
=
1
b_{11}:w·x_0 + b=1
b11:w⋅x0+b=1,所以有
m
a
x
d
=
2
∣
∣
w
∣
∣
max \ d= \frac{2}{||w||}
max d=∣∣w∣∣2
再对其进行简化
d
=
1
2
w
T
w
d= \frac{1}{2}w^{T}w
d=21wTw
综上所述,支持向量机两个基本的建模条件是:
{
目
标
函
数
:
m
a
x
d
=
1
2
w
T
w
约
束
条
件
:
y
i
(
w
x
i
+
b
)
≥
1
\begin{cases} 目标函数:max\ d= \frac{1}{2}w^{T}w\\ 约束条件:y_i(wx_i + b)≥1 \end{cases}
{目标函数:max d=21wTw约束条件:yi(wxi+b)≥1
模型求解
支持向量机使用了拉格朗日乘数法对目标函数进行求解。
{
目
标
函
数
:
m
a
x
d
=
1
2
w
T
w
约
束
条
件
:
y
i
(
w
x
i
+
b
)
≥
1
\begin{cases} 目标函数:max\ d= \frac{1}{2}w^{T}w\\ 约束条件:y_i(wx_i + b)≥1 \end{cases}
{目标函数:max d=21wTw约束条件:yi(wxi+b)≥1
令
L
P
=
1
2
w
T
w
−
∑
i
=
1
l
α
i
y
i
(
w
x
i
+
b
)
+
∑
i
=
1
l
α
i
L_P=\frac{1}{2}w^{T}w-\sum_{i=1}^{l}α_iy_i(wx_i + b)+\sum_{i=1}^{l}α_i
LP=21wTw−i=1∑lαiyi(wxi+b)+i=1∑lαi
分别对
w
w
w和
b
b
b求偏导
将上面的两条式子代入
L
P
L_P
LP中得到
L
P
L_P
LP的对偶函数
{
目
标
函
数
:
m
a
x
L
D
=
∑
i
=
1
N
α
i
−
1
2
∑
i
j
α
i
α
j
y
i
y
j
x
i
⋅
x
j
约
束
条
件
:
∑
i
α
i
y
i
=
0
,
α
i
≥
0
\begin{cases} 目标函数:max \ L_D=\sum_{i=1}^{N}α_i- \frac{1}{2}\sum_{ij}α_iα_jy_iy_jx_i·x_j\\ 约束条件:\sum_{i}α_iy_i=0 ,α_i\geq0 \end{cases}
{目标函数:max LD=∑i=1Nαi−21∑ijαiαjyiyjxi⋅xj约束条件:∑iαiyi=0,αi≥0
到这一步,未知的量只剩下
α
α
α,而且约束条件也比较简单,这个二次优化问题可以使用数值计算技术进行求解,如二次规划。计算出α后,可用下面的式子对
w
w
w和
b
b
b进行求解。
设
(
x
s
,
y
s
)
(x_s,y_s)
(xs,ys)是已知的支持向量,代入决策边缘中,得
y
s
(
x
s
⋅
w
+
b
)
=
1
y_s(x_s·w+b)=1
ys(xs⋅w+b)=1
y
s
(
x
s
⋅
∑
i
∈
S
α
i
y
i
x
i
+
b
)
=
1
y_s(x_s·\sum_{i\in S}α_iy_ix_i+b)=1
ys(xs⋅∑i∈Sαiyixi+b)=1
y
s
2
(
x
s
⋅
∑
i
∈
S
α
i
y
i
x
i
+
b
)
=
y
s
y_s^{2}(x_s·\sum_{i\in S}α_iy_ix_i+b)=y_s
ys2(xs⋅∑i∈Sαiyixi+b)=ys
b
=
y
s
−
x
s
⋅
∑
i
∈
S
α
i
y
i
x
i
b =y_s-x_s·\sum_{i\in S}α_iy_ix_i
b=ys−xs⋅∑i∈Sαiyixi
b
=
1
N
∑
s
∈
S
(
y
s
−
x
s
⋅
∑
i
∈
S
α
i
y
i
x
i
)
b =\frac{1}{N}\sum_{s\in S}(y_s-x_s·\sum_{i\in S}α_iy_ix_i)
b=N1∑s∈S(ys−xs⋅∑i∈Sαiyixi)
已知
w
w
w和
b
b
b便可代入
B
1
:
w
⋅
x
+
b
=
0
B_1:w·x+b=0
B1:w⋅x+b=0求出决策边界。
实际应用问题
模型中,约束条件要求决策边界将所有类分开,但是在实际应用中,这个约束条件是不能实现的,因为数据样本中会出现“你中有我,我中有你”的情况,即出现线性不可分的情况。所以,根据这一情况支持向量机对模型提出了软边缘(soft magrin)的概念。
软边缘
所谓的软边缘,即是在决定决策边界时,允许一定的训练误差,以解决线性不可分的情况。如下图:
原来的数学模型将变为以下式子:
{
目
标
函
数
:
m
i
n
d
=
1
2
w
T
w
+
C
(
∑
i
=
1
N
ξ
i
)
k
约
束
条
件
:
y
i
(
w
x
i
+
b
)
≥
1
−
ξ
i
\begin{cases} 目标函数:min\ d= \frac{1}{2}w^{T}w+C(\sum_{i=1}^{N}\xi_i)^k\\ 约束条件:y_i(wx_i + b)≥1-\xi_i \end{cases}
{目标函数:min d=21wTw+C(∑i=1Nξi)k约束条件:yi(wxi+b)≥1−ξi
其中
C
C
C和
k
k
k是用户指定的参数对五分训练实例加罚,通常
k
k
k取1,
C
C
C根据模型在确认上的性能选择。
模型求解的方法与上面介绍的都一致,最后得出来的结果与线性可分的情况也极为之相似,不同在于约束条件。
{
目
标
函
数
:
L
D
=
∑
i
=
1
N
α
i
−
1
2
∑
i
j
α
i
α
j
y
i
y
j
x
i
⋅
x
j
约
束
条
件
:
∑
i
α
i
y
i
=
0
,
0
≤
α
i
≤
C
\begin{cases} 目标函数:L_D=\sum_{i=1}^{N}α_i- \frac{1}{2}\sum_{ij}α_iα_jy_iy_jx_i·x_j\\ 约束条件:\sum_{i}α_iy_i=0 ,0\leq α_i\leq C \end{cases}
{目标函数:LD=∑i=1Nαi−21∑ijαiαjyiyjxi⋅xj约束条件:∑iαiyi=0,0≤αi≤C
核技术
以上的所有介绍都是基于线性分类,但是涉及到非线性分类,就无能为力了。所以需要引入关于非线性分类的技术,首先最容易想到是对数据进行非线性变换。即将非线性的问题转化为线性问题。
那么决策边界就可以表示为:
f
(
x
)
=
w
⋅
ϕ
(
x
)
+
b
=
0
f(x)=w·\phi(x)+b=0
f(x)=w⋅ϕ(x)+b=0
那么优化目标就变为了
{
目
标
函
数
:
m
i
n
d
=
1
2
w
T
w
约
束
条
件
:
y
i
(
w
⋅
ϕ
(
x
i
)
+
b
)
≥
1
\begin{cases} 目标函数:min\ d= \frac{1}{2}w^{T}w\\ 约束条件:y_i(w ·\phi (x_i )+ b)≥1 \end{cases}
{目标函数:min d=21wTw约束条件:yi(w⋅ϕ(xi)+b)≥1
根据上面介绍过的拉格朗日乘数法对优化目标进行求解,得到
{
目
标
函
数
:
L
D
=
∑
i
=
1
N
α
i
−
1
2
∑
i
j
N
α
i
α
j
y
i
y
j
ϕ
(
x
i
)
⋅
ϕ
(
x
j
)
约
束
条
件
:
∑
i
=
1
N
α
i
y
i
=
0
,
0
≤
α
i
\begin{cases} 目标函数:L_D=\sum_{i=1}^{N}α_i- \frac{1}{2}\sum_{ij}^{N}α_iα_jy_iy_j\phi(x_i)·\phi(x_j)\\ 约束条件:\sum_{i=1}^{N}α_iy_i=0 ,0\leq α_i \end{cases}
{目标函数:LD=∑i=1Nαi−21∑ijNαiαjyiyjϕ(xi)⋅ϕ(xj)约束条件:∑i=1Nαiyi=0,0≤αi
但是这种方式会涉及到向量之间的点积,可能导致维度灾难问题,所以不在此深入介绍该方法。为了避免唯独灾难的发生,所以就引入了核技术。
k
(
x
i
,
x
j
)
=
⟨
ϕ
(
x
i
)
,
ϕ
(
x
j
)
⟩
=
ϕ
(
x
i
)
T
⋅
ϕ
(
x
j
)
k(x_i,x_j)=⟨ϕ(x_i),ϕ(x_j)⟩=ϕ(x_i)^{T}·ϕ(x_j)
k(xi,xj)=⟨ϕ(xi),ϕ(xj)⟩=ϕ(xi)T⋅ϕ(xj)
即
x
i
x_i
xi和
x
j
x_j
xj 在特征空间的内积等于它们在原始样本空间中通过函数
k
(
⋅
,
⋅
)
k(⋅,⋅)
k(⋅,⋅)计算的结果,于是上面的公式可以演化为:
{
目
标
函
数
:
m
a
x
a
∑
i
=
1
N
a
i
−
1
2
∑
i
,
j
=
1
N
a
i
a
j
y
i
y
j
k
(
x
i
,
x
j
)
约
束
条
件
:
∑
i
α
i
y
i
=
0
,
0
≤
α
i
\begin{cases} 目标函数:\underset{a}{max}\sum_{i=1}^Na_i-\frac{1}{2}\sum_{i,j=1}^{N}a_ia_jy_iy_jk(x_i,x_j)\\ 约束条件:\sum_{i}α_iy_i=0 ,0\leq α_i \end{cases}
{目标函数:amax∑i=1Nai−21∑i,j=1Naiajyiyjk(xi,xj)约束条件:∑iαiyi=0,0≤αi
求解后,最终的决策函数模型为:
f
(
x
)
=
w
T
ϕ
(
x
)
+
b
=
∑
i
=
1
N
a
i
y
i
ϕ
(
x
i
)
T
⋅
ϕ
(
x
)
+
b
=
∑
i
=
1
N
a
i
y
i
k
(
x
,
x
i
)
+
b
\begin{aligned}f(x)&=w^T\phi(x)+b\\ &=\sum_{i=1}^{N}a_iy_i\phi(x_i)^T·\phi(x)+b\\ &=\sum_{i=1}^{N}a_iy_ik(x,x_i)+b \end{aligned}
f(x)=wTϕ(x)+b=i=1∑Naiyiϕ(xi)T⋅ϕ(x)+b=i=1∑Naiyik(x,xi)+b
这里的函数
k
(
⋅
,
⋅
)
k(⋅,⋅)
k(⋅,⋅)就是核函数,通过核函数,我们就不比直接去计算高维甚至无穷维特征空间中的内积,直接在原始输入空间进行计算,进而降低计算难度。
Mercer定理
对非线性SVM使用的核函数主要的要求是,必须存在一个相应的变换,使得计算一堆向量的核函数等价于在变换后的空间中计算这对向量的点积。这个要求可以用Mercer定理形式化地陈述。
Mercer定理 核函数K可以表示为:
K
(
u
,
v
)
=
ϕ
(
u
)
⋅
ϕ
(
v
)
K(u,v) = \phi(u)·\phi(v)
K(u,v)=ϕ(u)⋅ϕ(v)
当且仅当对于任意满足
∫
g
(
x
)
2
d
x
\int g(x)^2dx
∫g(x)2dx为有限值得函数
g
(
x
)
g(x)
g(x),则
∫
K
(
x
,
y
)
g
(
x
)
g
(
y
)
d
x
d
y
≥
0
\int K(x,y) g(x)g(y)dx dy\geq0
∫K(x,y)g(x)g(y)dxdy≥0
-
线性核函数
κ ( x , x i ) = x ⋅ x i κ(x,x_i)=x⋅x_i κ(x,xi)=x⋅xi
线性核,主要用于线性可分的情况,我们可以看到特征空间到输入空间的维度是一样的,其参数少速度快,对于线性可分数据,其分类效果很理想,因此我们通常首先尝试用线性核函数来做分类,看看效果如何,如果不行再换别的 -
多项式核函数
κ ( x , x i ) = ( ( x ⋅ x i ) + 1 ) d κ(x,x_i)=((x⋅x_i)+1)^{d} κ(x,xi)=((x⋅xi)+1)d
多项式核函数可以实现将低维的输入空间映射到高纬的特征空间,但是多项式核函数的参数多,当多项式的阶数比较高的时候,核矩阵的元素值将趋于无穷大或者无穷小,计算复杂度会大到无法计算。 -
sigmoid核函数
κ ( x , x i ) = t a n h ( η < x , x i > + θ ) κ(x,x_i)=tanh(η<x,x_i>+θ) κ(x,xi)=tanh(η<x,xi>+θ)
采用sigmoid核函数,支持向量机实现的就是一种多层神经网络。
因此,在选用核函数的时候,如果我们对我们的数据有一定的先验知识,就利用先验来选择符合数据分布的核函数;如果不知道的话,通常使用交叉验证的方法,来试用不同的核函数,误差最下的即为效果最好的核函数,或者也可以将多个核函数结合起来,形成混合核函数。在吴恩达的课上,也曾经给出过一系列的选择核函数的方法:
- 如果特征的数量大到和样本数量差不多,则选用LR或者线性核的SVM;
- 如果特征的数量小,样本的数量正常,则选用SVM+高斯核函数;
- 如果特征的数量小,而样本的数量很大,则需要手工添加一些特征从而变成第一种情况。
支持向量机的特点
- SVM学习问题可以表示为凸优化问题,因此可以利用已知的有效算法发现目标函数的全局最小值。而其他的分类方法(如基于规则的分类器和人工神经网络)都采用一种基于贪心学习的策略来搜索假设空间,这种方法一般只能获得局部最优解。
- SVM通过最大化决策边界的边缘来控制模型的能力。尽管如此,用户必须提供其他参数,如使用的核函数的类型,为了引入松弛变量所需的代价函数C等。
- 通过对数据中每个分类属性值引入一个哑变量,SVM可以应用于分类数据。例如,如果婚姻状况有三个值{单身,已婚,离异},可以对每一个属性值引入一个二元变量。
手写数字的识别(python实现SVM)
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC,SVC
from sklearn.metrics import classification_report
import os
import numpy as np
#=============part1 读入数据=====================
def get_data(path):
name = os.listdir(path)
attribute = [] #创建空列表装载样品属性
label = [] #创建空列表装载样品标签
for i in name:
file =open(path+'\\'+i,'r',encoding='utf-8')
data1 = file.read()
data1 = list(data1.replace('\n',''))
data2 = i[0]
attribute.append(data1)
label.append(data2)
return [np.array(attribute),np.array(label)]
[X_train,y_train] = get_data('./trainingDigits')
[X_test,y_test] = get_data('./testDigits')
#=============part3 标准化数据========================
ss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_test = ss.transform(X_test)
# ===================Part4 创建一个高斯核函数的svm分类器=============================
lsvc = LinearSVC()
lsvc.fit(X_train, y_train)
y_predict = lsvc.predict(X_test)
#参数:gamma-高斯核函数的西格玛的值
#参数:C—惩罚项系数
svm = SVC(kernel='rbf', random_state=0, gamma=0.0001, C=100)
svm.fit(X_train, y_train)
y_predict = svm.predict(X_test)
#==============part5 分类器的评价====================
print( 'The Accuracy of Linear SVC is: ', lsvc.score(X_test, y_test))
print( 'The Accuracy of Linear SVC is: ', svm.score(X_test, y_test))
print (classification_report(y_test,y_predict,target_names = ["1","9"]))
程序结果
Gamma | C | 分类精度 |
---|---|---|
10 | 1 | 0.478494623655914 |
0.1 | 10 | 0.478494623655914 |
0.001 | 1 | 0 .9946236559139785 |