学习彭亮《深度学习基础介绍:机器学习》课程
训练集 => 提取特征向量 => 结合一定算法(分类器:eg决策树,KNN) => 得到结果
深度学习出现之前,SVM被认为机器学习中近十几年来最成功的,表现最好的算法。
SVM要寻找区分两类的超平面(hyper plane),使边际(margin)最大
总共可以有无数个超平面
如何选取使得边际最大的超平面:超平面到一侧最近点的距离等于到另一侧最近点的距离,两侧的超平面平行
超平面可以定义为:W*x+b=0 (W:weight vector,b:Bias)
W={w1,w2…wn}特征值个数
假设二维特征向量
把b想象为额外的wight,超平面方程为:w0+w1x1+w2x2=0
超平面右上方的点都满足:w0+w1x1+w2x2>0
超平面左下方的点都满足:w0+w1x1+w2x2<0
调整weight,使得超平面定义边际的两边:
H1:w0+w1x1+w2x2>=1 ,对于所有yi=+1
H2:w0+w1x1+w2x2<=-1,对于所有yi=-1
综合以上两式,yi(w0+w1x1+w2x2)>=1,任意i 公式(1)
所有坐落在边际的两边的超平面上的被称作“支持向量(support vectors)”
分界的超平面和H1或H2上任意一点的距离为:1/||W||
所以margin=1/||W||+1/||W||=2/||W||
利用一些数学推导,公式(1)可变为有限制的凸优化问题(convex quadratic optimization)
利用karush-Kuhn-Tucher(KKT)条件和拉格朗日公式,可以推出MMH可以被表示为以下“决定边界:decision boundary”
其中,
对于任何测试(要归类的实例),带入以上公式,得出的符号是正还是负决定
#coding=utf-8
# @Author: yangenneng
# @Time: 2018-01-11 15:17
# @Abstract:支持向量机 support vector machine
from sklearn import svm
# 定义三个点
X = [[2, 0], [1, 1], [2, 3]]
# 分类标记 用0,1代表两类问题的分类
y = [0, 0, 1]
# 分类器 kernel和函数 用的是线性的 SVC()就是支持向量机
clf=svm.SVC(kernel='linear')
# X矩阵 每行一个实例 y 每个实例对应的class lable(分类标记)
clf.fit(X,y)
# 分类器
print ("'clf:'",clf)
# 哪几个点是支持向量 ('clf.support_vectors_:', array([[ 1., 1.],[ 2., 3.]])) => [1, 1], [2, 3]是支持向量
print ("clf.support_vectors_:",clf.support_vectors_)
# 传入的点中下标为多少的是支持向量 ('clf.support_:', array([1, 2])) => 第二个、第三个是支持向量
print ("clf.support_:",clf.support_)
# 有多少个点是支持向量 ('clf.n_support_:', array([1, 1])) => 两类每类里找出了一个支持向量
print ("clf.n_support_:",clf.n_support_)
# 预测
print clf.predict([2, .0])
#coding=utf-8
# @Author: yangenneng
# @Time: 2018-01-11 15:39
# @Abstract:支持向量机 support vector machine
# 导入矩阵运算的数据包
import numpy as np
# 导入python画图的数据包
import pylab as pl
from sklearn import svm
# 创建40个点
# seed(0)每次运行时产生的点不变
np.random.seed(0)
# randn(20,2) 随机产生20个2维的点:通过正态分布-[2,2](均值 方差都为2),靠下
X=np.r_[np.random.randn(20,2) - [2,2],np.random.randn(20,2)+[2,2]]
# 前20个点归为一类0,后20个点归为一类1
Y=[0]*20+[1]*20
clf=svm.SVC(kernel="linear")
# 装配数据
clf.fit(X,Y)
# 计算w0
w=clf.coef_[0]
# 计算直线斜率
a=-w[0]/w[1]
# 从(-5,5)产生一些连续的值eg:-5 -4 -3 -2 -1 0 1 2 3 4 5
xx=np.linspace(-5,5)
# 直线方程 (clf.intercept_[0])/w[1]截距
yy=a * xx -(clf.intercept_[0])/w[1]
# 和support相平行的两条线
# 取第一个支持向量带入计算下面那条线的截距
b=clf.support_vectors_[0]
yy_down=a*xx + (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 "clf.support_vectors_",clf.support_vectors_
print "clf.coef_",clf.coef_
# 画出三条线
pl.plot(xx,yy,'k+')
pl.plot(xx,yy_up,'k--')
pl.plot(xx,yy_down,'k--')
# 画出周围的点
pl.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],s=80,facecolors='none')
pl.scatter(X[:,0],X[:,1],c=Y,cmap=pl.cm.Paired)
pl.axis('tight')
pl.show()