当前位置: 首页 > news >正文

近似线性可分支持向量机 代码实现

### 定义近似线性可分支持向量机
### 软间隔最大化策略
class Soft_Margin_SVM:### 定义基本参数def __init__(self, kernel=linear_kernel, C=None):# 软间隔svm核函数,默认为线性核函数self.kernel = kernel# 惩罚参数self.C = Cif self.C is not None: self.C = float(self.C)### 定义线性支持向量机拟合方法def fit(self, X, y):# 训练样本数和特征数m, n = X.shape# 基于线性核计算Gram矩阵K = self._gram_matrix(X)# 初始化二次规划相关变量:P/q/G/hP = matrix(np.outer(y,y) * K)q = matrix(np.ones(m) * -1)A = matrix(y, (1, m))b = matrix(0.0)# 未设置惩罚参数时的G和h矩阵if self.C is None:G = matrix(np.diag(np.ones(m) * -1))h = matrix(np.zeros(m))# 设置惩罚参数时的G和h矩阵else:tmp1 = np.diag(np.ones(m) * -1)tmp2 = np.identity(m)G = matrix(np.vstack((tmp1, tmp2)))tmp1 = np.zeros(m)tmp2 = np.ones(m) * self.Ch = matrix(np.hstack((tmp1, tmp2)))# 构建二次规划求解sol = solvers.qp(P, q, G, h, A, b)# 拉格朗日乘子a = np.ravel(sol['x'])# 寻找支持向量spv = a > 1e-5ix = np.arange(len(a))[spv]self.a = a[spv]self.spv = X[spv]self.spv_y = y[spv]print('{0} support vectors out of {1} points'.format(len(self.a), m))# 截距向量self.b = 0for i in range(len(self.a)):self.b += self.spv_y[i]self.b -= np.sum(self.a * self.spv_y * K[ix[i], spv])self.b /= len(self.a)# 权重向量self.w = np.zeros(n,)for i in range(len(self.a)):self.w += self.a[i] * self.spv_y[i] * self.spv[i]### 定义Gram矩阵计算函数def _gram_matrix(self, X):m, n = X.shapeK = np.zeros((m, m))# 遍历计算Gram矩阵for i in range(m):for j in range(m):K[i,j] = self.kernel(X[i], X[j])return K

这段代码定义了一个 近似线性可分支持向量机(SVM) 的实现,采用了 软间隔最大化策略,并通过二次规划(Quadratic Programming, QP)来求解最优分类器。它通过核函数支持线性或非线性分类。下面是对这段代码的详细解释:

1. __init__() - 初始化模型参数

def __init__(self, kernel=linear_kernel, C=None):self.kernel = kernelself.C = Cif self.C is not None: self.C = float(self.C)
  • kernel:这是支持向量机的核函数,默认为 linear_kernel(线性核函数)。核函数用于计算两个样本之间的相似性,常用的核函数包括线性核、多项式核、RBF核等。
  • C:这是 SVM 的惩罚参数 C C C,用于控制软间隔。C 是 SVM 中的重要超参数,它平衡分类间隔的最大化和误分类样本的容忍度:
    • 较大的 C 倾向于减少误分类样本,但可能会导致过拟合。
    • 较小的 C 允许更多的误分类,以提高模型的泛化能力。

2. fit() - 训练支持向量机

def fit(self, X, y):m, n = X.shapeK = self._gram_matrix(X)P = matrix(np.outer(y, y) * K)q = matrix(np.ones(m) * -1)A = matrix(y, (1, m))b = matrix(0.0)
(1) 输入数据
  • X:训练数据的特征矩阵,形状为 ( m , n ) (m, n) (m,n),其中 m m m 是样本数, n n n 是特征数。
  • y:标签向量,形状为 ( m , ) (m,) (m,),每个样本对应一个标签 y i ∈ { − 1 , 1 } y_i \in \{-1, 1\} yi{1,1}
(2) Gram 矩阵的计算
  • K = self._gram_matrix(X):计算 Gram 矩阵 K K K,表示样本之间的相似性。对于线性核 k ( x i , x j ) = x i ⋅ x j k(x_i, x_j) = x_i \cdot x_j k(xi,xj)=xixj,Gram 矩阵就是输入数据的内积矩阵。
(3) 二次规划的定义
  • P:目标函数的二次项,定义为 P = y i y j K i j P = y_i y_j K_{ij} P=yiyjKij
  • q:线性项,定义为 q = − 1 q = -1 q=1 向量。
  • Ab:线性等式约束,确保 ∑ α i y i = 0 \sum \alpha_i y_i = 0 αiyi=0

3. 处理约束条件

