SVM-支持向量机实验分析(软硬间隔,线性核,高斯核)

目录

一、前言

二、实验

        0. 导入包

        1.  支持向量机带来的效果

        2. 软硬间隔

        3. 非线性支持向量机

         4. 核函数变换

        线性核

        高斯核

         对比不同的gamma值对结果的影响


一、前言

        学习本文之前要具有SVM支持向量机的理论知识,可以参考支持向量机(Support Vector Machines)

        本文对比了传统分类模型和SVM支持向量机分类模型,软硬间隔差别,非线性支持向量机,核技巧,高斯核函数的参数比较

二、实验

        0. 导入包

#0 导入包
import numpy as np
import os
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
import warnings
warnings.filterwarnings('ignore')

        1.  支持向量机带来的效果

from sklearn.svm import SVC
from sklearn.datasets import load_iris

iris = load_iris()
X = iris['data'][:,(2,3)]
y = iris['target']

setosa_or_versicolor = (y==0)|(y==1)   # 做个二分类
X = X[setosa_or_versicolor]
y = y[setosa_or_versicolor]

plt.plot(X[:,0][y==0],X[:,1][y==0],'bs')
plt.plot(X[:,0][y==1],X[:,1][y==1],'yo')

svm_clf = SVC(kernel='linear',C=10000)
svm_clf.fit(X,y)

 

               随便画了几条直线

#一般模型
x0 = np.linspace(0,5.5,200)
pred_1 = 5 * x0 - 20
pred_2 = x0 - 1.8
pred_3 = 0.1 * x0 + 0.5

         对比情况

#支持向量机
def plot_svc_decision_boundary(svm_clf,xmin,xmax,sv=True):
    #模型训练完后得到 W b
    w = svm_clf.coef_[0]
    b = svm_clf.intercept_[0]
    x0 = np.linspace(xmin,xmax,200)
    decision_boundary = -w[0]/w[1] *x0 - b/w[1]
    margin = 1/w[1]
    gutter_up = decision_boundary + margin
    gutter_down = decision_boundary - margin
    if sv:
        svs = svm_clf.support_vectors_
        plt.scatter(svs[:,0],svs[:,1],facecolors='#FFAAAA',s=180)
    plt.plot(x0,decision_boundary,'k-',linewidth=2)
    plt.plot(x0,gutter_up,'k--',linewidth=2)
    plt.plot(x0,gutter_down,'k--',linewidth=2)

plt.figure(figsize=(14,4))
plt.subplot(121)
plt.plot(x0,pred_1,'g--',linewidth=2)
plt.plot(x0,pred_2,'m-',linewidth=2)
plt.plot(x0,pred_3,'r-',linewidth=2)
plt.plot(X[:,0][y==0],X[:,1][y==0],'bs')
plt.plot(X[:,0][y==1],X[:,1][y==1],'yo')
plt.axis([0,5.5,0,2])

plt.subplot(122)
plot_svc_decision_boundary(svm_clf,0,5.5)
plt.plot(X[:,0][y==0],X[:,1][y==0],'bs')
plt.plot(X[:,0][y==1],X[:,1][y==1],'yo')
plt.axis([0,5.5,0,2])

 

        可以看出相较于传统的分类模型,支持向量机可以把决策超平面求出来,力保决策面达到最佳。

        2. 软硬间隔

        硬间隔:不允许有分类误差,导致过拟合

        软间隔: 允许有分类误差,降低过拟合风险

        在sklearn中可以使用超参数C控制软间隔程度

#可以使用超参数C控制软间隔程度
import numpy  as np
from sklearn import datasets
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC

