SVM的代码实现

  1. 生成假数据集:创建一个简单的二分类数据集。
  2. 数据标准化:标准化特征。
  3. 定义线性核函数:选择一个简单的线性核。
  4. 定义优化问题:使用对偶问题进行求解。
  5. 求解对偶问题:通过简单的梯度上升法求解对偶问题。
  6. 确定支持向量:找到支持向量。
  7. 计算权重和偏置:计算超平面的参数。
  8. 进行预测:使用训练好的模型对新数据点进行预测。

1. 生成假数据集

我们创建一个简单的二分类数据集:

import numpy as np# 生成假数据点
X = np.array([[2, 3], [3, 3], [4, 2], [1, 1], [2, 2], [2, 1]])
y = np.array([1, 1, 1, -1, -1, -1])  # 类别标签

2. 数据标准化

将数据标准化,使每个特征具有零均值和单位方差:

X_mean = np.mean(X, axis=0)
X_std = np.std(X, axis=0)
X = (X - X_mean) / X_std

3. 定义线性核函数

我们选择线性核函数:

def linear_kernel(x1, x2):return np.dot(x1, x2)

4. 定义优化问题

SVM 的对偶问题可以表示为:

max ⁡ α ∑ i = 1 n α i − 1 2 ∑ i = 1 n ∑ j = 1 n α i α j y i y j K ( x i , x j ) \max_{\alpha} \sum_{i=1}^{n} \alpha_i - \frac{1}{2} \sum_{i=1}^{n} \sum_{j=1}^{n} \alpha_i \alpha_j y_i y_j K(x_i, x_j) αmaxi=1nαi21i=1nj=1nαiαjyiyjK(xi,xj)

5. 求解对偶问题

通过简单的梯度上升法求解对偶问题:

def train_svm(X, y, C=1.0, max_iter=100, learning_rate=0.01):n_samples, n_features = X.shapealpha = np.zeros(n_samples)for _ in range(max_iter):for i in range(n_samples):gradient = 1 - y[i] * np.sum(alpha * y * np.array([linear_kernel(X[i], X[j]) for j in range(n_samples)]))alpha[i] += learning_rate * gradientalpha[i] = max(0, min(alpha[i], C))return alphaalpha = train_svm(X, y)

下面我们逐行解释 train_svm 函数的代码:

def train_svm(X, y, C=1.0, max_iter=100, learning_rate=0.01):
  • 函数定义train_svm 是一个用于训练支持向量机的函数。
  • 参数说明
    • X:输入数据集,形状为 (n_samples, n_features),表示 n 个样本和每个样本的特征向量。
    • y:标签数组,长度为 n_samples,取值为 1 或 -1,表示每个样本的类别。
    • C:正则化参数,默认值为 1.0,控制对误分类的惩罚程度。
    • max_iter:最大迭代次数,默认值为 100,表示算法将运行的最大迭代次数。
    • learning_rate:学习率,默认值为 0.01,控制每次更新的步长。
    n_samples, n_features = X.shapealpha = np.zeros(n_samples)
  • 数据维度n_samplesn_features 分别表示样本数和特征数。
  • 初始化alpha 是拉格朗日乘子,初始化为零数组,长度为样本数。
    for _ in range(max_iter):
  • 迭代循环:主循环,控制最大迭代次数。
        for i in range(n_samples):
  • 样本循环:遍历每个样本。
            gradient = 1 - y[i] * np.sum(alpha * y * np.array([linear_kernel(X[i], X[j]) for j in range(n_samples)]))
  • 计算梯度
    • 线性核函数:计算所有样本与第 i i i 个样本的线性核(即点积)。
    • 梯度计算gradient 是对偶问题的梯度,计算公式为 1 − y i ∑ j = 1 n α j y j K ( x i , x j ) 1 - y_i \sum_{j=1}^{n} \alpha_j y_j K(x_i, x_j) 1yij=1nαjyjK(xi,xj)
    • linear_kernel(X[i], X[j]) 计算第 i i i 个样本和第 j j j 个样本的点积。
            alpha[i] += learning_rate * gradient
  • 更新拉格朗日乘子:按照梯度上升法更新 alpha
            alpha[i] = max(0, min(alpha[i], C))
  • 约束拉格朗日乘子:将 alpha[i] 限制在 0 到 C 之间,确保满足对偶问题的约束条件。
    return alpha
  • 返回结果:迭代结束后,返回更新后的 alpha 数组。

