机器学习——支持向量机(SVM)

目录

  • 一、支持向量机
    • 1.简介
    • 2.SVM原理
    • 3.非线性SVM
  • 二、几个基础知识点
    • 1.函数间隔
    • 2.几何间隔
    • 3.核函数
  • 三、代码学习
    • 1.SVM在sklearn下
    • 2.SVM中使用多项式特征
    • 3.高斯核函数
    • 4、超参数 γ γ γ

一、支持向量机

1.简介

支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。
支持向量机的基本思想是SVM从线性可分情况下的最优分类面发展而来。最优分类面就是要求分类线不但能将两类正确分开(训练错误率为0),且使分类间隔最大。SVM考虑寻找一个满足分类要求的超平面,并且使训练集中的点距离分类面尽可能的远,也就是寻找一个分类面使它两侧的空白区域(margin)最大。(SVM算法就是为找到距分类样本点间隔最大的分类超平面 ( ω , b ) (\omega, b) (ω,b)过两类样本中离分类面最近的点,且平行于最优分类面的超平面上H1,H2的训练样本就叫支持向量。)

2.SVM原理

SVM学习的基本想法是求解能够正确划分训练数据集并且几何间隔最大的分离超平面。如下图所示, ω ⋅ x + b = 0 \omega·x+b=0 ωx+b=0即为分离超平面,对于线性可分的数据集来说,这样的超平面有无穷多个(即感知机),但是几何间隔最大的分离超平面却是唯一的。
机器学习——支持向量机(SVM)_第1张图片

3.非线性SVM

从非线性分类训练集,通过核函数与软间隔最大化,或者凸二次优化,学习得到的分类决策函数
f ( x ) = s i g n ( ∑ i = 0 N f(x)=sign(\displaystyle\sum_{i=0}^N f(x)=sign(i=0Naiyi K ( x , x K(x,x K(x,xi ) + b ) )+b) )+b)
其中, K ( x , x K(x,x K(x,xi ) ) )是正定核函数。

二、几个基础知识点

1.函数间隔

定义超平面(ω,b)关于样本点 ( x (x (xi , y , y ,yi ) ) )的函数间隔是
γ i = y γ i^=y γi=yi ( w ∗ x (w∗x (wxi + b ) +b) +b);超平面(ω,b)关于训练集T的函数间隔为:
超平面(ω,b)与所有样本点 ( x (x (xi , y , y ,yi ) ) )的函数间隔最小值:
γ ^ = min ⁡ i = 1 , 2... N γ i ^ {\hat{\gamma}=\displaystyle\min_{i=1,2...N}\hat{\gamma_i}} γ^=i=1,2...Nminγi^
函数间隔和分类预测的正确性及确信度有所关联。

2.几何间隔

定义超平面 ( ω , b ) (ω,b) (ω,b)关于样本点 ( x (x (xi , y ,y ,yi ) ) )的几何间隔是γi=yi ( ∥ ω ∥ ω ∗ x ( ∥ω∥ω∗x (ωωxi + ∥ ω ∥ b ) ; + ∥ω∥b); +ωb);
超平面 ( ω , b ) (ω,b) (ω,b)关于训练数据集T的几何间隔是:超平面 ( ω , b ) (ω,b) (ω,b)与所有样本点 ( x (x (xi , y ,y ,yi ) ) )的几何间隔最小值:
γ = min ⁡ i = 1 , 2... N γ i ^ {{\gamma}=\displaystyle\min_{i=1,2...N}\hat{\gamma_i}} γ=i=1,2...Nminγi^

3.核函数

从输入空间 χ χ χ(欧式空间Rn的子集或者离散集合)到特征空间 H H H(希尔伯特空间)的映射:
ϕ ( x ) : χ ⇒ H ϕ(x):χ⇒H ϕ(x):χH;使得对所有的x,z∈χ,函数 K ( x , z ) K(x,z) K(x,z)满足条件 K ( x , z ) = ϕ ( x ) ∗ ϕ ( z ) K(x,z)=ϕ(x)∗ϕ(z) K(x,z)=ϕ(x)ϕ(z),则称 K ( x , z ) K(x,z) K(x,z)为核函数, ϕ ( x ) ϕ(x) ϕ(x)为映射函数。

三、代码学习

1.SVM在sklearn下

①先是加载一个简单的二类数据集的分布