iris = datasets.load_iris()
X = iris['data'][:,(2,3)]
y = (iris['target'] == 2).astype(np.float64)
svm_clf = Pipeline((
    ('std',StandardScaler()),
    ('LinearSVC',LinearSVC(C=1))
))
svm_clf.fit(X,y)
svm_clf.predict([[5,1.6]])
#对比不同的C值所带来的效果差异
scaler = StandardScaler()
svm_clf1 = LinearSVC(C=1,random_state=42)
svm_clf2 = LinearSVC(C=100,random_state=42)
scaled_svm_clf1 =Pipeline((
    ('std',scaler),
    ('LinearSVC',svm_clf1)
))
scaled_svm_clf2=Pipeline((
    ('std',scaler),
    ('LinearSVC',svm_clf2)
))
scaled_svm_clf1.fit(X,y)
scaled_svm_clf2.fit(X,y)
#将标准化后的数据还原
b1 = svm_clf1.decision_function([-scaler.mean_ / scaler.scale_])
b2 = svm_clf2.decision_function([-scaler.mean_ / scaler.scale_])
w1 = svm_clf1.coef_[0] /scaler.scale_
w2 = svm_clf2.coef_[0] /scaler.scale_
svm_clf1.intercept_ = np.array([b1])
svm_clf2.intercept_ = np.array([b2])
svm_clf1.coef_ = np.array([w1])
svm_clf2.coef_ = np.array([w2])
plt.figure(figsize=(14,5))
plt.subplot(121)
plt.plot(X[:,0][y==0],X[:,1][y==0],'bs',label='Iris-Virginica')
plt.plot(X[:,0][y==1],X[:,1][y==1],'yo',label='Iris-Versicolor')
plot_svc_decision_boundary(svm_clf1,4,6,sv=False)
plt.xlabel('Petal length',fontsize=14)
plt.ylabel('Petal width',fontsize=14)
plt.legend(loc='upper center',fontsize=14)
plt.title('$C= {}$'.format(svm_clf1.C),fontsize=16)
plt.axis([4,6,0.8,2.8])

plt.subplot(122)
plt.plot(X[:,0][y==0],X[:,1][y==0],'bs')
plt.plot(X[:,0][y==1],X[:,1][y==1],'yo')
plot_svc_decision_boundary(svm_clf2,4,6,sv=False)
plt.xlabel('Petal length',fontsize=14)
plt.title('$C= {}$'.format(svm_clf2.C),fontsize=16)
plt.axis([4,6,0.8,2.8])

         在右侧,使用较高的的C值,分类器会减少误分类,但是最终会有较小间隔 

          在左侧,使用较低的的C值,间隔要大得多,但是很多实例最终会出现在间隔之内

        3. 非线性支持向量机

#创建一份有点难度的数据集
from sklearn.datasets import make_moons
X,y = make_moons(n_samples=100,noise=0.15,random_state=42)
def plot_dataset(X,y,axes):
    plt.plot(X[:,0][y==0],X[:,1][y==0],'bs')
    plt.plot(X[:,0][y==1],X[:,1][y==1],'g^') 
    plt.axis(axes)
    plt.grid(True,which='both')
    plt.xlabel(r'$x_1$',fontsize=20)
    plt.ylabel(r'$x_2$',fontsize=20,rotation=0)
plot_dataset(X,y,[-1.5,2.5,-1,1.5])
plt.show()

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
Polynomial_svm_clf = Pipeline((
    ('poly-features',PolynomialFeatures(degree=3)), #变换数据
    ('scaler',StandardScaler()),
    ('svm_clf',LinearSVC(C=10,loss='hinge')) # 用线性SVC
))
Polynomial_svm_clf.fit(X,y)

def plot_predictions(clf,axes):
    x0s = np.linspace(axes[0],axes[1],100)
    x1s = np.linspace(axes[2],axes[3],100)
    x0,x1 = np.meshgrid(x0s,x1s)
    X_new = np.c_[x0.ravel(),x1.ravel()]
    y_pred = clf.predict(X_new).reshape(x0.shape)
    print(y_pred)
    plt.contourf(x0,x1,y_pred,cmap=plt.cm.brg,alpha = 0.2)

plot_predictions(Polynomial_svm_clf,[-1.5,2.5,-1,1.5])
plot_dataset(X,y,[-1.5,2.5,-1,1.5])

         4. 核函数变换

                SVM的牛逼之处

        线性核

from sklearn.svm import SVC

poly_kernel_svm_clf = Pipeline([
    ('scaler',StandardScaler()),
    ('svm_clf',SVC(kernel='poly',degree=3,coef0=1,C=5))
])
poly_kernel_svm_clf.fit(X,y)
poly100_kernel_svm_clf = Pipeline([
    ('scaler',StandardScaler()),
    ('svm_clf',SVC(kernel='poly',degree=10,coef0=100,C=5))
])
poly100_kernel_svm_clf.fit(X,y)

