SVM算法笔记

本文深入解析SVM算法的数学原理,包括最大化margin的概念、Soft Margin SVM的灵活性调整、使用sklearn进行实践,以及如何处理非线性数据的多项式特征和高斯核函数。同时,探讨了SVM在分类和回归任务中的应用。
摘要由CSDN通过智能技术生成

SVM数学理论:

在这里插入图片描述如图所示:我们的目标是最大化margin,而margin = 2d ,so 最大化margin ,就是要最大化d。
点到直线的距离拓展到n维平面:

在这里插入图片描述
下面介绍 Soft Margin SVM :
在这里插入图片描述
C 越大, 越是不允许犯错,当C无穷大的时候,严格不允许犯错,也就是SVM分类一定要全部分对
反之则反。 hard margin svm 就是那类严格不允许犯错的。


下面用sklearn 来实践一下SVM:
# iris数据集
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y<2,: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和KNN算法一样的,首先要对数据进行标准化处理:

from sklearn.preprocessing import StandardScaler

standardScaler = StandardScaler()
standardScaler.fit(X)
X_standard = standardScaler.transform(X)

当我们的C取非常大的时候,也就是分类非常严格,进行训练:

from sklearn.svm import LinearSVC

svc = LinearSVC(C=1e9)
svc.fit(X_standard,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 = [-3,3,-3,3])
plt.scatter(X_standard[y==0,0],X_standard[y==0,1])
plt.scatter(X_standard[y==1,0],X_standard[y==1,1])
plt.show()

在这里插入图片描述
我们可以看出来,基本上分类很成功,每一个都严格分类成功,下面我们把C设置小一点,再试试:

svc2 = LinearSVC(C=0.01)
svc2.fit(X_standard,y)
plot_decision_boundary(svc2, axis = [-3,3,-3,3])
plt.scatter(X_standard[y==0,0],X_standard[y==0,1])
plt.scatter(X_standard[y==1,0],X_standard[y==1,1])
plt.show()

在这里插入图片描述
我们发现,有一个蓝色的点分错了类,可以看出来,C变小了,分类也随之不严格了。


下面介绍在SVM中使用多项式特征

为啥子使用多项式,专门是为了分类一些非线性的数据,下面举个栗子,我们用moons数据集:

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets

X, y = datasets.make_moons(noise=0.15, random_state=666)
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述
这个情况下,我们想用多条直线进行分类,明显是不可以,这时候只能用多项式:

from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline

def polynomialSVC(degree, C=1.0):
    return Pipeline([
        ("poly",PolynomialFeatures(degree=degree)),
        ("std_scaler", StandardScaler()),
        ("linearSVC", LinearSVC(C=C))
    ])
    
poly_svc = polynomialSVC(degree=3)   # 这里我们使用三次方
poly_svc.fit(X,y)

边界图如下:

plot_decision_boundary(poly_svc, axis = [-1.5,2.5,-1,1.5])
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述
多项式进行分类,其实sklearn中多项式核函数也能实现:

from sklearn.svm import SVC

def PolynomialKernelSVC(degree, C=1.0):
    return Pipeline([
       ( "std_scaler",StandardScaler()),
        ("kernelSVC",SVC(kernel="poly", degree=degree,C=C))
    ])
poly_kernel_svc = PolynomialKernelSVC(degree=3)
poly_kernel_svc.fit(X,y)

核函数分类结果:

plot_decision_boundary(poly_kernel_svc, axis = [-1.5,2.5,-1,1.5])
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述


下面是多项式核函数理论基础

在这里插入图片描述
核函数的作用就是,把传入的x,y进行K(x,y)变换,变成 x i , y i x^i , y^i xi,yi ,转成2,3…n次项,上图是2次项。
K ( x , y ) = ( x ∗ y + c ) d K(x,y) = (x*y+c)^d K(x,y)=(xy+c)d


高斯核函数

在这里插入图片描述
在这里插入图片描述
举一个例子,对上面的例子,如何把红色和蓝色分离,现在它们在一维平面,如果想要分离,高斯核函数通过高斯公式,映射到二维,如上所示。


Scikit-learn中使用RBF核(也就是高斯核函数)

from sklearn import datasets

X, y = datasets.make_moons(noise=0.15, random_state=666)
plt.scatter(X[y ==0,0], X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述

from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline

def RBFKernelSVC(gamma=1.0):
    return Pipeline([
        ("std_scatter",StandardScaler()),
        ("svc",SVC(kernel="rbf",gamma=gamma))
    ])
 
svc = RBFKernelSVC(gamma=1.0)
svc.fit(X,y)

边界图:

plot_decision_boundary(svc, axis = [-1.5,2.5,-1,1.5])
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述
当我们把gamma取100时候(这里的gamma是高斯函数里面那个r):

svc100 = RBFKernelSVC(gamma=100.0)
svc100.fit(X,y)

在这里插入图片描述
明显过拟合了~,调节gamma的过程就是调节超参数,找出最适合的参数。


下面讨论的问题,SVM回归问题

上面我们只讨论分类的问题,其实之前我们讨论的很多算法,既可以实现分类,同样是可以回归。

下面用波士顿房价来做个栗子:

boston = datasets.load_boston()
X = boston.data
y = boston.target

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=666)
rom sklearn.svm import LinearSVR
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

def StandardLinearSVR(epsilon=0.1):
    return Pipeline([
        ("std_scaler",StandardScaler()),
        ('linearSVR',LinearSVR(epsilon=epsilon))
    ])

训练,并计算准确率:

svr = StandardLinearSVR()
svr.fit(X_train, y_train)
svr.score(X_test,y_test)

SVM的学习笔记到此完毕,下面继续总结。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值