逐行解释总结

train_svm 函数实现了一个简化的支持向量机训练过程。主要步骤如下:

  1. 初始化 alpha 为零。
  2. 在最大迭代次数内,遍历所有样本,计算梯度并更新 alpha
  3. 每次更新 alpha 后,确保其在合法范围内(0 到 C)。
  4. 最终返回更新后的 alpha 值。

通过这种方法,我们得到了拉格朗日乘子 alpha,可以进一步用于计算权重向量和偏置,进而构建 SVM 模型进行分类预测。

6. 确定支持向量

支持向量是那些 α i > 0 \alpha_i > 0 αi>0的数据点:

support_vectors_idx = np.where(alpha > 1e-5)[0]
support_vectors = X[support_vectors_idx]
support_vector_labels = y[support_vectors_idx]

7. 计算权重和偏置

权重向量 w \mathbf{w} w 和偏置 b b b 的计算:

# 计算权重向量 w
w = np.sum(alpha[:, None] * y[:, None] * X, axis=0)

数学公式
w = ∑ i = 1 n α i y i x i w = \sum_{i=1}^{n} \alpha_i y_i x_i w=i=1nαiyixi

# 计算偏置 b
b = np.mean([y[i] - np.dot(w, X[i]) for i in support_vectors_idx])

数学公式
b = 1 ∣ S ∣ ∑ i ∈ S ( y i − w ⋅ x i ) b = \frac{1}{|S|} \sum_{i \in S} \left( y_i - w \cdot x_i \right) b=S1iS(yiwxi)

通过代码和公式的结合,可以更清晰地理解 SVM 模型的训练过程。

8. 进行预测

定义预测函数:

def predict(X):return np.sign(np.dot(X, w) + b)# 进行预测
new_points = np.array([[3, 2], [1, 3]])
new_points = (new_points - X_mean) / X_std
predictions = predict(new_points)

下面我们逐行解释如何使用高斯核(RBF核)来修改预测函数。首先我们回顾一下高斯核的公式:

K ( x i , x j ) = exp ⁡ ( − ∥ x i − x j ∥ 2 2 σ 2 ) K(x_i, x_j) = \exp\left(-\frac{\|x_i - x_j\|^2}{2\sigma^2}\right) K(xi,xj)=exp(2σ2xixj2)

这里的 σ \sigma σ是高斯核的参数,决定了核函数的宽度。

代码解释

import numpy as npdef gaussian_kernel(x, y, sigma=1.0):return np.exp(-np.linalg.norm(x - y) ** 2 / (2 * sigma ** 2))
  1. 定义高斯核函数gaussian_kernel(x, y, sigma=1.0) 计算两个向量 xy 之间的高斯核值。np.linalg.norm(x - y) ** 2 计算向量 xy 之间的欧几里得距离平方,然后除以 2 σ 2 2\sigma^2 2σ2并取负数,再用 np.exp 计算指数函数,得到核值。
def predict(X, support_vectors, support_vector_labels, alphas, b, sigma=1.0):y_pred = np.zeros(X.shape[0])for i in range(X.shape[0]):kernel_sum = 0for alpha, sv_y, sv in zip(alphas, support_vector_labels, support_vectors):kernel_sum += alpha * sv_y * gaussian_kernel(X[i], sv, sigma)y_pred[i] = kernel_sumreturn np.sign(y_pred + b)
  1. 定义预测函数predict 函数接受新的数据点 X,支持向量 support_vectors,支持向量的标签 support_vector_labels,拉格朗日乘子 alphas,偏置 b,以及高斯核参数 sigma

  2. 初始化预测结果y_pred = np.zeros(X.shape[0]) 创建一个与 X 的样本数量相同的零向量,用于存储预测结果。

  3. 遍历每个新数据点for i in range(X.shape[0]) 逐个遍历每个新样本 X[i]

  4. 计算每个样本的核函数和kernel_sum = 0 初始化当前样本的核函数和。接下来,通过 for alpha, sv_y, sv in zip(alphas, support_vector_labels, support_vectors) 遍历每个支持向量的拉格朗日乘子 alpha,标签 sv_y,以及支持向量 sv,计算 alpha * sv_y * gaussian_kernel(X[i], sv, sigma) 并累加到 kernel_sum 中。

  5. 存储预测值y_pred[i] = kernel_sum 将当前样本的核函数和赋值给 y_pred[i]

  6. 返回最终预测结果return np.sign(y_pred + b)y_pred 加上偏置 b 后取符号,得到最终的预测结果。