plt.figure(figsize=(10,4))
plt.subplot(121)
plot_predictions(poly_kernel_svm_clf,[-1.5,2.5,-1,1.5])
plt.axis([-1.5,2.5,-1,1.5])
plt.xlabel('$X_1$',fontsize = 14)
plt.ylabel('$X_2$',fontsize = 14)
plot_dataset(X,y,[-1.5,2.5,-1,1.5])
plt.title(r'$kernel=poly,degree=3,coef0=1,C=5$',fontsize=12)
plt.subplot(122)
plot_predictions(poly100_kernel_svm_clf,[-1.5,2.5,-1,1.5])
plt.axis([-1.5,2.5,-1,1.5])
plt.xlabel('$X_1$',fontsize = 14)
plt.ylabel('$X_2$',fontsize = 14)
plot_dataset(X,y,[-1.5,2.5,-1,1.5])
plt.title(r'$kernel=poly,degree=100,coef0=10,C=5$',fontsize=12)
plt.show()

      

        高斯核

        利用相似度来变换特征(升维技巧)

       高斯核函数: \phi _{\gamma}=e^{-\gamma\left | x-\iota \right |^2} 

                选择一份一维数据,并在x1 = -2 , x1 = 1 处添加两个高斯函数,将相似度函数定义为\gamma=0.3的径向基函数(RBF)

        例如:X1=-1:它位于距第一个地标\iota距离为1的地方,距第二个地标\iota地标距离为2的地方,因此新特征是x_2=e^{(-0.3*1^2)}\approx 0.74,并且x_3=e^{(-0.3*2^2)}\approx 0.3,成功把一维升为二维。

        如果把每个样本当作地标,最多生成和样本数量一样多的维度

        这里手写了高斯核函数

#高斯核函数
def guassian_rbf(x, landmark, gamma):
    return np.exp(-gamma * np.linalg.norm(x - landmark,axis = 1) ** 2) 


gamma = 0.3 #假设

#创造数据
x1s = np.linspace(-4.5,4.5,100).reshape(-1,1) #还未变换得一维数据
y1 = np.random.randint(1,size=(25,1)) #前25个是0
y2 = np.random.randint(1,2,size=(50,1)) #中间50个是1
y3 = np.random.randint(1,size=(25,1)) #后25个是0
y = np.vstack((y1,y2))
y = np.vstack((y,y3)).reshape(1,-1)

#训练
x2s = guassian_rbf(x1s,-2,gamma) #以-2为地标
x3s = guassian_rbf(x1s,1,gamma) #以1为地标
x2 = x2s.reshape(-1,1)
x3 = x3s.reshape(-1,1)
X_train = np.hstack((x2,x3))
svm_clf = LinearSVC(C=100).fit(X_train,y[0])
x_1_max = np.max(x2s)
x_1_min = np.min(x2s)
x_2_max = np.max(x3s)
x_2_min = np.min(x3s)

#棋盘
def plot_guassian_decision_boundary(svm_clf,axes=[x_1_min,x_1_max,x_2_min,x_2_max]):
    x11s = np.linspace(axes[0],axes[1],100)
    x22s = np.linspace(axes[2],axes[3],100)
    x0,x1 = np.meshgrid(x11s,x22s)
    X_new = np.c_[x0.ravel(),x1.ravel()]
    y_pred = svm_clf.predict(X_new).reshape(x0.shape)
    plt.plot(X_train[:,0][y[0]==0],X_train[:,1][y[0]==0],'bs')
    plt.plot(X_train[:,0][y[0]==1],X_train[:,1][y[0]==1],'g^') 
    plt.contourf(x0,x1,y_pred,cmap=plt.cm.brg,alpha = 0.2)
    plt.axis([x_1_min-0.01,x_1_max+0.01,x_2_min-0.01,x_2_max+0.01])


plt.figure(figsize=(14,6))
plt.subplot(121)
plt.plot(x1s[:,0][y[0]==0],np.zeros(sum(y[0]==0)),'bs')
plt.plot(x1s[:,0][y[0]==1],np.zeros(sum(y[0]==1)),'g^') 
plt.axis([-4.5,4.5,-1,1])
plt.title("original one dimension data")
plt.xlabel(r'$X_0$')
plt.grid(True,which='both')
plt.subplot(122)
plot_guassian_decision_boundary(svm_clf)
plt.title("GF turn to two dimension data")
plt.xlabel(r'$X_1$')
plt.ylabel(r'$X_2$',rotation=0)

        

        我们可以看到,在左侧的数据无法用线性切分,可以通过升维的方法,到右侧划分。

         对比不同的gamma值对结果的影响

#对比不同的gamma值对结果的影响
from sklearn.svm import SVC
from sklearn.datasets import make_moons
X,y = make_moons(n_samples=100,noise=0.15,random_state=42)