import numpy as np
import matplotlib.pyplot as plt 
from sklearn import datasets 
from sklearn.preprocessing import StandardScaler 
from sklearn.svm import LinearSVC 
iris = datasets.load_iris() 
X = iris.data 
y = iris.target
X = X[y<2,:2]
y = y[y<2]
plt.scatter(X[y==0,0],X[y==0,1],color='red') 
plt.scatter(X[y==1,0],X[y==1,1],color='blue') 
plt.show()

机器学习——支持向量机(SVM)_第2张图片
②绘制决策边界

import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from matplotlib.colors import ListedColormap
import warnings
def plot_decision_boundary(model,axis):
    x0,x1=np.meshgrid(
        np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)).reshape(-1,1),
        np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100)).reshape(-1,1)
    ) 
    x_new=np.c_[x0.ravel(),x1.ravel()]
    y_predict=model.predict(x_new)
    zz=y_predict.reshape(x0.shape)
    custom_cmap=ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
    plt.contourf(x0,x1,zz,linewidth=5,cmap=custom_cmap)
warnings.filterwarnings("ignore")
data = load_iris()
x = data.data
y = data.target
x = x[y<2,:2]
y = y[y<2]
scaler = StandardScaler()
scaler.fit(x)
x = scaler.transform(x)
svc = LinearSVC(C=1e9)
svc.fit(x,y)
plot_decision_boundary(svc,axis=[-3,3,-3,3])
plt.scatter(x[y==0,0],x[y==0,1],c='r')
plt.scatter(x[y==1,0],x[y==1,1],c='b')
plt.show()

机器学习——支持向量机(SVM)_第3张图片
③再次实例化一个svc,并传入一个较小的 C

import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from matplotlib.colors import ListedColormap
import warnings
def plot_decision_boundary(model,axis):
    x0,x1=np.meshgrid(
        np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)).reshape(-1,1),
        np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100)).reshape(-1,1)
    ) 
    x_new=np.c_[x0.ravel(),x1.ravel()]
    y_predict=model.predict(x_new)
    zz=y_predict.reshape(x0.shape)
    custom_cmap=ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
    plt.contourf(x0,x1,zz,linewidth=5,cmap=custom_cmap)
warnings.filterwarnings("ignore")
data = load_iris()
x = data.data
y = data.target
x = x[y<2,:2]
y = y[y<2]
scaler = StandardScaler()
scaler.fit(x)
x = scaler.transform(x)
svc = LinearSVC(C=0.01)
svc.fit(x,y)
plot_decision_boundary(svc,axis=[-3,3,-3,3])
plt.scatter(x[y==0,0],x[y==0,1],c='r')
plt.scatter(x[y==1,0],x[y==1,1],c='b')
plt.show()

机器学习——支持向量机(SVM)_第4张图片
对比发现,C大的没有出现分类错误,C小的出现了一处错误,这证明了C越大,分类越过拟合,同样C越小容错率反而越大。

2.SVM中使用多项式特征

①处理非线性的数据并绘制图像

import numpy as np 
import matplotlib.pyplot as plt 
from sklearn import datasets 
X, y = datasets.make_moons() #使用生成的数据 
print(X.shape) # (100,2) 
print(y.shape) # (100,)
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1]) 
plt.show()

机器学习——支持向量机(SVM)_第5张图片
②我们再给数据集增加一些噪声干扰(原始数据集过于规范)

import numpy as np 
import matplotlib.pyplot as plt 
from sklearn import datasets 
X, y = datasets.make_moons(noise=0.15,random_state=777) #随机生成噪声点,random_state是随机种子,noise是方差 
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1]) 
plt.show()

③通过多项式特征进行分类

import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures,StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline
from matplotlib.colors import ListedColormap
import warnings
def plot_decision_boundary(model,axis):
    x0,x1=np.meshgrid(
        np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)).reshape(-1,1),
        np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100)).reshape(-1,1)
    )
    x_new=np.c_[x0.ravel(),x1.ravel()]
    y_predict=model.predict(x_new)
    zz=y_predict.reshape(x0.shape)
    custom_cmap=ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
    plt.contourf(x0,x1,zz,linewidth=5,cmap=custom_cmap)    
def PolynomialSVC(degree,C=1.0):
    return Pipeline([
        ('poly',PolynomialFeatures(degree=degree)),
        ('std_scaler',StandardScaler()),
        ('linearSVC',LinearSVC(C=C))
    ])
