支持向量机是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的,
间隔最大使它区别于感知机。
支持向量机还包括核技巧,这使它成为实质上的非线性分类器。
学习策略可以形式化为求解凸二次规划问题,或者等价于 最小化合页损失
分离超平面:
决策函数:
函数间隔:
几何间隔:
原始目标函数:
上式中的函数距离不影响最优化问题的解(例如一个正实例点的特征带入决策函数:w·x+b = y> 0, 等比例缩放b和w为原来的k倍,kw·x + kb = ky > 0依旧成立。所以可以通过调整k值同时缩放w和b使得约束条件右边的函数距离ky = 1。ps:问题:学习过程的最终结果同样会改变w和b,为什么缩放对结果没影响,而学习过程是有影响并会得到一个有效的决策函数呢?答:缩放体现在决策函数w`x+b上不改变决策函数结果的正负性,而学习过程中w和b不是同比例缩放的,而是遵循让某些点的(w·x +b)=1的约束条件下进行改变的)
确定可以令函数距离=1之后,目标函数就变成这样:(取倒数和乘0.5是为了求导方便)
支持向量之间的距离为:
然后对目标函数构建拉格朗日函数:
求得拉格朗日是式子取到极致的拉格朗日乘子向量 a* = (a1,a2,a3…an),这里面的乘子有很多0,支持向量外的点,乘子a不等于0的点就是支持向量。最终的决策函数就变成:
为了解决线性不可分问题(有坏点)引入软间隔,给每个样本点引入松弛变量,使函数间隔加上松弛变量 >=1。
约束条件变为:
目标函数变为:
C是对松弛变量的惩罚参数,C越大对误分类点的惩罚就越大,C越小对误分类点的惩罚就越小。
所以新目标函数的最小化是要求:
1:支持向量的距离尽量远,函数间隔大。
2:同时函数间隔中间部分的点尽量少(会被惩罚)。
C是调和这两项的系数,需要在实践中去搜索查找
根据目标函数的约束条件:
构建拉格朗日函数:
软间隔支持向量机结果示意图:
上文的目标都是间隔最大,如果把目标换成损失最小,并且为了区别于感知机的只对误分类设定loss,合页损失对即使正确分类,但是非常靠近决策边界的点也要惩罚(合页损失对分类有更高的要求)。合页损失如下(这里的w是L2范数,正则化项):
合页损失示意图:
合页损失最小化过程的最终化简加过和最大化间隔是一样的。
核技巧就是通过映射的方式把原特征映射到高维特征空间中,使原本不是线性问题的问题在高维空间变成线性问题。
常用核函数:
1:多项式核函数:
2:高斯核函数:
3:字符串核函数:
为了简化最优化过程中大量的拉格朗日算子的计算。序列最小化可以帮助我们去逼近最优化的a*,
通过同时改变两个ai,aj(因为sum(yiai)=0的约束条件下,必须至少同时改变两个参数),同时改变两个参数达到此时其他参数不变的情况下的最优(局部),然后不断的选点-局部最优-选点-局部最优。。。,去逼近全局最优的a*。
"""
作业7
1:已知正例点(1,2),(2,2),(3,3),负例点(2,1),(3,2),试求最大间隔分离超平面,间隔边界,及支持向量。
2:调用sklearn 中的svm,尝试改变参数如C ,kernel
"""
#训练数据集
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# import sympy
import random
# %matplotlib
train = np.array([
[1,2],
[2,2],
[3,3],
[2,1],
[3,2],
])
y = np.array([1,1,1,-1,-1])
fig = plt.figure()
plt.scatter(train[:3,0],train[:3,1],c="red",s=30)
plt.scatter(train[3:,0],train[3:,1],c="blue",s=30)
plt.show()
<Figure size 640x480 with 1 Axes>
"""
假设分类超平面为: w1 * x1 + w2 * x2 + b = 0
支持面就是:
w1 * x1 + w2 * x2 + b + 1 = 0
w1 * x1 + w2 * x2 + b - 1 = 0
那么决策函数就是 sign(w1 * x1 + w2 * x2 + b) (=1 if >0 else = -1)
学习过程:
目标函数:min(1/2*||w||2) ps:变量是w
约束条件:yi(w·xi +b -1 ) >= 0
令a1,a2,a3...a5是大于等于0的系数
原问题等价于对偶问题 min( 0.5 * sumsum(ai * aj * yi* yj *(x·xi) ) + sum(ai)) ps:变量是拉格朗日系数a
约束条件:sum(ai*yi)=0 , ai>=0
解出最优解a_ = (a1_, a2_, a3_ ,a4_, a5_) 之后
w_ = sum(ai * yi * xi)
b_ = yj - sum(ai * yi(xi · xj)) ps: (即随便选一个a不为0的点j(决策向量)带入 w_ 的决策函数中,得到b)
"""
print(train)
print(y)
[[1 2]
[2 2]
[3 3]
[2 1]
[3 2]]
[ 1 1 1 -1 -1]
def svmSimpleSMO(train,y,C