gamma1 , gamma2 = 0.1 ,5
C1,C2 = 0.001,1000
hyperparams = ((gamma1,C1),(gamma1,C2),(gamma2,C1),(gamma2,C2))

svm_clfs = []
for gamma,C in  hyperparams:
    rbf_kernel_svm_clf = Pipeline([
        ('scaler',StandardScaler()),
        ('svm_clf',SVC(kernel='rbf',gamma=gamma,C=C))
    ])
    rbf_kernel_svm_clf.fit(X,y)
    svm_clfs.append(rbf_kernel_svm_clf)

plt.figure(figsize=(11,7))

for i,svm_clf in enumerate (svm_clfs):
    plt.subplot(221+i)
    plot_predictions(svm_clf,[-1.5,2.5,-1,1.5])
    plot_dataset(X,y,[-1.5,2.5,-1,1.5])
    gamma , C = hyperparams[i]
    plt.title(r"$\gamma = {}, C = {}$".format(gamma,C),fontsize = 16)

        

SVM中利用了核函数计算技巧,大大降低了计算复杂度:

    增加gamma值使高斯曲线变窄,因此每个实例影响范围都较小;决策边界最终变得更不规则,在个别实例周围摆动

    减少gamma值使高斯曲线变宽,因此每个实例影响范围都较大;决策边界最终变得更加平滑,降低过拟合风险

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/464006.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

epoll怎么就高效了?

目录 摘要 1 举个栗子 2 从 epoll_create 开始 3 epoll_ctl,插入待监听的描述符 3.1 故事围绕 ep_item 展开 3.2 在 socket 等待队列上设置 epoll 回调 3.3 关系变得复杂 4 epoll_wait 等你 4.1 等待就绪事件 4.2 共享内存? 5 来了来了&#xf…

第 126 场 LeetCode 双周赛题解

A 求出加密整数的和 模拟 class Solution { public:int sumOfEncryptedInt(vector<int> &nums) {int res 0;for (auto x: nums) {string s to_string(x);char ch *max_element(s.begin(), s.end());for (auto &c: s)c ch;res stoi(s);}return res;} };B 执行…

Java学习笔记(15)

JDK7前时间相关类 Date时间类 Simpledateformat Format 格式化 Parse 解析 默认格式 指定格式 EE&#xff1a;表示周几 Parse&#xff1a;把字符串时间转成date对象 注意&#xff1a;创建对象的格式要和字符串的格式一样 Calendar日历类 不能创建对象 Getinstance 获取当…

8款手机宝藏APP,每款都非常强大实用!

1. 综合AI工具箱——HuluAI 综合AI工具https://h5.cxyhub.com/?invitationhmeEo7 HuluAI是一款聚合式全能AI工具&#xff0c;完美接入官方正版GPT4.0和Midjourney绘画&#xff01;。除此之外&#xff0c;还拥有文心一言语言大模型和DallE3绘图功能。经过长时间的稳定运行&am…

【数据结构】深入理解AVL树:实现和应用

AVL树是一种自平衡的二叉搜索树&#xff0c;它能够保持良好的平衡性质&#xff0c;使得在最坏情况下的时间复杂度也能保持在对数级别。本文将深入介绍AVL树的原理、实现和应用&#xff0c;并通过示例代码演示其基本操作。 文章目录 什么是AVL树&#xff1f;AVL树的实现在AVL树…

Linux - 安装 Jenkins(详细教程)

目录 前言一、简介二、安装前准备三、下载与安装四、配置镜像地址五、启动与关闭六、常用插件的安装 前言 虽然说网上有很多关于 Jenkins 安装的教程&#xff0c;但是大部分都不够详细&#xff0c;或者是需要搭配 docker 或者 k8s 等进行安装&#xff0c;对于新手小白而已&…

2024人工智能四大趋势→

2023年&#xff0c;世人见证了ChatGPT在全球范围的大火。以生成式人工智能为代表的新一代人工智能问世&#xff0c;改变了人工智能&#xff08;AI&#xff09;技术与应用的发展轨迹&#xff0c;加速了人与AI的互动进程&#xff0c;是人工智能发展史上的新里程碑。2024年&#x…

职场中的“跨界思维”:如何拓宽你的职业发展道路?