warnings.filterwarnings("ignore")
poly_svc = PolynomialSVC(degree=3)
X, y = datasets.make_moons(noise=0.15,random_state=777) #随机生成噪声点,random_state是随机种子,noise是方差
poly_svc.fit(X,y)
plot_decision_boundary(poly_svc,axis=[-1.5,2.5,-1.0,1.5])
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

机器学习——支持向量机(SVM)_第6张图片
④使用核函数来对数据进行处理
核函数使其维度提升,使原本线性不可分的数据,在高维空间变成线性可分的,再用线性SVM来进行处理。

import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures,StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline
from matplotlib.colors import ListedColormap
import warnings
def plot_decision_boundary(model,axis):
    x0,x1=np.meshgrid(
        np.linspace(axis[0],axis[1],int((axis[1]-axis[0])*100)).reshape(-1,1),
        np.linspace(axis[2],axis[3],int((axis[3]-axis[2])*100)).reshape(-1,1)
    )
    x_new=np.c_[x0.ravel(),x1.ravel()]
    y_predict=model.predict(x_new)
    zz=y_predict.reshape(x0.shape)
    custom_cmap=ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
    plt.contourf(x0,x1,zz,linewidth=5,cmap=custom_cmap)    
def PolynomialKernelSVC(degree,C=1.0): 
    return Pipeline([ ("std_scaler",StandardScaler()), 
                     ("kernelSVC",SVC(kernel="poly")) # poly代表多项式特征 
                    ])
poly_kernel_svc = PolynomialKernelSVC(degree=3)
X, y = datasets.make_moons(noise=0.15,random_state=777)
poly_kernel_svc.fit(X,y) 
plot_decision_boundary(poly_kernel_svc,axis=[-1.5,2.5,-1.0,1.5]) 
plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1]) 
plt.show()

机器学习——支持向量机(SVM)_第7张图片

3.高斯核函数

①升维

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]))# x取y=0的点, y取0,有多少个x,就有多少个y 
plt.scatter(x[y==1],[0]*len(x[y==1])) 
plt.show() 

机器学习——支持向量机(SVM)_第8张图片
②再将一个一维的数据映射到二维的空间

# 高斯核函数 
def gaussian(x,l): 
    gamma = 1.0 
    return np.exp(-gamma * (x -l)**2) 
l1,l2 = -1,1 
X_new = np.empty((len(x),2)) #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()

机器学习——支持向量机(SVM)_第9张图片

4、超参数 γ γ γ

最大化分离超平面与训练数据集的几何间隔gamma(γ)=1.0时

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
x, y = datasets.make_moons(noise=0.15, random_state=666)
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline
def RBFKernelSVC(gamma=1.0):
    return Pipeline([('std_scale', StandardScaler()),('svc', SVC(kernel='rbf', gamma=gamma))])
svc = RBFKernelSVC(gamma=1.0)
svc.fit(x, y)
def plot_decision_boundary(model, axis):
    x0, x1 = np.meshgrid(np.linspace(axis[0], axis[1], int((axis[1] - axis[0])*100)).reshape(1, -1),np.linspace(axis[2], axis[3], int((axis[3] - axis[2])*100)).reshape(1, -1),)
    x_new = np.c_[x0.ravel(), x1.ravel()]
    y_predict = model.predict(x_new)
    zz = y_predict.reshape(x0.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])
    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
plot_decision_boundary(svc, axis=[-1.5, 2.5, -1.0, 1.5])
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

机器学习——支持向量机(SVM)_第10张图片
最大化分离超平面与训练数据集的几何间隔gamma( γ γ γ)=100时

#最大化分离超平面与训练数据集的几何间隔gamma(γ)=100时
svc_gamma100 = RBFKernelSVC(gamma=100)
svc_gamma100.fit(x, y)
plot_decision_boundary(svc_gamma100, axis=[-1.5, 2.5, -1.0, 1.5])
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

机器学习——支持向量机(SVM)_第11张图片
gamma( γ γ γ)=10时
机器学习——支持向量机(SVM)_第12张图片
可以看出,gammma越小,模型复杂度越低,gamma越大,模型复杂度越高。平衡过拟合和欠拟合可以通过调节超参数gamma来实现。
参考学习链接:
http://blog.sina.com.cn/s/blog_6c3438600102yn9x.html

你可能感兴趣的:(机器学习)