基于Python的SVM算法深入研究

一、线性数据处理

(一)非标准化原始数据显示

Python代码

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<2的类别,也就是0 1 并且只取前两个特征
y = y[y<2] # 只取y<2的类别

# 分别画出类别0和1的点
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()

# 标准化
standardScaler = StandardScaler()

standardScaler.fit(X) #计算训练数据的均值和方差
X_standard = standardScaler.transform(X) #再用scaler中的均值和方差来转换X,使X标准化

svc = LinearSVC(C=1e9) #线性SVM分类器
svc.fit(X_standard,y) # 训练svm

数据显示结果
在这里插入图片描述

(二)绘制决策边界

Python代码

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]) # x,y轴都在-3到3之间
# 绘制原始数据
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='red') 
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='blue')
plt.show()

运行结果
在这里插入图片描述

(三)实例化一个SVC并传入超参数C

Python代码

svc2 = LinearSVC(C=0.01)
svc2.fit(X_standard,y)
plot_decision_boundary(svc2,axis=[-3,3,-3,3]) # x,y轴都在-3到3之间
# 绘制原始数据
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='red') 
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='blue')
plt.show()

运行结果
在这里插入图片描述

二、非线性数据处理

(一)生成月亮数据集

Python代码

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,)

运行结果
在这里插入图片描述
绘图显示月亮数据集:
Python代码

plt.scatter(X[y==0,0],X[y==0,1]) 
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

在这里插入图片描述

(二)在月亮数据上增加噪声点

Python代码

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()

运行结果
在这里插入图片描述

(三)通过多项式特征的SVM分类

Python代码

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))#最后生成svm
    ])

poly_svc = PolynomialSVC(degree=3)
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处理

可以使用核技巧来对数据进行处理,使其维度提升,使线性不可分的数据在高维空间变成线性可分

Python代码

from sklearn.svm import SVC

def PolynomialKernelSVC(degree,C=1.0):
    return Pipeline([
        ("std_scaler",StandardScaler()),
        ("kernelSVC",SVC(kernel="poly")) # poly代表多项式特征
    ])

poly_kernel_svc = PolynomialKernelSVC(degree=3)
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()

运行结果
在这里插入图片描述

三、核函数

(一)核函数定义

核函数包括线性核函数、多项式核函数、高斯核函数等,其中高斯核函数最常用,可以将数据映射到无穷维,也叫做径向基函数(Radial Basis Function 简称 RBF),是某种沿径向对称的标量函数。通常定义为空间中任一点x到某一中心xc之间欧氏距离的单调函数,可记作 k(||x-xc||), 其作用往往是局部的,即当x远离xc时函数取值很小。

(二)高斯核函数

1. 定义
所谓径向基函数 (Radial Basis Function 简称 RBF), 就是某种沿径向对称的标量函数。 通常定义为空间中任一点x到某一中心xc之间欧氏距离的单调函数 , 可记作 k(||x-xc||), 其作用往往是局部的 , 即当x远离xc时函数取值很小。最常用的径向基函数是高斯核函数 ,形式为 k(||x-xc||)=exp{- ||x-xc||2/(2*σ2) } 其中xc为核函数中心,σ为函数的宽度参数 , 控制了函数的径向作用范围。
高斯函数:
在这里插入图片描述
高斯核函数:
在这里插入图片描述
2. 计算机视觉中的作用
在计算机视觉中,有时也简称为高斯函数。高斯函数具有五个重要的性质,这些性质使得它在早期图像处理中特别有用.这些性质表明,高斯平滑滤波器无论在空间域还是在频率域都是十分有效的低通滤波器,且在实际图像处理中得到了工程人员的有效使用.高斯函数具有五个十分重要的性质,它们是:

(1)二维高斯函数具有旋转对称性,即滤波器在各个方向上的平滑程度是相同的
(2)高斯函数是单值函数
(3)高斯函数的傅立叶变换频谱是单瓣的
(4)高斯滤波器宽度(决定着平滑程度)是由参数σ表征的,而且σ和平滑程度的关系是非常简单的.σ越大,高斯滤波器的频带就越宽,平滑程度就越好
(5)由于高斯函数的可分离性,大高斯滤波器可以得以有效地实现

(三)生成测试数据集

Python代码

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()

运行结果
在这里插入图片描述

(四)数据集升维处理

Python代码

# 高斯核函数
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()

运行结果
在这里插入图片描述
由上述可见,经过升维处理之后,数据分类变得更加容易了

四、超参数问题

(一)超参数定义

在机器学习的上下文中,超参数是在开始学习过程之前设置值的参数。 相反,其他参数的值通过训练得出。

超参数:

  • 定义关于模型的更高层次的概念,如复杂性或学习能力
  • 不能直接从标准模型培训过程中的数据中学习,需要预先定义
  • 可以通过设置不同的值,训练不同的模型和选择更好的测试值来决定

超参数的一些示例:

  • 树的数量或树的深度
  • 矩阵分解中潜在因素的数量
  • 学习率(多种模式)
  • 深层神经网络隐藏层数
  • k均值聚类中的簇数

高斯函数:
在这里插入图片描述
在这里插入图片描述
在高斯函数中, σ 越大,分布就越宽
在这里插入图片描述

(二)生成数据集

Python代码

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

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

运行结果
在这里插入图片描述

(三)定义一个RBF核的SVM

Python代码
γ γ γ=1

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

def RBFKernelSVC(gamma=1.0):
    return Pipeline([
        ('std_scaler',StandardScaler()),
        ('svc',SVC(kernel='rbf',gamma=gamma))
    ])

svc = RBFKernelSVC()
svc.fit(X,y)

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()

运行结果
在这里插入图片描述
修改 γ γ γ参数运行代码

γ γ γ=100

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

def RBFKernelSVC(gamma=1.0):
    return Pipeline([
        ('std_scaler',StandardScaler()),
        ('svc',SVC(kernel='rbf',gamma=gamma))
    ])

svc = RBFKernelSVC(100)
svc.fit(X,y)

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()

运行结果
在这里插入图片描述
γ γ γ=10

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

def RBFKernelSVC(gamma=1.0):
    return Pipeline([
        ('std_scaler',StandardScaler()),
        ('svc',SVC(kernel='rbf',gamma=gamma))
    ])

svc = RBFKernelSVC(10)
svc.fit(X,y)

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()

运行结果
在这里插入图片描述
γ \gamma γ取值越大,就是高斯分布的钟形图越窄,这里相当于每个样本点都形成了钟形图。很明显这样是过拟合的。

γ \gamma γ=0.1

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

def RBFKernelSVC(gamma=1.0):
    return Pipeline([
        ('std_scaler',StandardScaler()),
        ('svc',SVC(kernel='rbf',gamma=gamma))
    ])

svc = RBFKernelSVC(0.1)
svc.fit(X,y)

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()

运行结果
在这里插入图片描述
此时它是欠拟合的,因此,我们可以看出 γ \gamma γ 值相当于在调整模型的复杂度。

综上分析,当 γ \gamma γ=100时,分类更准确

(四)准确度

python代码

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

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=777) # 把数据集拆分成训练数据和测试数据

from sklearn.svm import LinearSVR 
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler

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) #0.6989278257702748

运行结果
在这里插入图片描述
以上就是SVM算法的部分分析,还有疏漏的地方,欢迎大家指正~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值