在当今职场&#xff0c;单一技能的竞争已经越来越激烈&#xff0c;具备跨界思维的人才越来越受到企业的青睐。本文将探讨职场中的“跨界思维”&#xff0c;帮助您拓宽职业发展道路&#xff0c;提升自身竞争力。 一、什么是跨界思维&#xff1f; 跨界思维&#xff0c;顾名思义&a…

【重新定义matlab强大系列十八】Matlab深度学习长短期记忆 (LSTM) 网络生成文本

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

Etcd 介绍与使用(入门篇)

etcd 介绍 etcd 简介 etc &#xff08;基于 Go 语言实现&#xff0c;&#xff09;在 Linux 系统中是配置文件目录名&#xff1b;etcd 就是配置服务&#xff1b; etcd 诞生于 CoreOS 公司&#xff0c;最初用于解决集群管理系统中 os 升级时的分布式并发控制、配置文件的存储与分…

Bean的作用域、Bean的自动装配、注解自动装配 (Spring学习笔记五)

1、Bean 的作用域 官网上显示有六种 1、Bean的作用域默认的是singleton&#xff08;单例模式的实现&#xff09; 也可以显示的设置&#xff08;单例模式的实现&#xff09; <!--用scope可以设置Bean的作用域--><bean id"user2" class"com.li.pojo.Us…

Elasticsearch从入门到精通-05ES匹配查询

Elasticsearch从入门到精通-05ES匹配查询 &#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是程序员行走的鱼 &#x1f4d6; 本篇主要介绍和大家一块学习一下ES各种场景下的匹配查询,有助于我们在项目中进行综合使用 前提 创建索引并指定ik分词器: PUT /es_db {"…

[ Linux ] vim的使用(附:命令模式的常见命令列表)

1.下载安装 这里是在通过yum进行下载安装 yum install -y vim 2.了解 vim是一款编辑器&#xff0c;它具有多模式的特点 主要有&#xff1a;插入模式&#xff0c;命令模式&#xff0c;底行模式 3.使用 打开 vim 文件名 命令模式的常见命令列表 插入模式 按「 i 」切换…

建设IAM/IDM统一身份管理,实现系统之间的单点登录(SSO)

企业实施身份管理的现状&#xff1a; 1.身份存储分散&#xff0c;不能统一供应诸多应用系统&#xff0c;企业用户信息常常存在于多个系统&#xff0c;如HR系统有一套用户信息&#xff0c;OA系统也有一套用户信息&#xff0c;身份存储不集中&#xff0c;不能统一地为诸多应用系…

BUUCTF-WEB1

[ACTF2020 新生赛]Exec1 1.打开靶机 是一个ping命令 2.利用管道符“|” ping一下本地主机并查看ls ping 127.0.0.1 | ls 可以看到回显的内容是一个文件 127.0.0.1 | cat index.php #查看主机下index.php 127.0.0.1 | ls / #查看主机根目录下的文件 看的一个flag文件 …

C++:菱形继承与虚继承

看下面这个示例代码 class A{ public: int num10; A(){cout<<"A构造"<<endl;} virtual void fun(){cout<<"A虚函数"<<endl;} };class B:public A{ public: B(){cout<<"B构造"<<endl;} void fun(){cout<…

Linux基本使用

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;热门专栏&#xff1a;网络原理&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 Linux是什么&#xff1f; Linux常用命令介绍 命令提示…

云服务器容器常用操作系统介绍

常用操作系统介绍 开源软件国内镜像源Alpine操作系统介绍镜像源修改镜像源apk包管理器 Debian操作系统介绍镜像源修改镜像源apt包管理器 ubuntu操作系统介绍修改镜像源apt包管理器 CentOS操作系统介绍修改镜像源yum包管理器 开源软件国内镜像源 名称地址南京大学mirror.nju.ed…

【安全类书籍-2】Web渗透测试:使用Kali Linux

目录 内容简介 作用 下载地址 内容简介 书籍的主要内容是指导读者如何运用Kali Linux这一专业的渗透测试平台对Web应用程序进行全面的安全测试。作者们从攻击者的视角出发,详细阐述了渗透测试的基本概念和技术,以及如何配置Kali Linux以适应渗透测试需求。书中不仅教授读者…

初识Java篇(JavaSE基础语法)(1)

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a; 我要学编程(ಥ_ಥ)-CSDN博客 目录 前言&#xff1a; 初识Java 运行Java程序 注释 标识符 关键字 数据类型与变量 字面常量 数据类型 变量 类型转换 类型提升 字…