目录

介绍

SVM模型

优化问题

优化算法

分类

结论与分析


可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表。

介绍

支持向量机(SVM)是一种基于特征空间最大边距的分类器。SVM的学习策略是使边际最大,可以转化为凸二次规划问题。在学习SVM算法之前,我先介绍一些术语。

功能边距定义为:对于给定的训练集T和超平面(w,b),超平面(w,b)和样本(xi, yi)之间的功能边距为:

超平面(w,b)和训练集T之间的功能边距是的最小值

功能边距表示分类结果的置信水平。如果超参数(w,b) 按比例变化,例如,(w,b)变为(2w,2b)。虽然超平面没有改变,但功能边距消耗增加了一倍。因此,我们在w上应用一些禁令来定义超平面,例如规范化||w|| = 1。然后,边界称为几何边距:对于给定的训练集T和超平面(w,b),超平面(w,b) 和样本(xi, yi)之间的功能边距为:

类似地,超平面(w,b) 和训练集T之间的几何边距是的最小值

现在,我们可以得出功能边距与几何边距之间的关系:

SVM模型

SVM模型由优化问题,优化算法和分类组成。

优化问题

当数据集可线性分离时,支持向量是最接近超平面的样本,如下所示。

对样品H1和H2是之间的支持向量。在H1和H2之间的距离被称为硬边距。然后,SVM的优化问题是:

当数据集不是线性可分时,训练集中的一些样本不满足函数余量大于或等于1的条件。为了解决这个问题,我们为每个样本(xi, yi)添加一个松弛变量。然后,约束是:

同时,为每个松弛变量添加成本。目标函数是:

其中C是惩罚系数。当C规模很大时,对错误分类的惩罚将会增加,然而对错误分类的惩罚将会减少。然后,SVM的优化问题是:

支撑向量位于边距的边界上或边界和超平面之间,如下所示。在这种情况下,边距为软边距

当数据集不是线性可分的时,它需要应用内核技巧将数据从原始空间转换为特征空间。内核技巧的函数叫做内核函数,定义如下:

其中是从输入空间到特征空间的映射,即

内核技巧的代码如下所示:

def kernelTransformation(self, data, sample, kernel):sample_num, feature_dim = np.shape(data)K = np.zeros([sample_num])if kernel == "linear":  # linear functionK = np.dot(data, sample.T)elif kernel == "poly":  # polynomial functionK = (np.dot(data, sample.T) + self.c) ** self.nelif kernel == "sigmoid":  # sigmoid functionK = np.tanh(self.g * np.dot(data, sample.T) + self.c)elif kernel == "rbf":  # Gaussian functionfor i in range(sample_num):delta = data[i, :] - sampleK[i] = np.dot(delta, delta.T)K = np.exp(-self.g * K)else:raise NameError('Unrecognized kernel function')return K

应用内核技巧后,SVM的优化问题是:

其中是拉格朗日因子。

优化算法

用传统的凸二次规划算法求解SVM优化问题是可行的。但是,当训练集很大时,算法将花费很长时间。为了解决这个问题,Platt提出了一种称为顺序最小优化(SMO)的有效算法。

SMO是一种启发式算法。当所有变量都遵循KKT条件时,优化问题就解决了。否则,选择两个变量并修复其他变量,并用两个变量构造凸二次规划问题。问题有两个变量:一个选择违反KKT条件的alpha,另一个选择由约束决定。表示,是变量,修复。因此,有如下方法计算:

如果确定,则相应地确定。在SMO的每次迭代中,更新两个变量直到问题解决。然后,SVM的优化问题是:

当只有两个变量时,它是一个简单的二次规划问题,如下所示:

因为约束是:

,因为

优化值如下:

其中L和H是对角线的下限和上限,其计算公式为:

未切割的优化值如下:

其中E 1和E 2是预测值g(x)和实际值之间的差值。g(x)定义为:

到目前为止,我们为获得可行的解决办法:

SMO中有两个循环,即外循环和内循环。

外部循环中,选择违反KKT条件的alpha,即

首先,按照搜索样本。如果所有样本都遵循该条件,则搜索整个数据集。

内部循环,先搜索,这使得最大。如果所选择的值没有减少,请首先在边距边界上搜索样本。如果选择的值减少,请停止搜索。否则,搜索整个数据集。如果我们在搜索整个数据集后找到可行的,我们将选择一个新的

