本篇内容是xxxx深度学习基础课程视频上的,如有侵权,请与我联系,谢谢!
本博客可能写的没有什么条理,主要目的是为了记录学习中的关键点,方便自己日后回顾。
一,理论知识
上图中有红绿蓝三条线,那条线分类效果最好呢?明显是红色的线,为什么红线比蓝线效果好呢?
1)SVM寻找分两类的超平面(hyper plane),使边际(magrin)最大
下图解释一下边际最大:
2)总共可以有多少个可能的超平面?答案是有无数条
如何选取使边际(margin)最大的的超平面(Max Margin Hyperplane)?
超平面到一侧最近点的距离等于到另一侧最近点的距离
,两侧的两个超平面平行
3)线性可分和线性不可分
4)超平面定义与公式建立
n是特征值的个数
X:是训练实例
b:bias
用yi=+1表示一类
yi=-1表示另一类
所有坐落在边际的两边的超平面上的点被成为“支持向量(support vectors)”
分界的超平面和H1或H2上任意一点的距离为:
5) SVM如何找出最大边际的超平面(MMH)?
利用一些数学推导…
最终结果是
就是我们要求的最大边际超平面,其中:
yi是支持向量点
Xi是支持向量点的类别标记
XT是要测试的实例
ai和b0都是单一数值型参数,由以上推导算法得到
l是支持向量点的个数
6)SVM求解超平面实例 (线性可分的情况)
a) 首先假设已经求得支持向量点(2,3),(1,1)
b) 用两个点求weight vector:
w=(2,3)-(1,1)=(w0,w1)=(a,2a)
c) w0X0+w1X1+b0=-1,w0X0+w1X1+b0=1
根据(1,1) g(1,1)=-1 -》a+2a+b0=-1
根据(2,3) g(2,3)=1 -》2a+6a+b0=-1
求得 a=2/5 b0=-11/5
w=(2/5,4/5)
g(x)=2/5x0+4/5x1-11/5=x0+2X1-5.5
7) 代码实现
from sklearn import svm
#线性可分的情况下应用SVM分类
x=[[2,0],[1,1],[2,3]] #训练点
y=[0,0,1] #类型标签
clf=svm.SVC(kernel='linear') #建立分类器 kernel='linear' 线性核函数
clf.fit(x,y) #创建模型
print(clf)
#打印支持向量点
print(clf.support_vectors_)
#打印支持向量点下标
print(clf.support_)
#打印每个分类支持向量点的个数
print(clf.n_support_)
#预测一个新点类型
x1=[[2,0]]
print(clf.predict([[2,4]]))
8)结果
7)线性可分的情况,SVM分类
创建40个随机点,并且是线性可分的,用SVM算法将这些点进行分类,并画出相关图。
a)代码
import numpy as np #numpy是支持矩阵运算的数据包
import pylab as pl #画图的功能
from sklearn import svm #导入svm库
#创建40个独立点,并且是线性可分的
np.random.seed(0) #保证下次运行程序时产生的点和本次一样
# np.random.randn(20,2) 产生20个2维的点
# - [2,2] 均值是2,方差是2,“-”表示在下方 “+”表示上方
X=np.r_[np.random.randn(20,2) - [2,2],np.random.randn(20,2) + [2,2]]
Y=[0]*20+[1]*20
#创建模型
clf=svm.SVC(kernel='linear')
clf.fit(X,Y)
#获得独立的超平面,中间那条线 w0*x+w1*y+w3=0 -> y=-w0/w1-w3/w1
w=clf.coef_[0] #获取w值 w0 w1
a=-w[0]/w[1] #斜率
xx=np.linspace(-5,5) #产生-5到5的连续值,x=-5,-4,-3,-2,-1,0,1,2,3,4,5
yy=a*xx-(clf.intercept_[0])/w[1] #(clf.intercept_[0])/w[1] 截距
#画出与超平面平行的且经过支持向量的平行线
b=clf.support_vectors_[0] #获取支持向量的第一个点
yy_down=a*xx+(b[1]-a*b[0]) #(b[1]-y)/b[0]=a -> y=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_)
#画出线,点,和支持向量
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='red')
pl.scatter(X[:,0],X[:,1],c=Y,cmap=pl.cm.Paired)
pl.axis('tight')
pl.show()
b)结果
二、线性不可分情况
1) 数据集在空间中对应的向量不可被一个超平面区分开
两个步骤来解决:
a)利用一个非线性的映射把原始数据集中的向量点转换到一个更高维度的空间中
b)在这个高维度的空间中找一个线性的超平面来根据线性可分的情况处理
2)如何利用非线性映射把原始数据转化到高维中?
例子:
3)
a) 如何选择合理的非线性转化把数据转化到高维度中?
b) 如何解决计算内积时算法复杂度非常高的问题?
答案是使用 核方法(kernel trick)
c) 核方法动机:
d)核方法基本思想:
e)常用的核函数
f)如何选择使用哪个核函数?
g)核函数举例
h)人脸识别源代码
…