基于jupyter notebook的python编程-----支持向量机学习二(SVM处理线性[鸢尾花数据集]和非线性数据集[月亮数据集])


前面我们通过学习了支持向量机(Support Vector Machine)算法的基础学习,并对比了其他两种算法:LDA和K-means算法的线性可视化,主要目的就是通过对比学习支持向量机,并没有深入了解支持向量机的算法原理,本次博客,林君学长主要带大家了解支持向量机的深度学习,数据来源同样为鸢尾花数据集和月亮数据集,一起来看吧!

一、SVM处理线性数据集(鸢尾花数据集)

1、导入需要的python库

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
  • numpy:用于计算
  • matplotlib.pyplot:用于作图
  • sklearn:包括鸢尾花和月亮数据集
  • StandardScaler:标准化,计算数据集的均值和方差
  • sklearn.svm:构建SVM算法和决策边界

2、选取鸢尾花的数据集的两个特征,用于分类构建SVM算法

1)、选取鸢尾花的两个特征:长宽

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

2)、可视化的运行结果显示
在这里插入图片描述

3、标准化、构建SVM分类(实例化SVC)及训练SVM

1)、标准化后构建分类器及训练SVM数据,传入C值为10的9次方

# 标准化
standardScaler = StandardScaler()
standardScaler.fit(X) #计算训练数据的均值和方差
X_standard = standardScaler.transform(X) #再用scaler中的均值和方差来转换X,使X标准化
svc = LinearSVC(C=1e9) #线性SVM分类器
svc.fit(X_standard,y) # 训练svm

2)、训练结果展示
在这里插入图片描述

4、定义绘制决策边界函数

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)

5、绘制决策边界

1)、调用函数,绘制鸢尾花数据集两个特征的决策边界

# 绘制决策边界
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()

2)、决策边界绘制结果展示:
在这里插入图片描述

6、实例化SVC,并传入参数C值

1)、再次实例化SVC,传递参数C值为0.05

svc2 = LinearSVC(C=0.05)
svc2.fit(X_standard,y)

2)、调用决策边界函数进行鸢尾花数据集的绘制

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

3)、C值为0.05时候的决策边界绘制结果
在这里插入图片描述
4)、更改C值为一个较大的值,例如100000,再次绘制进行对比

svc2 = LinearSVC(C=100000)
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()

在这里插入图片描述
可以很明显的看到和第一个决策边界的不同,在第一个决策边界汇总,有一个红点是分类错误的,这意味着:C值越小容错空间越大,越容易出现错误。我们可以通过svc.coef_ 函数来获取学习到的权重系数,svc.intercept_ 函数获取偏差

二、SVM处理非线性数据集(月亮数据集)

1、导入需要的python库

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import PolynomialFeatures,StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
  • numpy:用于计算
  • matplotlib.pyplot:用于作图
  • sklearn:包括月亮数据集
  • PolynomialFeatures,StandardScaler:生成多项式和标准化
  • LinearSVC:构建决策边界
  • sklearn.pipeline:管道:可以将许多算法模型串联起来,比如将特征提取、归一化、分类组织在一起形成一个典型的机器学习问题工作流
  • SVC:用于核处理(核技巧来对数据进行处理)

2、构建月亮的特征数据并可视化

1)、构建月亮数据集的两个特征数据并可视化

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

2)、可视化运行结果
在这里插入图片描述

3、生成噪声点并可视化

1)、生成噪声点并可视化

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

2)、可视化运行结果展示
在这里插入图片描述

4、定义非线性SVM分类函数

def PolynomialSVC(degree,C=1.0):
    return Pipeline([
        ("poly",PolynomialFeatures(degree=degree)),#生成多项式
        ("std_scaler",StandardScaler()),#标准化
        ("linearSVC",LinearSVC(C=C))#最后生成svm
    ])

5、调用PolynomialSVC函数进行分类可视化

1)、调用非线性SVM分类,实例化SVC,传递参数为5并可视化

poly_svc = PolynomialSVC(degree=5)
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()

2)、可视化运行结果
在这里插入图片描述
我们可以看到,生成的边界不再是线性的直线了,因为月亮数据集提取的两个特征并不是线性的,所以决策边界自然不会是线性!

6、核处理(核技巧来对数据进行处理)

使用核技巧来对数据进行处理,使其维度提升,使原本线性不可分的数据,在高维空间变成线性可分的。再用线性SVM来进行处理。
1)、定义核处理函数

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

2)、调用核处理函数并实例化非线性SVC后可视化

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

3)、可视化运行结果展示
在这里插入图片描述
可以看到这种方式也生成了一个非线性的边界,但与上面有巨大的不同,这个在慢慢饿趋于近似线性.
这里SVC(kernel=“poly”)有个参数是kernel,就是核函数,下面林君学长将带大家了解核函数,一起来看吧!

三、核函数

核函数的重要作用就是通过升维来进行线性回归的模拟,对于核函数的具体了解,小伙伴可以通过如下链接进行深入学习,本次博客林君学长主要通过python代码进行相应的核函数理解,链接如下:https://baike.baidu.com/item/%E6%A0%B8%E5%87%BD%E6%95%B0/4693132?fr=aladdin

1、随机生成数据并可视化

1)、随机数据构建

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

2)、可视化运行结果
在这里插入图片描述

2、利用高斯核函数,进行数据的升维(一维升二维)

1)、高斯核函数定义

def gaussian(x,l):
    gamma = 1.0
    return np.exp(-gamma * (x -l)**2)

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

3)、升维可视化运行结果展示
在这里插入图片描述
对于这样的二维数据显然是线性可分的,在蓝色和黄色的点中插入直线切割分类就好:
在这里插入图片描述
了解了核函数的原理,接下来我们通过核函数来进行非线性数据集月亮数据集的分类处理吧:

四、核函数处理月亮数据集

1、导入需要的python库

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline

2、导入月亮数据集并可视化

1)、导入月亮数据集并可视化(选取两个特征)

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

2)、可视化运行结果展示
在这里插入图片描述

3、定义RBF核的SVM分类函数

我们设置函数的默认参数γ=1.0\gamma=1.0,该值自己可以设定,后面我们做对比分析

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

4、实例化SVC并传递γ\gamma参数

1)、传递γ\gamma值为200并可视化

svc = RBFKernelSVC(200)
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()

2)、可视化运行结果
在这里插入图片描述
3)、传递γ\gamma值为20并可视化

svc = RBFKernelSVC(20)
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取值越大,就是高斯分布的钟形图越窄,这里相当于每个样本点都形成了钟形图。很明显这样是过拟合的
4)、传递γ\gamma值为0.2并可视化

svc = RBFKernelSVC(0.2)
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值相当于在调整模型的复杂度。
以上就是本次博客的全部内容啦,希望通过对本次博客的阅读,可以帮助小伙伴深入了解支持向量机,同时,通过python代码学习SVM如何进行线性数据集和非线性数据集的分类,通过代码了解原理,是程序员的必备技能啦!
遇到问题的小伙伴记得留言评论哦,林君学长看到会为大家进行解答的,这个学长不太冷

陈一月的又一天编程岁月^ _ ^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章