作 者:echoy189
介 绍:spark数据处理与算法交流
公众号:spark推荐系统
在上文中,我们了解了SVM处理线性(硬间隔/软间隔)可分的情况,而对于非线性的情况,SVM的处理方法是选择一个核函数K(),通过将数据映射到高维空间,来解决在原始低维空间中线性不可分的问题
目录
判别式函数另一种表达形
SVM的升维
引入核函数
常用核函数
SVM算法流程总结
代码展示
一)判别式函数另一种表达形
对于线性SVM来说,判别式函数
由于(线性可分SVM推导出w) 可参考 : 机器学习|支持向量机SVM(二)
所以可将判别式转换成下式:
可以得到结论:每点在计算判别函数结果时需要求得待判断点和所有训练集样本的内积
升维是一种处理线性不可分问题的方式,通常把原始的x映射到更高维空间ϕ(x)上
ϕ(x):指的是将x,通过函数变化映射到高维空间的函数
比如多项式回归:
可以将二元特征(x1,x2)映射为五元特征(x1,x2,x1²,x2²,x1x2)这样在五元空间中有些二元空间里线性不可分的问题就变得线性可分了
二)SVM的升维
对于线性SVM来说,最优化问题为:
如果使用ϕ(x) 对训练集升维,最优化问题就变成了:
看似这种升维方式已经完美解决了线性不可分问题,但是带来一个新的问题:
假设使用多项式回归的方式进行升维,对于二维x1,x2升维后的结果是x1,x2,x1²,x2²,x1x2变成五维;三维x1,x2,x3就变成了19维;假如10维 或更多就会导致维度爆炸。而且升维之后还需要做向量的内积,时间和空间都会消耗特别大
三)引入核函数
在svm学习过程中
只需求得ϕ(xi)▪ϕ(xj)的结果,并不需知道具体的ϕ(x)是什么,所以直接跳过ϕ(x),来定义ϕ(xi)▪ϕ(xj)的结果,这样既可以达到升维的效果,又可以避免维度爆炸的问题
定义K(x,z) = ϕ(x)▪ϕ(z)
此时,对偶问题的目标函数变为了:
判别式函数变为了:
四)常用核函数
1.线性核函数 K(x,z) = x▪z
这实际上是原始空间上面的内积,并没有达到升维效果。它存在的意见就是在sklearn中svm类中没有专门的线性可分和不可分,在这种通用的表达形式上通过核函数的选择来达到区分线性可不可分SVM 的目的
2.多项式核函数 K(x,z) = (γx▪z + r)ⁿ
但是多项式核函数的参数多,当多项式的阶数比较高的时候,核矩阵的元素值将趋于无穷大或者无穷小,计算复杂度会大到无法计算
3.高斯核函数 K(x,z) = exp(-γ||x-z||²) (最常用)
高斯径向基函数是一种局部性强的核函数,其可以将一个样本映射到一个更高维的空间内,该核函数是应用最广的一个,无论大样本还是小样本都有比较好的性能,而且其相对于多项式核函数参数要少,因此大多数情况下在不知道用什么核函数的时候,优先使用高斯核函数
4.sigmoid核函数 K(x,z) = tanh(γx▪z + r)
采用sigmoid核函数,支持向量机实现的就是一种多层神经网络
五)SVM算法流程总结
1.选择某个核函数及对应的超参数
2.选择惩罚系数C
3.构造最优化问题
4.利用SMO算法求解一组α
5.根据α计算w
6.根据α找到全部支持向量,计算每个支持向量对应的b
7.对b 求均值得到最终的b
学的超平面为:
最终的判别函数为:
六)代码展示
目的:将线性不可分的数据变为线性可分;
方法:一维数据升到二维
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-4, 5, 1)
y = np.array((x >= -2) & (x <= 2), dtype='int')
plt.scatter(x[y == 0], [0] * len(x[y == 0]))
plt.scatter(x[y == 1], [0] * len(x[y == 1]))
plt.show()
def gaussian(x, l):
# 此处直接将超参数 γ 设定为 1.0;
# 此处 x 表示一维的样本,也就是一个具体的值,l 相应的也是一个具体的数,
因为 l 和 x 一样,从特征空间中选定;
gamma = 1.0
# 此处因为 x 和 l 都只是一个数,不需要再计算模,可以直接平方;
return np.exp(-gamma * (x - l) ** 2)
# 设定地标 l1、l2 为 -1和1
l1, l2 = -1, 1
x_new = np.empty((len(x), 2))
for i, data in enumerate(x):
x_new[i, 0] = gaussian(data, l1)
x_new[i, 1] = gaussian(data, l2)
plt.scatter(x_new[y == 0, 0], x_new[y == 0, 1])
plt.scatter(x_new[y == 1, 0], x_new[y == 1, 1])
plt.show()
往期精选
机器学习-线性回归(一)
长按识别二维码关注我