在每次迭代中,我们通过如下算式更新b:

为方便起见,我们必须存储的值,其计算方法如下:

搜索和更新代码如下所示:

def innerLoop(self, i):Ei = self.calculateErrors(i)if self.checkKKT(i):j, Ej = self.selectAplha2(i, Ei)          # select alpha2 according to alpha1# copy alpha1 and alpha2old_alpha1 = self.alphas[i]old_alpha2 = self.alphas[j]# determine the range of alpha2 L and H      in page of 126# if y1 != y2    L = max(0, old_alpha2 - old_alpha1), H = min(C, C + old_alpha2 - old_alpha1)# if y1 == y2    L = max(0, old_alpha2 + old_alpha1 - C), H = min(C, old_alpha2 + old_alpha1)if self.train_label[i] != self.train_label[j]:L = max(0, old_alpha2 - old_alpha1)H = min(self.C, self.C + old_alpha2 - old_alpha1)else:L = max(0, old_alpha2 + old_alpha1 - self.C)H = min(self.C, old_alpha2 + old_alpha2)if L == H:# print("L == H")return 0# calculate eta in page of 127 Eq.(7.107)# eta = K11 + K22 - 2K12K11 = self.K[i, i]K12 = self.K[i, j]K21 = self.K[j, i]K22 = self.K[j, j]eta = K11 + K22 - 2 * K12if eta <= 0:# print("eta <= 0")return 0# update alpha2 and its error in page of 127 Eq.(7.106) and Eq.(7.108)self.alphas[j] = old_alpha2 + self.train_label[j]*(Ei - Ej)/etaself.alphas[j] = self.updateAlpha2(self.alphas[j], L, H)new_alphas2 = self.alphas[j]self.upadateError(j)# update the alpha1 and its error in page of 127 Eq.(7.109)# new_alpha1 = old_alpha1 + y1y2(old_alpha2 - new_alpha2)new_alphas1 = old_alpha1 + self.train_label[i] * self.train_label[j] * (old_alpha2 - new_alphas2)self.alphas[i] = new_alphas1self.upadateError(i)# determine b in page of 130 Eq.(7.115) and Eq.(7.116)# new_b1 = -E1 - y1K11(new_alpha1 - old_alpha1) - y2K21(new_alpha2 - old_alpha2) + old_b# new_b2 = -E2 - y1K12(new_alpha1 - old_alpha1) - y2K22(new_alpha2 - old_alpha2) + old_bb1 = - Ei - self.train_label[i] * K11 * (old_alpha1 - self.alphas[i]) - self.train_label[j] * K21 * (old_alpha2 - self.alphas[j]) + self.bb2 = - Ej - self.train_label[i] * K12 * (old_alpha1 - self.alphas[i]) - self.train_label[j] * K22 * (old_alpha2 - self.alphas[j]) + self.bif (self.alphas[i] > 0) and (self.alphas[i] < self.C):self.b = b1elif (self.alphas[j] > 0) and (self.alphas[j] < self.C):self.b = b2else:self.b = (b1 + b2)/2.0return 1else:return 0

分类

我们可以使用优化的参数进行预测,该参数由下式给出:

for i in range(test_num):kernel_data = self.kernelTransformation(support_vectors, test_data[i, :], self.kernel)probability[i] = np.dot(kernel_data.T, np.multiply(support_vectors_label, support_vectors_alphas)) + self.bif probability[i] > 0:prediction[i] = 1else:prediction[i] = -1

结论与分析

SVM是一种比以前的算法更复杂的算法。在本文中,我们简化了搜索过程,使其更容易理解。最后,让我们将我们的SVM与Sklearn中的SVM进行比较,检测性能如下所示:

检测性能比sklearn更差,这是因为我们的SVM中的SMO比sklearn更简单。

可以在MachineLearning中找到本文中的相关代码和数据集。

有兴趣的小伙伴可以查看上一篇或者下一篇。

原文地址:https://www.codeproject.com/Articles/4064358/Step-by-Step-Guide-to-Implement-Machine-Learning-V