假设我们已经训练好了一个使用高斯核的 SVM 模型,得到了支持向量、支持向量标签、拉格朗日乘子和偏置。使用上述 predict 函数,我们可以对新的数据点进行分类预测。

这样,我们通过逐行解释了如何修改预测函数以使用高斯核来处理非线性分类问题。

小结

以上代码展示了如何手动实现一个简单的线性支持向量机(SVM)模型。我们生成了一些假数据,进行了数据标准化,定义了线性核函数,通过梯度上升法求解对偶问题,确定支持向量,计算了模型参数,并进行了预测。

这个例子只是一个简化的版本,实际应用中,SVM 的训练过程涉及更多的细节和优化算法,如序列最小优化(SMO)等。通过这一例子,你可以理解 SVM 的基本原理和求解过程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kotlin协程的理解

伴生对象:companion object 其实质等同于Java中的单例模式 协程:通常实现是用户态的任务协作式调度 一段可执行代码可挂起/可恢复执行概念上与语言无关,协程这个概念于1958年提出 依赖框架: 协程的启动: 1.协程体&a…

大模型LLMs概述:利用大模型 (LLMs) 解决信息抽取任务

论文标题:Large Language Models for Generative Information Extraction: A Survey 论文链接:https://arxiv.org/pdf/2312.17617.pdf 论文主要探讨了大型语言模型(LLMs)在生成式信息抽取(IE)任务中的应用…

属性描述符初探——Vue实现数据劫持的基础

目录 属性描述符——Vue实现数据劫持的基础 一、属性描述符是什么? ​编辑 1.1、属性描述符示例 1.2、用属性描述符定义属性及获取对象的属性描述符 1.3、带有读取器和设置器的属性描述符 二、使用属性描述符的情景 2.1、封装和数据隐藏 使用getter和setter…

Desktop docker 部署 WordPress

Desktop Docker 部署 WordPress 之前都是在Linux里面玩的,今天看到别人在windwos下安装docker,一时兴起装了一个试试,效果一般,很吃硬盘空间和内存。 首先在docker官方下载桌面版,安装下一步一直到完成。 安装完docker会自动加入到环境变量,而且docker-compose也会一并安…

sql业务场景分析思路参考

1、时间可以进行排序,也可以用聚合函数对时间求最大值max(时间) 例如下面的例子:取最晚入职的人,那就是将入职时间倒序排序,然后limit 1 表: 场景:查找最晚入职员工的所有信息 se…

第十四届蓝桥杯省赛C++B组F题【岛屿个数】题解(AC)

题目大意 给定一个 01 地图,分别表示陆地和海,问地图中一共有多少块岛屿?另外,若一个岛屿在另一个岛屿的内部,则不统计。如下图中的大岛屿包含着内部的小岛屿,故内部小岛屿不计算,最终输出 1。…

vue3自定义全局指令和局部指令

1.全局指令 el:指令绑定到的DOM元素,可以用于直接操作当前元素,默认传入钩子的就是el参数,例如我们开始实现的focus指令,就是直接操作的元素DOM binding:这是一个对象,包含以下属性:…

oracle中的nocache的用法和例子

在Oracle数据库中,NOCACHE是与序列(Sequence)对象相关的一个选项,用于控制序列值的生成方式。当在创建或修改序列时指定NOCACHE选项,Oracle数据库将不会预先在内存中缓存序列值,而是每次调用序列的NEXTVAL时…

【C#】ProgressBar进度条异步编程思想