if self.C is None:G = matrix(np.diag(np.ones(m) * -1))h = matrix(np.zeros(m))
else:tmp1 = np.diag(np.ones(m) * -1)tmp2 = np.identity(m)G = matrix(np.vstack((tmp1, tmp2)))tmp1 = np.zeros(m)tmp2 = np.ones(m) * self.Ch = matrix(np.hstack((tmp1, tmp2)))
(1) 无惩罚参数 C C C
  • 如果 C C C 没有设置,则这是一个 硬间隔 SVM,没有松弛变量。约束条件为 α i ≥ 0 \alpha_i \geq 0 αi0
(2) 有惩罚参数 C C C
  • 当设置了惩罚参数 C C C 时,这是 软间隔 SVM,允许有误分类。约束条件为 0 ≤ α i ≤ C 0 \leq \alpha_i \leq C 0αiC,其中 α i \alpha_i αi 是拉格朗日乘子。

4. 二次规划求解

sol = solvers.qp(P, q, G, h, A, b)
a = np.ravel(sol['x'])

通过 solvers.qp() 调用 CVXOPT 库来求解二次规划问题,返回的解 sol['x'] 是拉格朗日乘子 α \alpha α

5. 支持向量的确定

spv = a > 1e-5
ix = np.arange(len(a))[spv]
self.a = a[spv]
self.spv = X[spv]
self.spv_y = y[spv]
print('{0} support vectors out of {1} points'.format(len(self.a), m))

通过判断 α i > 1 e − 5 \alpha_i > 1e-5 αi>1e5 来识别支持向量,这些支持向量会影响最终的分类边界。

6. 计算偏置项 b b b

self.b = 0
for i in range(len(self.a)):self.b += self.spv_y[i]self.b -= np.sum(self.a * self.spv_y * K[ix[i], spv])
self.b /= len(self.a)

偏置项 b b b 是通过支持向量的标签和 Gram 矩阵的相似性来计算的,它用于调整决策边界的位置。

7. 计算权重向量 w w w

self.w = np.zeros(n,)
for i in range(len(self.a)):self.w += self.a[i] * self.spv_y[i] * self.spv[i]

对于线性支持向量机,权重向量 w w w 是支持向量的线性组合。

8. _gram_matrix() - 计算 Gram 矩阵

def _gram_matrix(self, X):m, n = X.shapeK = np.zeros((m, m))for i in range(m):for j in range(m):K[i, j] = self.kernel(X[i], X[j])return K

Gram 矩阵计算了每对样本之间的核函数值,用于定义二次规划的目标函数。


总结

这段代码实现了软间隔支持向量机的训练过程,主要包括以下步骤:

  • 核函数:通过核函数(默认线性核)来计算样本间的相似性。
  • 二次规划:构建了二次规划问题,最大化分类间隔,并允许误分类(通过惩罚参数 C C C 控制)。
  • 支持向量:利用拉格朗日乘子 α \alpha α 识别支持向量,这些向量决定了分类边界。
  • 权重与偏置:最终通过支持向量计算分类决策函数的权重 w w w 和偏置 b b b,用于分类新样本。

http://www.mrgr.cn/news/59671.html

相关文章:

  • 【p2p、分布式,区块链笔记 IPFS】go-ipfs windows系统客户端节点实现 kubo试用
  • 故障诊断 | MTF-TLSSA-DarkNet-GRU-MSA迁移学习故障识别程序(t分布+莱维飞行改进麻雀优化)
  • c++数据抽象
  • LabVIEW显微镜自动对焦系统
  • 毕业设计选题:基于Python的个性化旅游路线推荐系统-flask+vue
  • 表格编辑demo
  • 使用代理服务器后sse数据合并问题
  • C++的继承和多态
  • 基于用户体验的在线相册管理平台创新设计与实现
  • Linux日志分析-应急响应实战笔记
  • CSS中为特定的元素设置背景图片(Top1,Top1,Top3)
  • 记一次内存溢出排查(dump文件)
  • RHCE nfs作业
  • C++11实践指北
  • OpsAny社区版与专业版的主要区别是什么
  • 农作物大豆病虫害识别分类数据集(猫脸码客第227期)
  • 基于IMX6ULL开发板LCD点阵显示字符学习
  • C++——string的模拟实现(上)
  • Fofa搜索技巧(理论加实践的整理)
  • TypeError: predict2() missing 1 required positional argument: ‘img2‘
  • 将CSDN博客转换为PDF的Python Web应用开发--Flask实战
  • IDEA中add frame work support被禁用或找不到的解决方案
  • 使用 Axios 上传大文件分片上传
  • 2023年06月中国电子学会青少年软件编程(图形化)等级考试试卷(一级)答案 + 解析
  • 【数据集】全球陆地表面反照率Albedo
  • MIT 6.824 Lab1记录