实现机器学习的循序渐进指南V——支持向量机相关推荐

  1. 实现机器学习的循序渐进指南系列汇总

    之前曾尝试翻译了机器学习中的KNN和决策树,最近这段时间陆续看到这个系列的相关文章,并尝试翻译分析.由于此系列文章直接相对零散,所以有了这篇简单的汇总文章,以帮助有兴趣的小伙伴迅速找到想看的文章. 具 ...

  2. 实现机器学习的循序渐进指南XII——Apriori

    目录 介绍 Apriori模型 频繁项集 关联规则 结论与分析 可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表. 介绍 Apriori是一种学习频繁项集和关联规则的算法.Aprio ...

  3. 实现机器学习的循序渐进指南XI——DBSCAN

    目录 介绍 DBSCAN模型 开始 聚类算法 参数估计 结论与分析 可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表. 介绍 基于密度的噪声应用空间聚类(DBSCAN)是一种基于密度 ...

  4. 实现机器学习的循序渐进指南X——KMeans

    目录 介绍 KMeans模型 KMEANS 平分KMeans KMEANS ++ 结论与分析 可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表. 介绍 KMeans是一种简单的聚类算 ...

  5. 实现机器学习的循序渐进指南VIII——线性回归

    目录 介绍 回归模型 线性回归 局部加权线性回归 岭回归 套索(Lasso)回归 逐步线性回归 结论与分析 可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表. 介绍 通常存在变量之间 ...

  6. 实现机器学习的循序渐进指南IX ——树回归

    目录 介绍 回归模型 特征选择 回归树的生成 回归 结论与分析 可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表. 介绍 在现实世界中,一些关系不是线性的.因此,应用线性回归分析这些 ...

  7. 实现机器学习的循序渐进指南VII——Blending Stacking

    目录 介绍 混合(Blending)模型 混合(Blending)架构 混合(Blending)实现 混合(Blending)分类 堆叠(Stacking)模型 堆叠(Stacking)架构 堆叠(S ...

  8. 实现机器学习的循序渐进指南VI——AdaBoost

    目录 介绍 AdaBoost模型 弱分类器 权重更新 分类 结论与分析 可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表. 介绍 AdaBoost是Boosting的一种方法,它基于 ...

  9. 实现机器学习的循序渐进指南IV——逻辑回归

    目录 介绍 逻辑回归模型 参数估计 优化算法 分类 结论与分析 可访问 实现机器学习的循序渐进指南系列汇总,获取本系列完成文章列表. 介绍 逻辑回归是统计学习中的经典方法,它计算条件概率P(Y|X)并 ...

最新文章

  1. 教你用ERD轻松修改系统登录密码
  2. 群晖备份linux分区,黑群晖二合一系统无损扩充系统分区方法补充
  3. 哈希表和有序表的简单介绍
  4. linux中如何运行html文件路径问题,Linux中如何查询运行文件的全路径的方法
  5. sublime3使用笔记
  6. 【转】how can i build fast
  7. 迎建国七十周年,Linux厂商巡礼之一铭软件
  8. c/c++中与字符串处理相关的函数
  9. dubbo学习视频教程
  10. 基于Proteus的51单片机程序设计及仿真(交通灯控制系统)
  11. python绘图画猫咪_Turtle库画小猫咪
  12. 是的你没看错,HTTP3来了
  13. 推荐使用的热电阻Pt100测温电路
  14. mysql error 1236_【MySQL】Got fatal error 1236原因和解决方法
  15. Android 10.0 SystemUI修改状态栏电池图标样式为横屏显示
  16. java根据身份证获取出生年月日,性别,年龄
  17. 联想拯救者Y7000P触摸板无法使用
  18. 阿里云数据库RDS MySQL Serverless测评
  19. 第二阶段--团队冲刺--第三天
  20. 学JAVA可从事的工作岗位

热门文章

  1. python创建包含双引号的字符串代码_python 字符串组成MySql 命令时,字符串含有单引号或者双引号导致出错解决办法...
  2. mysql配置修改记录_mysql设置修改时间,更新记录当前时间
  3. 最受欢迎的资源是高质量的GUI工具包
  4. 如何使用模板生成多个页面_Divi不再只是页面构建器。 使用主题生成器,可以完全设计整个网站。...
  5. windows 根据进程id获得进程名称 C++
  6. systemd.generator — systemd unit generators
  7. Memcached下载与安装
  8. 汇编中bss,data,text,rodata,heap,stack段的作用
  9. 深度学习与神经网络概述
  10. qq html消息,类似于QQ新消息提醒-前端