1.控件介绍 进度条通常用于显示代码的执行进程进度,在一些复杂功能交互体验时告知用户进程还在继续。 在属性栏中,有三个值常用: Value表示当前值,Minimum表示进度条范围下限,Maximum表示进度条范围上限。 2.简单实…

简单的git pull fail Can‘t update has no tracked branch解决记录

简单的git pull fail Can‘t update has no tracked branch解决记录 1. 问题描述 上午同事使用idea拉取代码的时候,发现拉取不了,提示用户权限问题,之后修改了git用户信息,发现还是拉取不了分支代码,然后删除了git r…

对FPGA开发流程系统的学习

FPGA 开发流程: HDL(Hardware Design Language)和原理图是两种最常用的数字硬件电路描述方法,HDL 设计法具有更好的可移植性、通用性和模块划分与重用性的特点,在目前的工程设计中被广泛使用。所以,我们在…

WPF在.NET9中的重大更新:Windows 11 主题

在2023年的2月20日,在WPF的讨论区,WPF团队对路线的优先级发起了一次讨论。 对三个事项发起了投票。 第一个是Windows 11 主题 第二个是更新的控件 第三个是可空性注释 最终Windows 11 主题得票最高,WPF团队2023-2024的工作优先级就是Windows…

网安小贴士(8)IPv4与IPv6

一、前言 IPv4和IPv6都是互联网协议(IP)的版本,它们用于在互联网上标识和定位设备。 二、定义 IPv4(互联网协议第四版): IPv4是互联网协议的第一个广泛使用的版本,最初在1981年被标准化为RFC 7…

利用Java构建高可靠性的分布式系统

利用Java构建高可靠性的分布式系统 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. 引言 随着互联网应用的发展和用户规模的增长,构建高可靠性…

交换数字00

题目链接 交换数字 题目描述 注意点 numbers.length 2-2147483647 < numbers[i] < 2147483647 解答思路 不适用临时变量&#xff0c;可以先将numbers[0]和numbers[1]的信息都存到某个位置&#xff08;可以相加可以相减或其他位操作&#xff09;&#xff0c;然后另一…

SpringBoot 通过Knife4j集成API文档 在线调试

介绍 Knife4j 是一款基于 Swagger 构建的增强型 API 文档生成工具&#xff0c;它提供了更多的定制化功能和界面优化&#xff0c;使得生成的 API 文档更加美观和易用。它可以帮助开发者快速生成和管理 API 文档&#xff0c;支持在线调试和交互。 依赖 <!--knife4j--> &…

期末C语言易错知识点整理

1.在定义多维数组时&#xff0c;除了最左边的维度&#xff0c;其余的维度必须明确指定大小 2.int m[1][4]{4}; 定义的是一个 1 行 4 列的二维数组&#xff0c;初始化时提供了一个元素 4&#xff0c;其余元素默认初始化为 0&#xff0c;因此是正确的。 3.二维数组 a[3][6] 中的索…

谷粒商城学习笔记-05-项目微服务划分图

文章目录 一&#xff0c;商城业务服务-前端服务二&#xff0c;商城业务服务-后端服务三&#xff0c;存储服务四&#xff0c;第三方服务五&#xff0c;服务治理六&#xff0c;日志七&#xff0c;监控预警系统1&#xff0c;Prometheus2&#xff0c;Grafana3&#xff0c;Prometheu…

科技助力农业——土壤化肥测试仪

在农业生产中&#xff0c;土壤养分是作物健康生长的关键因素。然而&#xff0c;如何科学、精准地评估土壤养分含量&#xff0c;指导农民合理施肥&#xff0c;一直是农业科研和技术人员努力的方向。近年来&#xff0c;随着科技的进步&#xff0c;土壤化肥测试仪作为一种新型农业…

clion远程开发

clion远程开发 简要概括&#xff1a; 建立 SFTP 通讯&#xff0c;创建远程目录与本地目录的映射文件夹&#xff0c;就可以把本机文件夹中的文件用鼠标右键选中上全传&#xff0c;打开自动同步功能&#xff0c;后面更改文件就可以自动同步文件了。 一.新建SFTP远程链接服务 …