监督学习:线性回归基础
Picture from Unsplash
1.介绍
回归分析是监督机器学习的一个子领域。它旨在模拟一定数量的特征和连续目标变量之间的关系。
在回归问题中,我们试图给出一个定量的答案,比如预测房子的价格或某人看视频的秒数。
2.简单线性回归:通过数据拟合直线
有了一组点,回归算法将对单个特征(解释变量 x)和连续值响应(目标变量 y)之间的关系进行建模。
该模型将通过设置一条任意线并计算从这条线到数据点的距离来模拟这种关系。这个距离,垂直线,是残差或预测的误差。
回归算法将在每次迭代中不断移动直线,试图找到最合适的直线,换句话说,就是误差最小的直线。
有几种技术来执行这项任务,最终目标是使线更接近最大点数。
2.1 移动线
Figure by the Author
绝对的诡计
当有一个点和一条线时,目标是让线更靠近这个点。为了完成这项任务,算法将使用一个称为“学习率”的参数。该学习率是将与函数参数相乘的数字,以便在逼近直线到点时进行小步进。
换句话说,学习率将决定每次迭代中使直线更接近该点的距离长度。它通常被表示为α符号。
2.1.2 方块戏法
它基于以下前提:如果有一个点更靠近一条线,并且距离很小,那么这条线就移动一点距离。如果远的话,线会移动很多。
3。梯度下降
假设我们有一组点,我们想开发一种算法,找到最适合这组点的直线。如前所述,误差是从直线到点的距离。
移动直线并计算误差。这个过程一遍又一遍地重复,每次减少一点点误差,直到获得完美的线条。这条完美的线将是误差最小的线。为了减小这种误差,我们将使用梯度下降法。
梯度下降法是一种方法,对于每一步,该方法将观察线可以移动的不同方向,以减少误差,并采取措施减少大部分误差。
维基百科中梯度的定义:
escalar 场(f)的梯度是一个向量场。当它在 f 的定义域的一般点上求值时,它表明了 f 的快速方差的方向。
所以梯度下降会朝着负梯度的方向前进一步。
Figure by Author
当该算法采取足够的步骤时,如果学习率被设置为适当的值,它将最终达到局部或全局最小值。这是一个非常重要的细节,因为如果学习率太高,算法将会错过最小值,因为它将采取太大的步骤。而如果这个学习率太低,就需要无限的时间才能到达重点。
Figure by Author
4。梯度下降法
4.1 随机梯度下降
当梯度下降逐点进行时。
4.2 批次梯度下降
当对所有数据点应用平方或绝对技巧时,我们获得一些值来添加到模型的权重中,将它们相加,然后用这些值的总和来更新权重。
4.3 小批量梯度下降
实际上,前面两种方法都没有用,因为从计算上来说都很慢。执行线性回归的最佳方法是将数据分成许多小批。每批,点数大致相同。然后使用每个批次来更新权重。这种方法被称为小批量梯度下降。
5。更高的尺寸
当我们有一个输入列和一个输出列时,我们面临的是一个二维问题,回归是一条线。预测将是一个常数由自变量加上其他常数。
如果我们有更多的输入列,这意味着有更多的维度,输出将不再是一条线,而是平面或超平面(取决于维度的数量)。
6。多元线性回归
自变量也被称为预测因子,它是我们用来预测其他变量的变量。我们试图预测的变量被称为因变量。
当我们试图预测的结果取决于不止一个变量时,我们可以建立一个更复杂的模型,将这种更高维度考虑在内。只要它们与所面临的问题相关,使用更多的预测变量可以帮助我们获得更好的预测。
如前所述,下图显示了一个简单的线性回归:
Figure by Author
下图显示了具有两个特征的多元线性回归的拟合超平面。
Figure by Author
随着我们增加更多的预测因素,我们给问题增加了更多的维度,也变得更加难以想象,但是这个过程的核心仍然是一样的。
7。线性回归警告
线性回归有一套假设,我们应该考虑到它并不是每种情况下的最佳模型。
a)当数据为线性时,线性回归效果最佳:
它从训练数据中产生一条直线。如果训练数据中的关系不是真正的线性,我们将需要进行调整(转换训练数据)、添加特征或使用其他模型。
b)线性回归对异常值敏感:
线性回归试图拟合训练数据中的最佳直线。如果数据集有一些不符合一般模式的异常极值,线性回归模型可能会受到异常值的严重影响。我们将不得不小心这些异常值,然后正常删除。
处理异常值的一种常用方法是使用替代的回归方法,这种方法对这种极值特别稳健。这种方法被称为随机样本一致性(RNASAC)算法,该算法将模型拟合到数据的内联子集。该算法执行以下步骤:
- 它选择随机数量的样本作为内联体并拟合模型。
- 它根据拟合的模型测试所有其他数据点,并添加属于用户选择值的数据点。
- 用新点重复模型的拟合。
- 计算拟合模型相对于内层的误差。
- 如果性能满足某个用户定义的阈值或达到迭代次数,则结束算法。否则,返回第一步。
7 .。多项式回归
多项式回归是多重线性 r 回归分析的特例,其中自变量 x 和因变量 y 之间的关系被建模为 x 中的 n 次多项式。换句话说,当我们的数据分布比线性分布更复杂时,我们使用线性模型来拟合非线性数据,从而生成曲线。
由预测变量的多项式展开产生的独立(或解释)变量被称为高次项。它被用来描述非线性现象,如组织的生长速度和疾病流行的进展。
Figure by Author
8。正规化
正则化是一种广泛使用的处理过拟合的方法。这主要通过以下技术实现:
- 减少模型的规模:减少模型中可学习参数的数量,从而减少其学习能力。目标是在学习能力过多和不足之间找到一个平衡点。不幸的是,没有任何神奇的公式来确定这种平衡,它必须通过设置不同数量的参数和观察其性能来测试和评估。
- 添加权重正则化:一般来说,模型越简单越好。只要它能很好地学习,一个更简单的模型就不太可能过度拟合。实现这一点的一种常见方法是通过强制其权重仅取小值来限制网络的复杂性,从而使权重值的分布规律化。这是通过向网络的损失函数添加与具有大权重相关联的成本来实现的。成本来自两个方面:
- L1 正则化:成本与权重系数的绝对值(权重的 L1 范数)成比例。
- l2 正则化:成本与权重系数(权重的 L2 范数)的值的平方成比例
Figure by Author
要决定哪一个应用于我们的模型,建议记住以下信息并考虑我们问题的性质:
Figure by Author
- λ参数:它是通过正则化计算的误差。如果我们有一个大的λ,那么我们是在惩罚复杂性,最终会得到一个更简单的模型。如果λ很小,我们将得到一个复杂的模型。
9。评估指标
为了跟踪我们的模型执行得有多好,我们需要设置一些评估指标。该评估度量是从生成的线(或超平面)到真实点计算的误差,并且将是通过梯度下降最小化的函数。
一些最常见的回归评估指标是:
9.1 平均绝对误差:
Figure by Author
平均绝对误差或 MAE 是真实数据点和预测结果之间的绝对差值的平均值。如果我们将此作为遵循的策略,梯度下降的每一步都将减少 MAE。
Figure by Author
9.2 均方误差:
Figure by Author
均方差或 MSE 是真实数据点和预测结果之间的平方差的平均值。这种方法惩罚越大的距离,这是标准的回归问题。
如果我们以此为策略,梯度下降的每一步都会降低 MSE。这将是计算最佳拟合线的首选方法,也称为普通最小二乘法或 OLS。
Figure by Author
9.3 均方根误差
均方根误差或 RMSE 是平方误差平均值的根,它是确定回归模型性能最常用的评估指标,因为根产生的单位与 y 相同
Figure by Author
9.4 决定系数或 R
决定系数可以理解为 MSE 的标准化版本,它为模型的性能提供了更好的可解释性。
从技术上讲,R 是模型捕获的响应方差的分数,换句话说,它是响应的方差。它被定义为:
Figure by Author
10。其他算法
虽然在本文中,我们关注的是线性和多元回归模型,但是在流行的机器学习库 Sci-kit learn(这是我们将在本系列中使用的库)中,几乎每种类型的算法都有回归变量。其中一些产生了非常好的结果。
一些例子是:
- 决策树回归器
- 随机森林回归量
- 支持向量回归机
- 套索
- 弹性网
- 梯度推进回归器
- Ada 增强回归器
11.结论
在整篇文章中,我们介绍了回归模型的基础知识,学习了它们的工作原理,主要的危险以及如何应对它们。我们还了解了最常见的评估指标是什么。
我们已经设置了开始使用我们的第一个机器学习模型的知识,这正是下一篇文章将要涵盖的内容。因此,如果您想学习如何使用 Sci-kit learn 库处理回归问题,请继续关注!
如果你喜欢这篇文章,那么你可以看看我关于数据科学和机器学习的其他文章 这里 。
如果你想了解更多关于机器学习、数据科学和人工智能的知识 请在 Medium 上关注我,敬请关注我的下一篇帖子!
监督机器学习
在我们开始这篇关于监督机器学习的文章之前,我们应该对什么是机器学习以及机器学习算法如何影响我们的决策有一个清晰的概念。
什么是机器学习?
机器学习是让计算机从例子中学习的实践,通过向它们提供数据,而不是显式地编程让它们这样做。机器学习使用统计学和计算机科学来开发实现计算机学习的算法。
A traditional Computer Program Photo By Ayush Kalla
A Machine Learning Model Photo By Ayush Kalla
机器学习模型与机器学习算法
机器学习算法是一种数学和统计学的通用规则,机器遵循它来“训练自己”。
机器学习模型是真实世界数据在一个或多个机器学习算法上的实现。
例如,线性回归算法是数学和统计学中的一组规则,使我们能够将点拟合到 y = mx + c 线上。另一方面,线性回归模型将使用这种线性回归算法来表示现实世界的问题,并可以根据新的输入为我们提供新的输出。例如,线性回归模型可以为我们提供线性方程 y = 2x + 3,其中常数 2 和 3 通过应用线性回归算法来确定。该模型可以根据输入(x)生成输出(y)。
现在我们知道了机器学习,就可以谈谈监督学习了。监督学习是一种通过向机器提供以前的实例及其输出来让机器学习的技术。**例如,**给机器学习模型输入数以千计不同的猫和狗的图像,并给出正确的输出,这将允许机器在未来区分猫和狗。
Supervised Learning Photo By Ayush Kalla
分类:预测我们预测的变量属于哪一类(狗或猫)
**多类分类:**如果预测变量有 2 类以上,称为多类分类。例如,天气类型(热、雨、冷、风)。这是一个包含 4 个类别的多类别分类。
**二元分类:**如果预测变量有 2 类,称为二元分类。例如,今天会下雨吗(会还是不会)
**回归:**预测连续变量,例如股票价格、平均收入等。回归被广泛用于处理金融数据。
培训和测试数据
在机器学习中,经常建议测试我们的模型。为此,我们可以将数据分为训练数据和测试数据。
**训练数据:**训练我们的机器学习模型的数据。
**测试数据:**用于测试模型效率的数据。
过度装配和装配不足
过拟合:如果模型被训练得太多,以至于它在训练数据上表现很好,但在测试数据上却不能给出类似的结果,这就叫做过拟合。
欠拟合:如果模型训练不够,称为欠拟合。
模型的精确度
模型的准确性告诉我们,我们的模型在使用新数据时表现如何。通过将模型与测试数据的实际输出和模型预测的输出进行比较,来确定模型的准确性。模型的高精度可以表明模型是一个好的模型,它可以很好地处理实时数据,并可以部署到实践中。
如果您有任何意见、建议或问题,请告诉我,我将很高兴收到您的来信。
监督机器学习:特征工程和超参数调整
特征工程是使用数据的领域知识来创建使机器学习算法工作的特征的过程。超参数优化或调谐是为学习算法选择一组最佳超参数的问题。与选择特定的模型相比,这些对模型验证的影响更大。在这里,我提供了一步一步的特征工程和超参数调整概述。
在这里,我们深入探讨特征工程和超参数调整步骤。在我们开始更好地理解模型验证之前,看看我以前的博客。 监督机器学习:模型验证,一步一步逼近 。
我将使用来自驱动数据的数据集。数据集用于从 Taarifa 和坦桑尼亚水利部的 水位表中 数据挖掘。这是一个具有高基数特征的多类分类问题。
特色工程
正如我之前的 博客 中提到的。特征工程是指识别独立特征和从属特征之间的关系。然后,我们可以将识别的关系添加为多项式或交互特征。
特征工程步骤是连续迭代的入口点。这是一个关键步骤,与模型验证相比,它在预测中起着更大的作用。
手头问题的领域知识将对特征工程有很大的用处。在这里,我将为新的识别特性提供一些思想模型。
让我们先看一下数据。似乎存在具有高基数和 NaN 值的要素。
如果需要,我们可以删除具有高基数和 NaN 值的列。同样对于数字特征,我们可以用其平均值、中值或众数来填充 NaN 值,而不是丢弃它。同样,对于分类特征,我们可以将 NaN 归类为一个单独的类别。
同样基于地下水位数据集,我们可以设计一些特征,如:
-
经度和纬度中的 NaN 值用其平均值更新。
-
识别出资方是否至少出资了 5 台泵的二元特征。同样确定安装人员是否安装了至少 5 台泵。
-
基于前缀对高基数的分类特征数据进行分组。更好的方法是详细分析数据集,并尝试根据某种逻辑结构对它们进行分组。
-
根据同一病房其他泵的中值更新建造 _ 年份。
-
将日期记录拆分为年记录和月记录。甚至分组在不同箱中。
-
根据建造年份和记录年份计算泵的年龄。
超参数调谐
超参数优化或调整是为学习算法选择一组最优超参数的问题。同一种机器学习模型可能需要不同的约束、权重或学习速率来概括不同的数据模式。这些措施被称为超参数,必须进行调整,以便模型可以最优地解决机器学习问题。超参数优化找到超参数元组,该元组产生最佳模型,该模型最小化给定独立数据上的预定义损失函数。目标函数采用一组超参数并返回相关损失。交叉验证通常用于评估这种泛化性能。
来源: 维基百科
简而言之,超参数调优意味着找到参数的最佳值。作为其中的一部分,我们选择了一系列值来调整参数。然后根据交叉验证结果确定哪个值更合适。然后进入下一组模型参数。超参数调整是一个微妙而繁琐的比较和排除过程。
这里我们用xgb classifier进行分类。 GridSearchCV 用于与独立测试数据集的交叉验证。为了简洁起见,让我们跳过管道和 param_grid 创建的细节。详情参考之前的博客。这里我来举例说明 XGBClassifier 的参数 max_depth 和 min_child_weight 的调整。
max_depth (int) — 基础学习者的最大树深度。
- 用于控制过度拟合,因为较高的深度将允许模型学习特定样本的特定关系。
- 典型值:3–9
min_child_weight (int) —一个孩子所需实例重量的最小总和(hessian)。
- 用于控制过度拟合。较高的值会阻止模型学习可能高度特定于为树选择的特定样本的关系。
- 过高的值会导致拟合不足,因此应该使用 CV 进行调整。典型值:1–5
参数调整的第一次迭代的输出:
- **交叉验证得分:**0。46860 . 66866868661
- 最佳参数:{ ’ xgb classifier _ _ max _ depth ‘:5,’ xgb classifier _ _ min _ child _ weight ':1 }
在第一次迭代中,我们以两步递增参数值。因此,在第二次迭代中,让我们进一步缩小参数范围并进行检查。
在第二次迭代期间, max_depth 的最佳值是 5 。现在是 6 。所以在第三次迭代中,让我们再次确认 max_depth 的值。现在让我们将最小 _ 子 _ 重量参数固定为 1。
参数调整的第三次迭代的输出:
- 交叉验证分数:0。46860 . 68686868661
- 最佳参数:{ ’ xgb classifier _ _ max _ depth ‘:6,’ xgb classifier _ _ min _ child _ weight ':1 }
从第三次迭代中,我们可以确定最大深度的值为 6 。以同样的方式,我们可以选择其他参数并调整它们的优化值。
注:本博客旨在提供关于特征工程和超参数调整的快速介绍。这里的想法是理解过程,所以代码没有优化。使用这种方法来设置基线指标得分。提高我们每次迭代的模型验证分数。
在此 获取完整笔记本 。
你可能会觉得我的其他博客很有趣。一定要去看看。
参考资料:
[## XGBoost 中参数调整的完整指南(带 Python 代码)
如果在预测建模中事情没有按照你的方式发展,使用 XGboost。XGBoost 算法已经成为终极…
www.analyticsvidhya.com](https://www.analyticsvidhya.com/blog/2016/03/complete-guide-parameter-tuning-xgboost-with-codes-python/)
监督机器学习:模型验证,一步一步的方法
模型验证是在测试数据集上评估已训练模型的过程。这提供了训练模型的泛化能力。在这里,我提供了一个逐步的方法来在几分钟内完成模型验证的第一次迭代。
应用监督机器学习模型的基本方法是:
选择一类模型
选择模型超参数
使模型符合训练数据
使用模型预测新数据的标签
摘自杰克·范德普拉斯撰写的 Python 数据科学手册
Jake VanderPlas 用四个简单明了的步骤给出了模型验证的过程。在我们开始他的第一步之前,还需要一个完整的过程。比如从数据中获取我们需要的所有信息,以便对选择类模型做出良好的判断。还提供收尾工作,以确认之后的结果。我将深入讨论这些步骤,并进一步分解。
- 数据清理和争论。
- 将数据分为训练数据集和测试数据集。
- 定义模型优化的指标。
- 快速获得初始指标评估。
- 优化指标的特征工程。(第一遍跳过这个)。
- 数据预处理。
- 特征选择。
- 型号选择。
- 模型验证。
- 解读结果。
- 获得最佳模型,并对照测试数据集进行检查。
我将使用来自 UCI 机器学习库的数据集。数据集来自台湾新竹市的 输血服务中心 。这是一个分类问题。这背后的思想也延伸到回归问题。
数据清理和争论。
输血服务中心数据集是一个干净的数据集。对于大多数其他数据集来说,情况并非如此。因此,这是检查和清理数据的步骤,例如处理丢失的值…
将数据分为训练数据集和测试数据集。
有许多方法可以获得用于模型验证的训练和测试数据集,例如:
- 获取训练、验证和测试数据集的三向保持方法。
- 独立测试数据集的 k 重交叉验证。
- 独立测试数据集的留一交叉验证。
塞巴斯蒂安·拉什卡的 博客 对于确定这一点有很好的借鉴作用。
我将利用独立测试数据集进行五重交叉验证。所以把数据分成训练和测试数据集。
定义模型优化的指标。
分类和回归问题中使用的度量标准各不相同。分类问题使用准确性、精确度和召回率等指标…回归问题使用平均绝对误差、R2 分数等指标…
既然这是一个分类问题,我这里就用准确率评分。
快速获得初始指标评估。
这个步骤背后的主要思想是获得正在优化的度量的基线估计。该基线将作为模型验证的进一步步骤的参考。有几种方法可以得到分类问题的基线估计。我使用多数类进行预测。基线准确度分数约为 77% 。
优化指标的特征工程。
特征工程是使用数据的领域知识来创建使机器学习算法工作的特征的过程。特征工程是机器学习应用的基础,既困难又昂贵。
来自维基百科
这意味着识别独立特征和从属特征之间的关系。这是借助于图表,如对图或相关矩阵。然后,我们可以将识别的关系添加为多项式或交互特征。
特征工程步骤是连续迭代的入口点。这是一个关键步骤,与模型验证相比,它在预测中起着更大的作用。
作为快速解决方案,我们可以使用 sci-kit learn 中的 多项式特性添加一些多项式特性。
手头问题的领域知识将对特征工程有很大的用处。这本身就是一个更大的主题,需要投入大量的时间和资源。
数据预处理。
数据预处理将特征转换成更适合评估者的格式。一般来说,机器学习模型更喜欢数据集的标准化。在我们的例子中,我将使用鲁棒定标器。
详细信息请参考 sci-kit learn 的 预处理数据 部分。
特征选择。
数据集的特征选择或维度缩减有助于
- 要么提高模型的准确度
或者
- 来提高它们在高维数据集上的性能。
我会用 SelectKBest ,单变量特征选择法。用于分类和回归问题的评分函数会有所不同。
详细信息请参考 sci-kit learn 的 功能选择 章节。
型号选择。
由于我们正在处理分类问题,我将使用逻辑回归模型。对于回归问题,我们可以使用线性回归或岭模型。模型的选择取决于手头的问题。根据数据的复杂性,我们可以使用简单的线性模型或高级模型。
有关详细信息,请参考 sci-kit learn 的 广义线性模型 部分。
使用 sci-kit learn 的 管道 ,有一种优雅的方式可以将以上三个步骤结合起来。流水线在最终模型之前应用一系列转换。
模型验证。
超参数是模型本身不知道的参数。超参数作为参数传递给管道中步骤的构造函数。基于交叉验证分数,可以获取最佳的可能参数。
对于超参数调整**,GridSearchCV** 是选项之一。它对模型的指定参数值执行穷举搜索。这里,我们使用 param_grid 将超参数传递给管道中的步骤。 cv 设置为 5 ,因为我们要进行 5 重交叉验证。评分被设置为准确度,因为我们想要预测模型的准确度。
有关详细信息,请参考 sci-kit learn 的 调整估计器的超参数 部分。
解读结果。
GridSearchCV 返回一些重要信息,如:
- best_estimator_ ,给出最高分的评估者。利用这一点,我们可以获得关于所选特征的信息。
- **best_score_,**表示 best_estimator 的交叉验证分数。对于我们的问题集,我们在第一次迭代中得到了最好的分数 78% 。这看起来不多,但我们已经打破了我们的基线准确性得分。
- best_params_ ,给出保持数据最佳结果的参数设置。对于传递给模型的超参数,以下设置给出了最佳结果。
- 逻辑回归 __C’: 1.0
- ’ logistic regression _ _ class _ weight ':无
- selectkbest__k’: 4
这就结束了模型验证的第一次迭代。现在,我们可以返回并重复从特征工程步骤开始的过程。在每次迭代结束时,我们可以检查准确性分数的变化。重复该过程,直到达到期望的准确度分数或选择的度量。
获得最佳模型,并对照测试数据集进行检查。
选择最终模型后,使用测试数据集检查其性能。在这里,我们在测试数据集上获得了 75%的准确率分数。
注意这个博客是为了提供一个关于监督机器学习模型验证的快速介绍。这里的想法是不要在第一次迭代中获得最佳的度量分数。使用这种方法来设置基线指标得分。提高我们每次迭代的模型验证分数。
在此 获取完整笔记本 。
你可能会觉得我的其他博客很有趣。一定要去看看。
监督组学整合
生命科学的数理统计和机器学习
结合多种生物信息来源
在这篇来自我的专栏 生命科学的数理统计和机器学习 的文章中,我将扩展分子组学集成的主题,以便更好地对生物细胞进行建模。在之前的文章中,我介绍了这个主题,并解释了为什么我们需要在进行集成之前进行特性选择。这里我将解释如何使用**【PLS】****回归和判别分析执行监督的**组学整合。
慢性淋巴细胞白血病(CLL)数据集
随着大数据在这里成为现实,多分子组学的集成代表了计算生物学和生物医学中的当代挑战。我们将在此使用的多组学生物医学数据的一个例子是对慢性淋巴细胞白血病(CLL)的研究。这项研究将药物反应与体细胞突变信息、转录组图谱分析和 DNA 甲基化测定相结合。
From Dietrich et al., Journal of Clinical Investigation, 2017, image source
几十年来,执行整合的传统生物学方法一直是组学层的成对相关。尽管其可解释性和简单性,这种方法被认为在多个组学集的情况下提供了不一致的信息。为了克服不同数据集之间技术差异的问题,组学集成的一个更有前途的想法是用潜在变量来表示每个数据集,这些潜在变量不包含它们产生的技术记忆。
PLS-DA 与 DIABLO 的集成
当来自不同组学的最具信息性特征 以其第一个 PLS 成分之间相关性的约束被选择时,潜在变量概念的最直接实施是基于偏最小二乘(PLS)回归和判别分析的多组学的多元整合。这种方法由于其简单性和在 R 包 混合组学 中的高效实现而变得非常流行。
Rohart et al., Plos Computational Biology, 2017, image source
混合组学包括几个优雅的统计算法,其中 MINT 代表跨样本整合,类似于 批量效应校正 , DIABLO 代表跨组学整合,这是真正的多组学数据整合,我们将在此用于 CLL 数据集。
CLL 经济集团与暗黑破坏神的整合
我们将从阅读 CLL 的数据开始,并用简单的中位数估算法估算缺失值。我们将使用性别作为感兴趣的特征,因此 PLS-DA 算法将跨多个组学同时执行特征的提取,这些组学在低维潜在 PLS 空间中最大化雄性和雌性之间的分离。由于我们使用性别变量指导特征提取,这是一种监督组学整合方法**。**
接下来,我们将 n=200 个 CLL 样本分成训练(n=140)和测试(n=60)数据集,用于稍后测试模型的预测准确性。由于突变代表二进制数据,由于用 0 和 1 编码,总会有一个缺少变化。因此,我们将通过排除个体间方差接近于零的位点来预过滤突变矩阵。接下来,由于基因表达和甲基化数据集是高维的,我们使用 LASSO 以我在上一篇文章中描述的方式执行特征预选。查看我的 github 笔记本中的完整代码,了解这些步骤的详细信息。接下来,我们执行交叉验证来选择预测组件的最佳数量:
Selecting optimal number of PLS components through M-fold cross-validation
分类错误率似乎在 ncomp=2 时达到其平稳状态,因此我们将使用该数量作为预测组件的最佳数量,以保留在进一步的下游分析中。上面的设计矩阵定义了组学之间的预期协方差。由于缺乏先验知识,我们在组学之间选择一个强相关 1。此外,我们将再次使用交叉验证,以便在运行稀疏 PLS-DA 时,确定每个 OMIC 的最佳特征数,用于提取LASSO最具预测性的变量。最后,在我们找到每个 OMIC 中预测成分和变量的最佳数量后,我们运行稀疏 PLS-DA 进行组学整合。
Low-dimensional latent PLS space representation of each individual OMIC
Consensus plot across OMICs as a result of OMICs integration. Males and Females are linearly separable
上面的四个图显示了进行综合特征提取后单个组学的低维 PLS 表示。相比之下,下面所谓的箭头图可以被认为是整个组学的共识图。由于使用 PLS-DA 跨组学特征提取的同时和**,它显示了非常清晰的男性和女性之间的分离。**
整合结果的生物学解释
混合组学为数据的生物学解释提供了许多令人印象深刻的可视化。在这里,我们展示了相关性 圆形图,其中叠加了来自每个组学的最高负荷的变量。围绕圆的极点的变量的聚类意味着来自组学数据集的变量之间的强相关性。相关圆图的相反极点上的变量暗示强反相关**。**
Correlation Circle Plot (left) and Circus Plot (right) demonstrate feature connection across OMICs
另一种呈现组学中最具信息特征之间相关性的方法是所谓的 Circos 图。同样,该图的变量同时选自所有组学,即它们不同于从每个单独的 OMIC 单独获得的变量。关联网络是另一种以成对方式展示组学数据集中最具信息性特征之间关联的方式。
Correlation Network demonstrate par-wise correlations between features across OMICs
暗黑破坏神综合模型预测
现在是预测的时候了。一旦我们训练了 PLS-DA 模型,我们就可以使用它并利用 60 个测试样本来预测它们的性别并评估预测的准确性:
通常,在 CLL 数据集上,从 DIABLO 整合模型预测性别的成功率(准确性)为60–70%,这并不令人惊讶,因为这是一种线性整合方法。我们可以通过人工神经网络用非线性整合模型做得更好,我将在接下来的帖子中解释。
摘要
在这篇文章中,我们了解到 PLS-DA 是一种优雅的多变量组学整合方法,它将单个数据集投影到一个公共的潜在低维空间上,在那里数据集释放了它们初始技术差异的内存。组学可以在这个共同的潜在空间中合并,并且性状类别(也称为疾病-健康)变得线性 可分离。
请在下面的评论中告诉我,生命科学中的哪些分析对你来说似乎是 T2 特别神秘的,我会在这个专栏中尝试回答这些问题。在我的 github 上查看完整的笔记本。在 Medium 关注我,在 Twitter @NikolayOskolkov 关注我,在 Linkedin 关注我。下次我们将讨论无监督组学整合方法,敬请关注。
支持向量机解释
理论、实现和可视化
支持向量机(SVM)可能是数据科学家使用的最流行的 ML 算法之一。SVM 是强大的,易于解释,并在许多情况下推广良好。在本文中,我将解释 SVM 背后的基本原理,并展示 Python 中的实现。为了简单起见,本文中我将重点讨论二进制分类问题。然而,SVM 支持多分类。
1.理论
1.1 背后的总体思路
SVM 寻求最佳决策边界,该边界将具有最高概括能力的两个类分开(为什么关注概括?我会在后面的内核部分解释)。人们问的第一个问题是 SVM 如何定义最优性。
Which decision boundary should we pick? from MIT
与通过总体概率定义最优性的逻辑回归不同,SVM 希望数据点和决策边界之间的最小距离尽可能大。换句话说,如果你把决策边界想象成街道的中心线,SVM 更喜欢 8 线高速公路,而不是乡村公路。街道的宽度被称为边缘。
from Vapnik, Support-Vector Network
1.2 数学
定义边距
好吧,这个想法很直观。让我们找出边距的表达式。在我们开始之前,请记住本文中使用的符号:
如果我们知道决策边界的权重和截距,则该边界可以由以下等式表示:
The equation for the broken line in the last figure
从数据点到边界的距离为:
from Lecture 14-Support Vector Machine, Caltech
边距是从最近点到边界的距离:
最终目标
现在我们知道了如何计算利润,让我们尝试将需要优化的问题形式化:
Final Objective
我不得不承认这是一个奇怪的函数。只要记住这一点:这就像线性回归的 RMSE,逻辑回归的交叉熵,一个需要优化的函数。
1.3 Python 实现
现在我们了解了 svm 是如何工作的,让我们试试 SVM。Scikit-Learn 提供的 SVC 功能
等等,这些参数是什么?目标中没有 C 或“内核”。你确定这是正确的功能吗?不幸的是,是的,我们只需要稍微深入一点 SVM 背后的数学。
1.4 又是理论…
现在我们需要谈谈如何优化目标函数。回想一下,该函数是:
我们究竟如何最大化这个等式?我们不能求导就完事了,因为最终的 W 和 b 可能不满足约束。幸运的是,一个高中数学班的男生来拯救我们——拉格朗日。
消除约束
拉格朗日乘子的方法是一种策略,用于寻找服从等式约束(即服从一个或多个方程必须由所选变量值精确满足的条件)的函数的局部最大值和最小值。【1】基本思想是将一个有约束的问题转换成一种形式,使得无约束问题的导数测试仍然可以应用— 维基百科
from MIT
在拉格朗日乘数的帮助下,我们可以通过求解这个函数来找到上述问题的解:
Unconstrained objective function
算出 W 和 b
现在,W,b 和α都是未知的。天哪,我们该怎么办?幸运的是,Vapnik Vladimir 为我们指出了这一点:
首先相对于 W 和 b 最小化 L(假设我们知道α)
W and b are easy to find as long as we know alpha
用我们刚找到的 W 和 b 最大化 L w.r.t。
等等,为什么这突然变成最大化了?这被称为拉格朗日对偶。
拉格朗日对偶问题:我们可以根据之前获得的 w 和 b 的关系,在α(对偶变量)上最大化,而不是在 w,b 上最小化,受到α的约束—SVM 白痴指南
上述函数有一个很好的形式,可以用二次规划软件求解。只要把这个函数和约束传递给任何商业 QP 软件,它就会返回一个阿尔法列表。现在α解出来了,就可以计算 W 和 b 了。搞定了。
1.5 什么是参数‘C’
在上面的定义中,我们假设所有点都必须在页边空白的边界上或超出它(一个所谓的硬 SVM)。实际上,通常不是这样。我们需要定义一个软 SVM,允许轻微违反规则的行为受到一些处罚:
violation of constraints, from Caltech
如您所见,C 决定了 SVM 对违规的严重程度。如果 C 是 0,那么 SVM 根本不关心违例,因为惩罚项已经没有了。如果 C 非常巨大,微小的违反将导致目标函数的巨大增量。这个函数的解可以用上面解释的相同方法导出。
1.6 什么是参数‘内核’
内核技巧是一种强大的转换技术,它将数据从原始空间投影到转换后的空间,希望使数据更具线性可分性。
Radial kernel, from An Idiot’s Guide to SVM
更严格地说,我们需要一个转换函数:
回想一下我们之前推导的目标函数:
在新的空间中,我们必须计算这个函数:
在内核转换的帮助下,我们将能够将数据映射到更高维度,并有更大的机会用超平面将它们分开。
Decision boundary obtained with kernel methods, 3 classes, from Scikit-Learn
等等,为什么我们会得到非线性的边界?SVM 应该只找到线性边界。是的,你说对了一部分!你看到的决策边界是高维空间的投影。在我们在转换后的空间中完成分类后,我们可以将超平面映射回来,边界可能会变成非线性的!
transformation of space, from Sebastian Raschka
当前转换的小问题
变换函数将数据点投影到不同的空间。当投影空间变得更加复杂时,这个过程非常耗时。在某些情况下,我们甚至不知道变换方程。应该没有办法将一个数据点映射到一个无限维的空间。还是有?
如果我们再看一下变换后的目标函数,我们可以对它进行微小的修改:
你可能会说:好吧,另一个定义,那又怎样?但是看,这是天才的部分。只要我们知道 K(xi,xj)是什么,我们就不需要变换函数。这意味着我们可以选择想要的空间,而不用担心中间的细节。有了这个,我可以定义在没有变换函数φ的情况下,变换后的空间的点积是什么样子。例如,一个无限的。
the See the proof here
您可能想知道一些著名的、经过充分测试的内核:
2.又是 Python 实现
这一次,我们理解了这些参数的含义。让我们看看每个参数的效果。
C 的影响
控制对错误分类点的关注。较大的 C 将迫使模型牺牲余量以支持正确的预测(可能导致过度拟合)
内核的影响
Effects of different kernel
优势和劣势
from Scikit-Learn.org
摘要
SVM 寻求决策边界的余量和错误分类点的数量之间的平衡。核技巧使 SVM 能够在不增加目标函数局部极小值的情况下引入强大的非线性。现在你明白了 SVM 是如何工作的,是时候在实际项目中尝试一下了!
支持向量机——公式和推导
Photo by Andy Holmes on Unsplash
预测机器学习中的定性反应称为分类。
SVM 或支持向量机是最大限度地提高利润率的分类器。在下面的例子中,分类器的目标是找到一条线或(n-1)维超平面,它将 n 维空间中的两个类分开。
在下面给出的例子中,我们看到任何学习算法都会给出所提到的任何给定的行,但是什么可能是最好的行呢?
2 dimensional representation of binary classes
直观上,绿线看起来是最佳解决方案,因为它可能会对未来的测试数据集做出更好的预测。我们通过引入一个称为边缘的参数,即在没有任何训练样本的情况下,决策边界/分类器周围的带宽,来形式化分类器的优度的概念。
因此,目标是找到具有最大余量的决策边界。我们可以将边缘视为训练区域周围的区域,决策边界不能绕过该区域。随着半径的增加,可行域减小,它收敛到一条直线。
注意:只有少数带有气泡的训练样本触及了决策边界。这些样本本质上被称为支持向量。
打破维度诅咒
1970 年,数学家 Vapnik 和 Chervonenkis 给出了 VC 维的概念,他们将未来测试误差(R(α))估计为训练误差和 VC 维的某个函数(单调递增函数)。
VC 维数 h 被写成相对裕度平方的倒数和数据维数的最小值。因此,如果我们可以最大化相对裕度,我们将最小化它的平方反比,如果它低于数据的维度,h 将变得独立于维度。
注意:相对裕度就是裕度除以包含所有训练点的圆的直径。
SVM 的提法
我们使用方法 2 并将问题公式化为:
对拉格朗日形式中的常数进行积分,我们得到:
拉格朗日乘数法规定,如前所述,对于 w 和 b,J 最小化,但是对于 α,J 必须最大化**。**J 代表的点称为鞍点。
函数 J 目前以它的原始形式表示,我们可以把它转换成它的对偶形式来求解。
同样,从拉格朗日乘子的 KKT 条件中,我们可以说 J 函数中对应于拉格朗日乘子的所有项在最优时应该趋向于 0。
这意味着非零拉格朗日系数对应于支持向量数据点。利用上述等式,我们可以将 J 写成:
Q(α)代表 对偶形式 J 它只依赖于α,其余都是已知的标量。我们可以用任何 QP 优化来求解 Q(α),这超出了本文的范围。在得到α之后,我们得到 w,从这点出发,任何一个支持向量都可以根据 KKT 条件得到 b。
非线性可分离数据
我们研究了数据是线性可分的情况。现在,我们来看看数据可能不线性分离的情况,原因是
噪声数据
对于有噪声的数据,我们在估计/优化中引入一个训练误差参数。我们引入一个松弛变量,并增加额外的条件如下
用拉格朗日系数重复同样的过程,我们得到
唯一的区别是现在拉格朗日系数有了限制。参数 C 控制训练误差和 VC 维数之间的相对权重。
非线性边界
任何具有非线性边界的数据集,如果投影到更高维度,理论上都是线性可分的。
因此 Q(α)可以写成:
我们可以将 w 和其他测试相位方程写成:
内核技巧
我们可以看到,在训练和测试中,映射都以点积的形式出现。由于我们不知道映射,我们可以找到一个函数 K(x,y) 它等价于映射的点积;我们可以避免显式映射到更高维度。
让我们举一个二次核的例子来更好地理解。
我们看到,与映射然后相乘相比,核函数的计算复杂度更低。
这个可以扩展到 n 维内核。因此,n 维映射/核可以表示为
注意:添加两个有效内核也给了我们一个内核。这很容易证明。
因此,为了映射到极高的维度,我们可以将内核计算为:
无限维度
理论上,如果映射到无限维超平面,数据集将是线性可分的。因此,如果我们能找到一个能给出无限超平面映射乘积的核,我们的工作就完成了。
这里出现了 Mercer 定理,它陈述了当且仅当 K(X,Y)是对称的、连续的和正半定的(那么 Mercer 的条件),它可以表示为
意味着高维映射的线性组合的存在是有保证的。因此,现在我们只需检查函数是否满足 Mercer 条件,就可以得到无限维的映射。
我以此结束我关于 SVM 的博客,这是我用过的最好的分类器之一,观看这个空间的更多内容。
支持向量机:用 Python 实现数字分类:包括我手写的数字
了解 SVM 系列:第三部分
在前面对 SVM 算法的详细讨论之后,我将用一个 SVM 对手写数字进行分类的应用程序来结束这个系列。这里我们将使用 MNIST 数据库来存储手写数字,并使用 SVM 对数字从 0 到 9 进行分类。原始数据集处理起来很复杂,所以我使用 Joseph Redmon 处理过的数据集。
我已经遵循了 Kaggle 竞赛程序,你可以从 kaggle 本身下载数据集。数据集基于手写数字的灰度图像,每幅图像高 28 像素,宽 28 像素。每个像素都有一个与之关联的数字,其中 0 表示暗像素,255 表示白像素。训练和测试数据集都有 785 列,其中“标签”列代表手写数字,其余 784 列代表(28,28)像素值。训练和测试数据集分别包含 60,000 和 10,000 个样本。我将使用我在上一篇文章中介绍的几个技术,比如GridSearchCV
和Pipeline
,以及一些新概念,比如用numpy
数组表示灰度图像。
我使用了来自训练和测试数据集的 12000 个样本和 5000 个样本,只是为了减少计算时间,建议使用完整的数据集来获得更好的分数,并避免选择偏差。
import math, time
import matplotlib.pyplot as plt
import numpy as np
import pandas as pdstart = time.time() MNIST_train_small_df = pd.read_csv('mnist_train_small.csv', sep=',', index_col=0)
#print MNIST_train_small_df.head(3)
print MNIST_train_small_df.shape>> (12000, 785)
我们可以通过打印出 **value_counts()**
和/或标签分布图来检查训练数据集是否偏向某些数字。
sns.countplot(MNIST_train_small_df['label'])
plt.show()# looks kinda okay# or we can just printprint MNIST_train_small_df['label'].value_counts()>>
1 1351
7 1279
3 1228
6 1208
0 1206
9 1193
4 1184
2 1176
8 1127
5 1048
Figure 1: Bar plots of sample distribution in training data set
我们看到选择稍微偏向数字 1,并且标签 1 的样本计数比样本 5 高大约 30%,即使我们使用完整的训练数据集(60,000 个样本),这个问题仍然存在。继续,是时候分开标签和像素列了,标签是数据帧的第一列。
X_tr = MNIST_train_small_df.iloc[:,1:] # iloc ensures X_tr will be a dataframe
y_tr = MNIST_train_small_df.iloc[:, 0]
然后,我将训练数据和测试数据分开,20%的样本用于测试数据。我使用了**stratify=y**
来保存标签的分布(数字)—
X_train, X_test, y_train, y_test = train_test_split(X_tr,y_tr,test_size=0.2, random_state=30, stratify=y_tr)
由于像素值在 0-255 的范围内变化,是时候使用一些标准化了,我已经使用了[StandardScaler](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html)
,它通过移除平均值并将其缩放到单位方差来标准化特征。 同样在尝试了所有的核之后,多项式核取得了最好的成绩和最少的时间。 要了解更多关于内核的技巧,你可以查看以前的帖子。
这里我们将设置Pipeline
对象,用StandardScaler
和SVC
分别作为转换器和估计器。
steps = [('scaler', StandardScaler()), ('SVM', SVC(kernel='poly'))]
pipeline = Pipeline(steps) # define Pipeline object
为了决定C, gamma
的值,我们将使用具有 5 重交叉验证的GridSearchCV
方法。如果你想了解更多关于管道和网格搜索的知识,请查看我之前的帖子。
parameters = {'SVM__C':[0.001, 0.1, 100, 10e5], 'SVM__gamma':[10,1,0.1,0.01]}grid = GridSearchCV(pipeline, param_grid=parameters, cv=5)
现在,我们准备测试模型并找到最合适的参数。
grid.fit(X_train, y_train)print "score = %3.2f" %(grid.score(X_test, y_test))print "best parameters from train data: ", grid.best_params_>>
score = 0.96best parameters from train data: {'SVM__C': 0.001, 'SVM__gamma': 10}>>y_pred = grid.predict(X_test)
使用 12000 个样本获得了 96%的准确率,我预计使用完整的 60000 个样本后,这个分数会有所提高。GridSearchCV
部分比较耗时,如果你愿意,可以直接使用 C 和 gamma 参数。
我们可以检查一些预测
print y_pred[100:105]
print y_test[100:105]>>
[4 2 9 6 0]
1765 4
220 2
932 9
6201 6
11636 0
我们现在可以使用 python matplotlib pyplot imshow
来绘制数字。我们使用预测列表和来自测试列表的像素值进行比较。
for i in (np.random.randint(0,270,6)):
two_d = (np.reshape(X_test.values[i], (28, 28)) * 255).astype(np.uint8)
plt.title('predicted label: {0}'. format(y_pred[i]))
plt.imshow(two_d, interpolation='nearest', cmap='gray')
plt.show()
让我简单解释一下代码的第二行。由于像素值在数据集中排列成 784 列的一行,我们首先使用numpy
‘reshape’模块将其排列成 28 X 28 的数组,然后乘以 255,因为像素值最初是标准化的。请注意X_test.values
返回数据帧的‘numpy’表示。
Figure 2: Examples of digit classification on training data-set.
正如你在上面的图片中看到的,除了一个,所有的图片都被正确分类了(我认为图片(1,1)是数字 7 而不是 4)。要知道有多少数字被错误分类,我们可以打印出*混淆矩阵。*根据 scikit-learn 中给出的定义
混淆矩阵 C 使得 c(i,j)等于已知在组 I 中但预测在组 j 中的观察值的数量
print "confusion matrix: \n ", confusion_matrix(y_test, y_pred)>>[[236 0 0 1 1 2 1 0 0 0]
[ 0 264 1 1 0 0 1 1 2 0]
[ 0 1 229 1 2 0 0 0 1 1]
[ 0 0 2 232 0 3 0 2 5 2]
[ 0 1 0 0 229 1 1 0 1 4]
[ 0 0 1 4 1 201 0 0 1 2]
[ 3 1 2 0 3 3 229 0 0 0]
[ 0 1 3 0 6 0 0 241 0 5]
[ 0 0 3 6 1 2 0 0 213 0]
[ 3 1 1 0 1 0 0 1 2 230]]
因此,如果我们考虑第一行,我们可以理解,在 241 个零中,236 个被正确分类,等等…
现在,我们将对测试数据集(mnist_test.csv)重复该过程,但我没有使用GridSearchCV
来寻找 SVM (C,gamma)的最佳参数,而是使用了来自训练数据集的相同参数。
如前所述,我使用了 5000 个样本而不是 10000 个测试样本来减少时间消耗。
MNIST_df = pd.read_csv('mnist_test.csv')
MNIST_test_small = MNIST_df.iloc[0:5000]
MNIST_test_small.to_csv('mnist_test_small.csv')
MNIST_test_small_df = pd.read_csv('mnist_test_small.csv', sep=',', index_col=0)
下一步是选择特征和标签—
X_small_test = MNIST_test_small_df.iloc[:,1:]
Y_small_test = MNIST_test_small_df.iloc[:,0]
将特征和标签分为训练集和测试集
X_test_train, X_test_test, y_test_train, y_test_test = train_test_split(X_small_test,Y_small_test,test_size=0.2, random_state=30, stratify=Y_small_test)
设置Pipeline
对象
steps1 = [('scaler', StandardScaler()), ('SVM', SVC(kernel='poly'))]
pipeline1 = Pipeline(steps1) # define
设置GridSearchCV
对象,但这次我们使用通过 mnist_train.csv 文件估算的参数。
parameters1 = {'SVM__C':[grid.best_params_['SVM__C']], 'SVM__gamma':[grid.best_params_['SVM__gamma']]} grid1 = GridSearchCV(pipeline1, param_grid=parameters1, cv=5)
grid1.fit(X_test_train, y_test_train)print "score on the test data set= %3.2f" %(grid1.score(X_test_test, y_test_test))print "best parameters from train data: ", grid1.best_params_ # same as previous with training data set>>
score on the test data set= 0.93best parameters from train data: {'SVM__C': 0.001, 'SVM__gamma': 10}>>y_test_pred = grid1.predict(X_test_test)
测试数据集上的得分为 93%,而训练数据集上的得分为 96%。下面是测试数据集中的一些随机图像,与预测水平进行了比较。
Figure 3: Examples of digit classification on test data-set.
我们可以检查测试数据集的混淆矩阵,以全面了解错误分类。
print "confusion matrix: \n ", confusion_matrix(y_test_test, y_test_pred)>>[[ 91 0 0 0 0 0 0 0 1 0]
[ 0 111 2 0 1 0 0 0 0 0]
[ 0 0 98 1 0 0 1 2 4 0]
[ 0 0 1 91 0 2 0 0 4 2]
[ 0 0 0 1 95 0 0 1 0 3]
[ 0 0 1 3 1 77 4 0 3 2]
[ 1 1 1 0 2 0 85 0 2 0]
[ 0 0 0 1 0 0 0 100 0 2]
[ 0 0 1 1 0 2 0 1 93 0]
[ 0 0 0 0 4 1 0 3 3 93]]
请注意,在 92 个标签中,只有 1 个数字 0 分类错误。现在我们将继续讨论对我自己的手写图像进行分类的可能性。
对自己的手写图像进行分类:
下面是我准备数据集,然后对从 0 到 9 的数字进行分类的步骤
- 我已经使用 mypaint 首先编写(绘制)图像,然后使用 Imagemagick 来调整图像的大小,使其高度和宽度为 28X28 像素。
convert -resize 28X28! sample_image0.png sample_image0_r.png
Figure 4: Resized (28X28) My Own Hand-written Images
2.将图像转换为 numpy 数组并检查像素值是如何分布的。你可以在我的 github 上找到代码,下面是两个例子
Figure 5: Representing images with pixels using Image and Numpy
3.*将数组(28X28)展平为(784,)*转换为列表。然后写在一个 csv 文件,包括标签,即像素代表的数字。所以现在总列数是 785,与我以前使用的训练和测试 csv 文件一致。这些代码可在github.com获得。
4.把新的数据帧和测试数据帧连接起来,这样新文件就多了 10 行。
5.最后用这个新文件运行相同的分类过程,只有一个不同——训练和测试数据不是使用train_test_split
方法准备的,因为我的主要目的是看看算法如何对新数据起作用。所以我选择了前 3500 行用于训练,剩下的行(包括新数据)作为测试样本。
X_hand_train = new_file_df_hand.iloc[0:3500, 1:]
X_hand_test = new_file_df_hand.iloc[3500:5011, 1:]
y_hand_test = new_file_df_hand.iloc[3500:5011, 0]
y_hand_train = new_file_df_hand.iloc[0:3500, 0]
6.为了绘制手写图像以及它们与预测输出的匹配程度,我像以前一样使用了以下 for 循环——因为最后 1500 个样本(包括我自己的手写图像)被作为测试数据,所以循环在最后几行上进行。
for ik in range(1496, 1511, 1):
three_d = (np.reshape(X_hand_test.values[ik], (28, 28)) * 255).astype(np.uint8)
plt.title('predicted label: {0}'. format(y_hand_pred[ik]))
plt.imshow(three_d, interpolation='nearest', cmap='gray')
plt.show()
7.包括我自己手写数据在内的测试数据集上的得分是 93%。
8.让我们来看看分类器对我的笔迹从 0 到 9 的分类有多好
Figure 5: Predicted labels on my hand-written digits. 70% correct !!!
因此,10 个手写数字中有 7 个被正确分类,这很好,因为如果你与 MNIST 数据库的图像进行比较,我自己的图像是不同的,我认为一个原因是笔刷的选择。正如我意识到的,我使用的笔刷产生了更厚的图像。特别是在与 MNIST 图像比较时,我发现我的图像中边缘之间的像素比 MNIST 图像更亮(更高的像素值— > 255),这可能是 30%错误分类的原因。
我想你已经知道如何使用支持向量机来处理更现实的问题了。作为一个迷你项目,你可以使用类似的算法来分类 MNIST 时尚数据。
希望你喜欢这篇文章,如果你想了解更多关于 SVM 的基础知识,请查看我以前在这个系列中的文章。
支持向量机 Python 示例
Photo by Green Chameleon on Unsplash
支持向量机(SVM)是一种有监督的机器学习算法,能够执行分类、回归甚至离群点检测。线性 SVM 分类器的工作原理是在两个类之间画一条直线。落在线一侧的所有数据点将被标记为一类,落在线另一侧的所有数据点将被标记为第二类。听起来很简单,但是有无限多的行可供选择。我们如何知道哪一行在分类数据方面做得最好?这就是 LSVM 算法发挥作用的地方。LSVM 算法将选择一条线,该线不仅将两个类分开,而且尽可能远离最近的样本。事实上,“支持向量机”中的“支持向量”指的是从原点到指定决策边界的点所绘制的两个位置向量。
算法
假设,我们有一个向量 w ,它总是垂直于超平面(垂直于 2 维中的直线)。通过将样本的位置向量投影到向量 w 上,我们可以确定样本距离我们的决策边界有多远。快速复习一下,两个向量的点积与第一个向量到第二个向量的投影成正比。
https://commons.wikimedia.org/wiki/File:Scalar_Projection.png
如果它是一个正样本,我们将坚持认为前面的决策函数(给定样本的位置向量和 w 的点积加上某个常数)返回一个大于或等于 1 的值。
类似地,如果它是一个负样本,我们将坚持继续决策函数返回一个小于或等于-1 的值。
换句话说,我们不会考虑位于决策边界和支持向量之间的任何样本。
正如在麻省理工学院讲座中所述,为了方便起见,我们引入了一个附加变量。变量 y 对于所有正样本等于正 1,对于所有负样本等于负 1。
在乘以 y 之后,正样本和负样本的等式彼此相等。
也就是说,我们可以将约束简化为一个等式。
接下来,我们需要解决我们着手最大化利润的过程。为了得到边缘宽度的等式,我们从下面的一个中减去第一个支持向量,然后将结果乘以单位向量 w ,其中总是垂直于决策边界。
使用上面的约束和一点代数,我们得到下面的。
因此,为了选择最佳决策边界,我们必须最大化我们刚刚计算的方程。在继续之前,我们还应用了一些技巧(参考麻省理工学院讲座)。
现在,在大多数机器学习算法中,我们会使用类似梯度下降的东西来最小化所述函数,然而,对于支持向量机,我们使用拉格朗日函数。拉格朗日超出了本文的范围,但是如果你需要一个快速速成班,我推荐你去看看 汗学院 。本质上,使用拉格朗日,我们可以像在高中水平的微积分中一样求解全局最小值(即,取函数的导数并使其等于零)。拉格朗日告诉我们,通过对所有约束求和来减去成本函数,其中每个约束将乘以某个常数α(拉格朗日通常记为λ)。
然后,我们执行更多的代数运算,将上一步中找到的方程插回到原始方程中。
在我们进一步讨论之前,我们需要用矩阵来表示这个方程,而不是求和。原因是,来自 CVXOPT 库的qp
函数,我们将使用它来求解拉格朗日函数,接受非常具体的参数。因此,我们需要从:
其中:
并且:
收件人:
我们可以使用以下标识来实现这一点:
在应用它们时,我们得到:
注:X 是 X 和 y 的乘积(不要和 X 混淆)
然后,我们将变量映射到 CVXOPT 库所期望的变量。
Python 代码
现在,我们准备写一些代码。我们将从导入必要的库开始。
import numpy as np
import cvxopt
from sklearn.datasets.samples_generator import make_blobs
from sklearn.model_selection import train_test_split
from matplotlib import pyplot as plt
from sklearn.svm import LinearSVC
from sklearn.metrics import confusion_matrix
然后,我们定义我们的 SVM 类。正如我们之前提到的,我们可以使用拉格朗日函数直接求解 w 和 b ,而不是像线性回归那样使用梯度下降来寻找最佳拟合线。
class SVM:def fit(self, X, y):
n_samples, n_features = X.shape# P = X^T X
K = np.zeros((n_samples, n_samples))
for i in range(n_samples):
for j in range(n_samples):
K[i,j] = np.dot(X[i], X[j])P = cvxopt.matrix(np.outer(y, y) * K)# q = -1 (1xN)
q = cvxopt.matrix(np.ones(n_samples) * -1)# A = y^T
A = cvxopt.matrix(y, (1, n_samples))# b = 0
b = cvxopt.matrix(0.0)# -1 (NxN)
G = cvxopt.matrix(np.diag(np.ones(n_samples) * -1))# 0 (1xN)
h = cvxopt.matrix(np.zeros(n_samples))solution = cvxopt.solvers.qp(P, q, G, h, A, b)# Lagrange multipliers
a = np.ravel(solution['x'])# Lagrange have non zero lagrange multipliers
sv = a > 1e-5
ind = np.arange(len(a))[sv]
self.a = a[sv]
self.sv = X[sv]
self.sv_y = y[sv]# Intercept
self.b = 0
for n in range(len(self.a)):
self.b += self.sv_y[n]
self.b -= np.sum(self.a * self.sv_y * K[ind[n], sv])
self.b /= len(self.a)# Weights
self.w = np.zeros(n_features)
for n in range(len(self.a)):
self.w += self.a[n] * self.sv_y[n] * self.sv[n]
def project(self, X):
return np.dot(X, self.w) + self.b
def predict(self, X):
return np.sign(self.project(X))
为了简单起见,我们将使用scikit-learn
库来生成线性可分数据。我们将阴性样品标记为-1
而不是0
。cvxopt
希望数据采用特定的格式,这就是我们采取中间步骤的原因。
X, y = make_blobs(n_samples=250, centers=2,
random_state=0, cluster_std=0.60)y[y == 0] = -1tmp = np.ones(len(X))y = tmp * y
让我们通过绘制图表来感受一下这些数据。
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='winter')
我们将数据分成训练集和测试集。
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
然后,我们创建并训练我们的支持向量机类的一个实例。
svm = SVM()svm.fit(X_train, y_train)
接下来,我们绘制决策边界和支持向量。
def f(x, w, b, c=0):
return (-w[0] * x - b + c) / w[1]plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='winter')# w.x + b = 0
a0 = -4; a1 = f(a0, svm.w, svm.b)
b0 = 4; b1 = f(b0, svm.w, svm.b)
plt.plot([a0,b0], [a1,b1], 'k')# w.x + b = 1
a0 = -4; a1 = f(a0, svm.w, svm.b, 1)
b0 = 4; b1 = f(b0, svm.w, svm.b, 1)
plt.plot([a0,b0], [a1,b1], 'k--')# w.x + b = -1
a0 = -4; a1 = f(a0, svm.w, svm.b, -1)
b0 = 4; b1 = f(b0, svm.w, svm.b, -1)
plt.plot([a0,b0], [a1,b1], 'k--')
我们使用我们的模型来预测测试集中样本的类别。假设我们使用我们的模型来分类数据,我们使用混淆矩阵来评估其准确性。
y_pred = svm.predict(X_test)confusion_matrix(y_test, y_pred)
让我们使用支持向量分类器的scikit-learn
实现来尝试同样的事情。
svc = LinearSVC()svc.fit(X_train, y_train)
在训练我们的模型之后,我们绘制决策边界和支持向量。
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='winter');
ax = plt.gca()
xlim = ax.get_xlim()
w = svc.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(xlim[0], xlim[1])yy = a * xx - svc.intercept_[0] / w[1]
plt.plot(xx, yy)yy = a * xx - (svc.intercept_[0] - 1) / w[1]
plt.plot(xx, yy, 'k--')yy = a * xx - (svc.intercept_[0] + 1) / w[1]
plt.plot(xx, yy, 'k--')
同样,我们根据样本落在线的哪一侧来预测哪个样本属于哪个类别。
y_pred = svc.predict(X_test)confusion_matrix(y_test, y_pred)
正如我们所看到的,分类器正确地对每个样本进行了分类。
结论
我们看到了如何使用拉格朗日函数来确定最佳的数据分割线。在现实世界中,大多数问题都不是线性可分的。因此,我们利用一种叫做内核技巧的东西,用直线以外的东西来分离数据。请继续关注我们即将发表的关于这个主题的文章。
支持向量机——简单解释
支持向量机基本概念的简化说明
Photo by Malte Schmidt on Unsplash
我总是在逃避我的 ML 书籍中的支持向量机一章。它只是令人生畏,你知道,名称,支持,向量,机器。
但是,一旦我开始将支持向量机视为“道路机器”,它就会变得不那么可怕,它可以分离左侧、右侧的汽车、建筑物、行人,并尽可能形成最宽的车道。那些离街道很近的汽车和建筑是支持向量。
感觉好多了。让我们开始了解这个“路机是如何工作的。
本博客包括三个部分:
- 什么是支持向量机
- 在线性可分的情况下,它是如何工作的
- 在线性不可分的情况下,它是如何工作的
什么是支持向量机(分类器)
回到 ML 世界,那些汽车,建筑,行人现在都变成了点。红点代表街道左侧的物体;绿点代表右边的。街道变成了虚线和实线。
S 支持向量机(“路机”)负责寻找决策边界,以区分不同类别并最大化裕量。
边距是线条和最靠近线条的点之间的(垂直)距离。
线性可分情形下的 SVM
显然,在上面的例子中,存在无限的线来分隔红色和绿色的点。SVM 需要找到一条最优线,约束条件是要正确地分类这两类中的任何一类:
- 遵循约束:只查看单独的 超平面(例如,单独的线),正确分类的超平面
- 进行优化:选择最大化余量的一个
我将举例说明分离超平面和边界的概念,但在这篇文章中不会解释如何用约束条件来解决优化问题。
那么什么是超平面?
H 超平面是 n 维空间的(n 减 1)维子空间。对于一个 2 维空间,它的超平面将是 1 维的,这只是一条线。对于三维空间,它的超平面将是二维的,这是一个切割立方体的平面。好吧,你明白了。
Any Hyperplane can be written mathematically as above
For a 2-dimensional space, the Hyperplane, which is the line.
The dots above this line, are those x1, x2 satisfy the formula above
The dots below this line, similar logic.
什么是分离超平面?
假设标签 y 是 1(代表绿色)或-1(代表红色),下面的三条线都是分离超平面。因为它们都有相同的属性——在这条线上,是绿色的;线下面是红色的。
该属性可以用数学公式再次写成如下形式:
如果我们进一步把这两个归纳成一个,它就变成了:
S 分离超平面约束用数学方法写在上面。在完美的情况下——线性可分的情况,这个约束可以由 SVM 来满足。但是在不可分的情况下,我们需要放松它。
那么什么是保证金呢?
- 假设我们有一个超平面——X 线
- 计算所有这 40 个点到 X 线的垂直距离,将会有 40 个不同的距离
- 40 分中,最小的距离,就是我们的差距!
虚线两侧到实线之间的距离就是边距。我们可以把这条最佳线想象成红点和绿点之间最大延伸的中线。
综上所述,SVM 在线性可分的情况下:
- 约束/确保每个观察都在超平面的正确一侧
- 选择最佳线,使这些最近的点到超平面的距离最大化,即所谓的边距
线性不可分情形下的 SVM
在线性可分的情况下,SVM 试图找到使裕度最大化的超平面,条件是两个类都被正确分类。但在现实中,数据集可能永远不会线性分离,所以超平面 100%正确分类的条件永远不会满足。
SVM 通过引入两个概念来处理非线性可分的情况:软余量和内核技巧。
我们来举个例子。如果我在绿色聚类中添加一个红点,数据集就不再是线性不可分的了。这个问题有两个解决方案:
- **软边距:**尝试找到一条线来分隔,但允许一个或几个错误分类的点(例如,用红色圈出的点)
- **内核技巧:**尝试找到一个非线性决策边界
软利润
在软裕度下,SVM 容忍两种类型的错误分类:
- 该点位于决策边界的错误一侧,但位于正确一侧/边缘(如左侧所示)
- 该点位于决策边界的错误一侧和页边距的错误一侧(如右图所示)
应用软边距,SVM 容忍一些点被错误分类,并试图在找到一条最大化边距和最小化错误分类的线之间进行平衡。
容差程度
在寻找决策边界时,我们希望给出多少容差(软)是 SVM(线性和非线性解决方案)的一个重要超参数。在 Sklearn 中,它被表示为惩罚项—‘C’。C 越大,SVM 在分类错误时受到的惩罚就越多。因此,边缘越窄,决策边界将依赖的支持向量就越少。
# Default Penalty/Default Tolerance
clf = svm.SVC(kernel='linear', C=1)
# Less Penalty/More Tolearance
clf2 = svm.SVC(kernel='linear', C=0.01)
内核技巧
Kernel Trick 所做的是利用现有的特性,应用一些转换,并创建新的特性。这些新特征是 SVM 找到非线性决策边界的关键。
在 Sklearn — svm。SVC(),我们可以选择’线性’,‘多边形’,’ rbf ‘,’ sigmoid ‘,’ precomputed '或一个 callable 作为我们的内核/转换。我将给出两个最流行的核的例子——多项式和径向基函数(RBF)。
多项式内核
将多项式内核视为一个转换器/处理器,通过应用所有现有要素的多项式组合来生成新要素。
为了说明应用多项式转换器的好处,我们举一个简单的例子:
现有特征:X = np.array([-2,-1,0,1,2])
标签:Y = np.array([1,1,0,1,1])
我们不可能找到一条线将黄色(1)和紫色(0)的点分开(如左图所示)。
但是,如果我们应用变换 X 得到:
新特征:X = np.array([4,1,0,1,4])
通过组合现有的和新的特征,我们当然可以画一条线把黄紫色的点分开(如右图所示)。
具有多项式核的支持向量机可以使用那些多项式特征生成非线性决策边界。
径向基函数核
将径向基函数核视为一个转换器/处理器,通过测量所有其他点到特定点(中心)的距离来生成新要素。最流行/最基本的 RBF 核是高斯径向基函数:
gamma (γ) 控制新特征—φ(x,center) 对决策边界的影响。灰度系数越高,特征对决策边界的影响就越大,边界的波动就越大。
为了说明应用高斯 rbf (gamma = 0.1)的好处,让我们使用相同的示例:
现有特征:X = np.array([-2,-1,0,1,2])
标签:Y = np.array([1,1,0,1,1])
同样,我们也不可能找到一条线把点分开(左手)。
但是,如果我们使用两个中心(-1,0)和(2,0)应用高斯 RBF 变换来获得新特征,那么我们将能够绘制一条线来分隔黄色紫色点(在右侧):
新特征 1: X_new1 = array([1.01,1.00,1.01,1.04,1.09)
新特征 2: X_new2 = array([1.09,1.04,1.01,1.00
# Note for how we get New Feature 1, e.g. **1.01**:
Φ(x1,center1) = np.exp(np.power(-(gamma*(x1-center1)),2)) = 1.01
# gamma = 0.1
# center1 = [-1,0]
# x1 = [-2,0]
类似于软边界中的惩罚项 C,伽马是一个超参数,当我们将 SVM 与内核结合使用时,我们可以对其进行调整。
# Gamma is small, influence is small
clf = svm.SVC(kernel='rbf', Gamma=1)
# Gamma gets bigger, influence increase, the decision boundary get wiggled
clf2 = svm.SVC(kernel='rbf', Gamma=10)
# Gamma gets too big, influence too much, the decision boundary get too wiggled
clf3 = svm.SVC(kernel='rbf', Gamma=20)
总而言之,SVM 在线性不可分的情况下:
- 通过将软裕度(误分类容忍度)和核技巧结合在一起,支持向量机能够构造线性不可分情况的决策边界。
- 像 C 或伽马这样的超参数控制着 SVM 决策边界的摆动程度。
- C 越高,SVM 在错误分类时得到的惩罚就越多,因此决策边界的波动就越小
- 伽马值越高,特征数据点对决策边界的影响越大,因此边界的摆动越大
最后,就是这样。
这个博客的代码可以在我的 GitHub 链接中找到。
优化的一个很好的解释/理由可以在链接中找到,这里是 SVM uda city 的 YouTube 视频。
请在下面留下任何评论、问题或建议。谢谢大家!
支持向量机
支持向量:从来没有这么多人欠这么少人这么多
1.问题是
支持向量机着手解决“分类”问题。如果给我们一些数据,它将由一定数量的条目/行/点组成。现在,我们想把每一个点分成几类。为了简单起见,我们假设我们只对两类感兴趣,“积极的”和“消极的”。这可能有助于回答的重要问题示例(有些比其他更重要):
- 给定像素数据,照片中是否有猫(有猫表示阳性标签)。
- 从主题、发件人、文本等方面来看,一封邮件是否是垃圾邮件。
- 确定患者是否患有某种疾病。
这个想法是,当我们已经知道正确的答案时,我们想出一些规则来将数据分成两类(对于 SVM 的,这个“规则”恰好是画一个平面,称一边的所有点为正,另一边的所有点为负)。然后,当我们遇到一个我们不知道答案的新数据点时,我们使用我们(或我们的“机器”)“学习”的相同规则来分类它。这个话题很大程度上依赖于约束优化理论,并且是一个很好的例证,我不久前在博客上写了一篇关于约束优化理论的文章。此外,我们将大致遵循吴恩达的论文。
1.1.在图片中
我觉得直到我画了画,我才真正理解了事物。还有,大家都喜欢图片。所以让我们来看一些。
我们在特征空间中有一些点。为了便于可视化,让我们考虑一个二维特征空间,这样我们可以在屏幕上看到它。我们在这个空间中散布了一些点,每个点都有一个二进制标签(1/-1)。在下图中,我们可以认为绿点代表正标签,红点代表负标签。对于黄点,我们不知道它们的标签是什么(正面还是负面)。如果让你猜一个标签,你会选哪个?你可能会发现有些观点并不明确。
Fig 1: 2-D classification problem. Green points are positive and red ones are negative. Can you guess the labels for the yellow points? Created using: https://github.com/ryu577/pyray
现在,如果我画一条紫色的线来分隔这两个类,那么每个黄色点应该属于哪个类就变得更加清楚了(线上的任何东西都是绿色的,线下的任何东西都是红色的)。
Fig 2: Drawing a separating line gives us a “rule” for assigning positive and negative labels. Now, we can use that rule to label each of the yellow points. Created using: https://github.com/ryu577/pyray
然而,上面这条线并不是唯一的。有多条紫色的线完美的分隔了绿色和红色的点。下图显示了其中的一些。当我们在这些线之间切换时,一些黄色点的含义很严重(它们最终位于线的不同侧,因此会根据线的选择翻转它们的标签)。
Fig 3: There could be multiple separating lines that split the red points from the green perfectly well. Which of these lines should be choose? Created using: https://github.com/ryu577/pyray
所以,在所有候选线路中,问题是哪一条是“最好的”?从上面的图 3 中可以清楚地看出,当紫色线靠近右下角的红点时,它似乎不能很好地概括,而当它远离该点时,它看起来像是一条更好的分隔线。因此,似乎有一点决定了这条线有多好,使它变得“至关重要”。可以说,远离该红点的线尽可能远离所有训练示例,而不必要地靠近该红点的线最终看起来不如分类器那么好。因此,即使是最接近的训练样本,最终也会被推离自己很远的线会成为好的分类器。我们将在第 3 节更具体地阐述这一观点。但首先,让我们学习用数学画线。
2.画线
所以我们想画一条分隔线(或者只是一条一般的线)(在二维空间;它将是高维空间中的超平面)。那么,什么是线呢?它是有共同点的点的无限集合。它们都满足某个等式。为了找到这个方程,让我们从最简单的 x 轴开始。上面各点的位置向量有什么共同点?它们看起来都像:v_x = [x,0]意味着它们的 y 坐标为零。
另一种说法是,其上每个点的位置向量都与指向 y 轴方向的向量正交(垂直)。
第二个陈述可能看起来像是用一种奇怪而复杂的方式来表达更简单的东西,但这种方式很重要,因为它对所有行都适用,而不仅仅是这个 x 轴。这很好,因为我们不关心 x 轴本身。我们真的希望能够推广到任何行。一步一步来,让我们首先考虑穿过原点的直线(如 x 轴)。这些线可以通过简单地将 x 轴旋转某个角度来获得,如下图所示。
Fig 4: Rotating the x-axis can give us any line passing through the origin. And for all these lines, every point on them will be perpendicular to the orange vector.
当线改变时,恰好垂直于它的向量也改变,但是线上每个点的位置向量垂直于某个向量的事实对于所有线都是不变的。让我们称这个向量为 w 为通过原点的一般直线。当我们改变 w 时,我们将捕获所有这样的线。
注意,对于任何给定的行,也有多个值 w 。本质上,如果我们把它放大或缩小任意倍,直线上每个点的位置向量都垂直于它的事实不会改变。
Fig 5: Orthogonal w vector scaling up and down.
那么,为什么不把我们自己限制在大小为 1 的向量上呢?从现在开始,让我们假设任何时候我们谈论一个名为 w 的向量,它的大小都是 1。
所以现在我们已经成功地参数化了所有经过原点的线。那些没有的呢?我们可以通过将穿过原点的其中一条线向 w 的方向移动一定量 b ,得到这样一条线。现在, w 与直线上任意一点的位置矢量的点积不为零。但是,还是不变, b 。从下面的图 6 中可以清楚地看到这一点。w 矢量是一个单位矢量,从原点指向线(紫色)并与之垂直。a 是直线上离原点最近的点。假设距离 OA 为 -b 。现在,考虑两个随机点 B 和 C(绿色和橙色)。如果你取 OB 或 OC 与单位向量 w 的点积,你就分别得到三角形 OAB 和 OAC 的底边。而且这两种情况下,这只是 OA,也就是 -b 。由于这两个点是直线上的任意点,我们可以得出结论,直线上的所有点都将满足 w^T x+b=0 (其中 x 是点的位置向量,即上面两个示例点的 OB 和 OC)。
Fig 6: A line that doesn’t necessarily pass through the origin.
当我们把一个不在直线上的点代入上面推导出的直线的方程,会发生什么?我们得到一个不为零的数,当然,但它也恰好是点到直线的垂直距离(所以对于直线上的点,这是预期的零)。值得注意的是,这个结论只有在 |w|=1 时才成立,正如我们一直要求的那样。下图应该清楚地表明了这一结果。我们取任意一点,B 不在直线上。然后,我们从紫色线 B "和代表 w 矢量的线 B ‘上的 B 点开始画垂线。从 B 到直线的垂直距离由图中的 BB”给出。但是由于 A-B’-B-B ’ ‘形成一个矩形,这个距离等于 AB’=OB’-OA。现在,OB ‘只是 B (OB)的位置向量与 w 的点积,所以,如果 x 是 b 的位置向量,那么|OB’| = w^T x 。这意味着|AB’|= w^T x-(-b) (回想一下 OA= -b )。所以点到直线的垂直距离变成:|AB’|= w^T x+b ,这是直线的方程。
Fig 7: What happens when we plug a point not on the line into its equation? We get the perpendicular distance between the point and the line.
请注意,插入电源时, w 指向的线一侧的所有点(如图 7 中的 B 点)的垂直距离为正,而另一侧的点的垂直距离为负。
但是,所有位于 w 点一侧的点都有一个正标号( t_i=1 ),位于另一侧的点都有一个负标号( t_i=-1 )。因此,如果我们将标注与垂直距离相乘,只要这些点被线正确分类,调整后的垂直距离对所有点都是正的(即标注为正的点位于一侧,标注为负的点位于另一侧)。
3.最佳路线
现在来看看支持向量机的妙处。我们称调整后的任意点到直线的垂直距离为该点的边距。任何给定的线对于所有点都有一些边距(如果该点被该线正确分类,这些边距将为正,否则为负)。我们希望线条能够很好地区分积极和消极。换句话说,边距应该尽可能大,即使是最靠近边界(分离平面)的点也是如此。这与我们在 1.1 节末尾讨论的想法是一致的。
因此,最大化甚至最差裕量的平面应该很好地分离点。现在,给定一个( w,b )组合,第 I 个点的余量将由下式给出( x_i 是特征空间中的位置向量, t_i 是标签:1 表示正,1 表示负):
Equation of the margin.
所有点的最小余量变成:
Eq (1): The minimum margin across all points.
我们希望( w,b )对最大化这个最小余量。换句话说,我们想要:
换句话说,我们想要满足 |w|=1 并最大化余量的( w,b )对:
Eq(2): The SVM objective function.
注意,如果该行没有分隔数据,那么对于那个( w,b )组合,术语:
Equation of the margin.
某些点会是负的。其中一个点会在第一次最小化中胜出。这将意味着那些( w,b )组合永远不会在第二个 arg max 中“胜出”。所以,这确保了获胜的( w,b )组合将总是分离数据,如果数据是可分离的话。
等式(2)是一个优化问题,包括最小化和最大化(mini-max)。解决只涉及一级优化而不是两级优化的问题要容易得多。所以,我们试着把它转化为一个约束优化问题。
让我们回到将跨越所有点的最小余量称为 γ 的问题上来。
Eq (3): The constraints
最终的优化问题变成了:
Eq (4): SVM optimization problem
这是一个带有二次/线性约束和线性目标函数的优化问题。它可以用二次规划求解器(我们将在后面看到一些代码)求解,并获得最佳分离线/平面( w,b 组合)。
现在,让我们看看是否可以进一步简化它。原来,有一种方法可以摆脱 γ 。这是有代价的——我们必须放弃 w^t w = 1 T3 的要求。但是考虑到简化,这是值得的。让我们以它来划分两边的约束。我们得到:
Eq (5): Divide plane equation by gamma.
现在,设置:
Introducing a new w variable.
取两边的模数,
Take modulus
但是,我们一直要求 |w|=1 。这意味着:
此外,等式(3)现在变成:
Eq (6)
等式(5)和(6)产生等式(4)中的优化问题:
到目前为止,优化问题有一个丑陋的目标函数。但是最大化 1/|w| 和最小化 |w| 是一回事,和最小化 |w| 是一回事。增加 1/2 会让以后的生活稍微轻松一点。
所以,我们可以把它重新表述为:
Eq (7)
这现在是一个具有二次目标函数和线性约束的优化问题(线性约束二次规划或 LCQP)。它可以用各种语言的二次规划求解器来解决。
我们现在知道如何通过解决一个优化问题来找到最优线。透过表面看这些类型的优化问题是如何解决的(通过拉格朗日乘数)会给我们对问题的强烈洞察力和直觉。请继续关注第 2 部分(此处为),在这一部分中,我们将完成这一过程,并展示一些玩具示例。
支持向量机分类
了解支持向量机(SVM),从直觉到实现
机器学习中的分类是学习区分数据集中属于两个或更多类别的点的任务。在几何术语中,将一组点与某个类别相关联涉及找到这些点之间的最佳可能分离。假设我们有一个类似这样的数据集:
Figure 1. Dataset representation and margin
在这里,我们可以清楚地区分两类,分别用 C1 = 1 和 C2 = -1 来标识。我们也将这定义为一个二元分类问题。例如,如果我们的每个数据点都代表电子邮件文本,并且我们希望将这些分类为垃圾邮件和非垃圾邮件,那么我们将每封电子邮件都是一个数据点 x ,而 y = 1 将识别垃圾邮件, y = -1 非垃圾邮件。同样,我们还可以有其他类似的场景,比如猫狗分类、信用/非信用批准等。
在图 1 中,我们还可以看到,中间的线性函数确保了两个类别之间的最佳分离。我们故意称之为超平面的原因是因为我们这里的描述可以扩展到多维场景。例如,如果我们在 3D 空间中工作,我们将有一个分割平面而不是一条线。
从现在起,我们将分类数据集之间的分离标识为边缘、,并且它将由最近点和分离超平面之间形成的距离来管理。因此,立即出现的问题是,我们如何确保这个最佳超平面确保两个类别的最佳可能余量?这正是支持向量机,或简称 SVM 将为我们做的。
在继续之前,值得指出的是,支持向量机是用于分类任务的最强大的机器学习算法之一,广泛用于从计算机视觉到 NLP 的应用。让我们进一步探讨这个方法。
导出原始问题
首先,假设我们的数据集由 N 个点组成。在图 1 中,我们可以看到,通过使用由下式定义的线性函数(即超平面),可以很好地分离这两个类别:
这里, x n 表示一个数据点, w 是一个权重向量, b 是偏差, y n 是模型的预测。在这种情况下,对于位于超平面两侧的点,每个预测可以是 1 或-1,对于位于超平面本身上的点,每个预测可以是 0。给定一个包含几个 x 及其对应的 y 的数据集,我们想要做的是找到给我们最好的可能余量的 w 和 b 的值。
为了更清楚,让我们用几何图形来说明我们的模型变量:
Figure 2. Geometric representation of variables
这里,xn是最接近超平面的点之一,并且它形成了源自该点的正交向量 d 。我们可以看到,矢量 d 与 w 方向相同。此外,位于超平面上的任何一点 x0 都会与xn形成一个矢量 r 。根据这些定义,我们可以清楚地看到 d 是 r 在 w 上的投影,由下式给出:****
让我们把 b 和- b 加到这个等式的分子上。 d 的大小将给出 x 到超平面的距离,定义如下:
注意,对于位于超平面上的 x0 ,其对应的预测 y0 为零,这就是括号内的表达式消失的原因。所以为了找到最优余量,我们要做的就是最大化 d 。有了这些考虑,我们最终可以陈述模型的优化问题:
嗯,从微积分我们知道,为了找到最大值,我们需要使用导数。在这种情况下,我们使用不涉及对等术语的表达会更方便。那么,我们怎样才能使 dd方程更容易优化呢?是的,你猜对了!将括号内的倒数项倒置,然后将其转化为最小化问题。让我们这样做:
Equation 1. Optimal distance expression
所以现在你可能会问,为什么我们把 w 的幂提高到 2,然后除以 2?这只是我们在计算导数时,为了让事情变得简单而应用的一个数学技巧。基本上,主要原因是这个表达式的导数就是 w 。然而,最重要的是,这将帮助我们定义一个二次规划问题,我们将能够使用流行的优化库来解决这个问题,我们将在后面看到。
好了,现在我们已经定义了优化问题的一部分。但是,让我们更深入地看看这个限制:
我们可以看到,这涉及到一个绝对值。看起来不太好,对吧?如果我们能摆脱它就好了。怎么才能做到呢?让我们稍微想想我们预测的正确性。我们希望我们的模型尽最大努力对所有点进行正确分类。但是我们如何用数学术语定义一个正确分类的点呢?让我们首先介绍一些有用的符号。
所以我们希望我们的模型做出与正确答案 yn 相等的预测。当给出的答案和预测的答案符号相同时,就会发生这种情况。也就是说,当两者的乘积至少为 1 时。让我们用数学表达式来表述:
Equation 2. Modified restriction
太好了!有了这个限制,以及等式 1,我们的优化问题将如下:
Equation 3. Expression for the primal problem
这个表达式定义了支持向量机的主要问题。请注意,对于由( x n , yn )形成的每个限制,都有一个关联的 Langrange 乘数 α 。阿尔法值大于零的数据点xn 也被称为支持向量,因为它们影响分离超平面的行为。
此外,如果我们看一下等式 3,我们可以看到它在 w 上有一个二次型。因此我们可以说这是一个二次规划问题。然而,我们这里有一个问题,这个问题取决于三个变量,而不是一个。让它只依赖于一个参数集肯定会让事情变得更简单,这将激发我们对下一节讨论的对偶问题的推导。
定义对偶问题
在上一节中,我们阐述了 SVM 的原始问题。然而,正如我们之前讨论的,让它依赖于一个参数会容易得多。让我们现在做那件事。
如果我们计算等式 3 中的 L 相对于 w 和 b 的导数,然后使导数等于零,我们得到:
从这里,我们得到:
替换等式 3 中的这两个表达式,我们得到:
重新排列:
Equation 4
嗯,正如我们所看到的,这已经成为一个二次规划问题,它只取决于拉格朗日乘数 α ,而不再取决于w和 b 。这肯定比我们之前讨论的原始问题要简单得多。除此之外,关于等式 4 中xm*和x* n 的产生还有一个有趣的方面。原来这个产品其实可以表述为一个内核函数。一般来说,核函数允许我们将非线性可分空间转换为线性可分空间,并且当我们试图执行不同的分类任务时,它是一个有用的工具。通常使用的核包括但不限于线性核和径向基函数(RBF)。更多关于内核方法的信息可以在【2】这里找到。
最后,对偶问题可以表述如下:
Equation 5. Dual problem for SVM
这是一个最大化的二次规划问题。这里, k 是我们定义的一个核函数。另外,请注意第一个限制,它强制所有字母大于或等于零。如前所述,阿尔法值大于零的数据点是支持向量,并影响分离超平面的行为。此外,如果我们将此转化为最小化问题,并将这些表达式转换为矩阵形式,我们可以很容易地使用 CVXOPT 等优化库来求解最佳参数。我们将在后面看到如何做到这一点。
我们对对偶问题的定义在这里有一个重要的限制。只有当类别可以完全分离时,它才能很好地工作。这就是为什么这个默认版本也被称为硬边际 SVM 。但是你可以想象,我们不太可能在现实生活中找到完全分离的数据集。因此,我们接下来将讨论一种变体,它允许我们将支持向量机扩展到一些点可能被错误分类的场景,也称为软裕度 SVM 。
软利润 SVM
如前所述,硬边界支持向量机在实际应用中用途有限。在这里,我们将表明,通过对原始对偶问题做一点小小的改变,我们可以将支持向量机扩展到一些点可能被错误分类的场景。让我们用图表来说明我们的想法:
Figure 3. Misclassification scenarios for the soft-margin SVM
这里,我们定义了一个新的公差变量ε。位于边缘的点的ε = 0。另一方面,我们离正确的边界越远,ε的值就越大。最终,对于在超平面错误一侧的点,我们期望ε大于 1。我们现在需要做的是,把这个新变量插入到原始问题的初始定义中。因此,如果我们将ε加入等式 2 中定义的限制条件,我们会得到:
这意味着我们的限制现在允许一些点离边界更远一点。ε本身现在成为另一个参数,我们必须在我们的主要问题中考虑,我们必须努力使它最小化。在这种情况下,我们的目标是:
如我们所见,这里的第二项是我们定义的一个新变量 C 和所有ε之和的乘积。这将迫使当 C 较大时,由ε值给出的总体错误分类将较小。这意味着, C 越大,保证金就越严格。通过考虑原始问题中的这些新变量,我们得到:
Equation 6
这里,μ是我们为公差值ε定义的拉格朗日乘数。我们期望每个μ大于或等于零。现在让我们相对于 w 、 b 和ε来区分 L 。
从这里,我们得到:
让我们把注意力稍微转向第三个表达。我们之前说过,μ和 α 都可以大于或等于零,这意味着:
然后,通过替换等式 6 中的所有这些表达式,并像我们对硬边界 SVM 情况所做的那样重新排列,我们得到以下结果:
Equation 7. Dual problem for the soft-margin SVM
太好了!在这一点上,我们可以看到,除了现在考虑到 C 的第一个限制之外,一切都与硬边际 SVM 的情况相同。在下一节中,我们将通过使用一个玩具数据集来实现一个软边界 SVM,我们将使用 CVXOPT 进行优化。
用 CVXOPT 实现软利润 SVM
注意:完整的实现可以在https://bit.ly/2xBDJ2Q的 Jupyter 笔记本上获得
CVXOPT [3]是一个用于凸优化的 Python 库。我们将用它来解决软间隔支持向量机的对偶问题。然而,在此之前,我们需要将这样一个对偶问题转化为一个最小化目标,然后将所有变量转化为矩阵。为了将对偶问题转化为最小化问题,我们只需反转等式 7 中拉格朗日量的符号,然后将其表示为矩阵形式:
在哪里
这里,我们使用了*操作符来表示 Python 中的逐元素乘法。此外, K 是通过计算整个数据集 X 的核值而得到的 Gram 矩阵。
现在以矩阵形式表示的限制如下:
现在,CVXOPT 将需要一个特殊的符号来配置我们的对偶问题,以及我们的限制。本质上,我们需要做的是配置以下矩阵:
使用 CVXOPT 的相应 Python 代码如下:
最后的容差参数定义了在声明收敛之前我们允许的变化量。如你所见, solvers.qp 调用接收我们配置的所有矩阵,它将打印出每个时期的成本值,直到收敛。
一旦我们的 SVM 被完全训练,我们可以通过使用下面的表达式容易地获得参数 w 和 b :
其中 S 是支持向量的子集。相应的实现如下:
为了便于说明,我们使用两个自己生成的数据集测试了这个实现。第一个数据集是线性可分的,第二个数据集包含可以用圆圈分隔的类别。这是两个数据集的图表:
Figure 4. Dataset graphs
在这两种情况下,我们可以看到属于第一类和第二类的点分别被染成红色和蓝色。同样,黑色的点是我们找到的支持向量。通过适当配置 C 参数,我们应该可以看到不同的裕量行为。
此外,第二数据集不是线性可分的。在这些情况下,我们所做的就是使用内核技巧。也就是说,我们使用一个核函数,将我们从某个空间中的非线性可分数据集带到另一个空间中的线性可分数据集。特别是,我们在本例中处理第二个数据集的方法是使用 RBF 而不是线性核。
线性核和 RBF 可以分别通过这些表达式来计算:
其中γ是我们为 RBF 情况设置的超参数。这些内核的相应实现如下所示:
结束语
支持向量机是一种非常强大的机器学习模型。尽管我们的注意力主要集中在用于二元分类的支持向量机上,但我们可以通过使用一对一或一对一等技术将它们的使用扩展到多类场景,这涉及到为每一对类创建一个 SVM。我强烈建议您进一步研究实现,以及我们如何使用流行的库来训练 SVM,例如 *sklearn。*在这里,您需要为 C 选择合适的值,以及一个合适的内核以获得更好的分类结果。
参考
[1] Bishop,Christopher M. 模式识别和机器学习 (2006)施普林格出版社柏林,海德堡。
[2]托马斯·霍夫曼。伯恩哈德·肖科普夫。《机器学习中的核心方法》 (2008)统计年鉴。第 36 卷,第 3 卷,1171-1220 页。
[3] CVXOPT。解一个二次规划。在 https://cvxopt.org/examples/tutorial/qp.html有售
[4]加州理工学院。从数据中学习 (2012)。在https://work.caltech.edu/telecourse上市
支持向量机和不平衡数据
在不平衡数据集的情况下,SVM 是如何工作的?
内容:
- 支持向量机简介
- 观察 SVM 在不平衡数据集的情况下如何工作。
- 观察超平面如何根据正则项的变化而变化。
支持向量机简介
在机器学习中,支持向量机器是具有相关学习算法的监督学习模型,其分析用于分类和回归分析的数据。给定一组训练样本,每个样本被标记为属于两个类别中的一个或另一个,SVM 训练算法建立一个模型,将新样本分配给一个类别或另一个类别。
在 SVM,超平面是以这样的方式选择的,它与两个类都是等距的,并且距离最短。
迷茫?看看下面的解释。
Figure 1
我们假设,红点是 1 类,绿点是 2 类。
现在,如果要我画一个阈值来区分这两个类别,我可以画出来,实际上有 n 种方法。
Figure 2
当我画一个如图 2 所示的边距时会发生什么?左边的任何东西都将被归类为红点,右边的任何东西都将被归类为绿点。
我们来分析一下。
Figure 3
这个新点可以归为红点,也就是 1 类。
Figure 4
这个新点可以归为绿点,也就是 2 类。
好吧!那是非常直接的。但是让我们看看下面的情况。
Figure 5
这个新点将被归类为绿点,因为它位于右侧。根据阈值,是的,这是一个正确的分类。但这真的对吗?不要!
该点离红点近得多,离绿点远得多。所以,这是一个错误的分类。
那我们怎么决定合适的阈值呢?
Figure 6
让我们把注意力集中在这两个类的边缘的观察上。现在让我们画一个阈值,这样它到两点的距离是相等的。
Figure 7
现在,该阈值左侧的任何点都将比绿点更靠近红点,因此将被归类为红点。右边的任何一点都是绿点。
Figure 8
边缘观察被称为支持向量。
观察值和阈值之间的最短距离称为裕度。当阈值在两个观察值的中间时,差值尽可能大。
现在让我们开始吧……
SVM 和不平衡数据
首先,让我们创建不平衡数据集,每个数据集都有正类和负类。
数据集 1-100 个正点和 2 个负点
数据集 2-100 个正点和 20 个负点
数据集 3-100 个正点和 40 个负点
数据集 4-100 个正点和 80 个负点
import numpy as np
import matplotlib.pyplot as plt
ratios = [(100,2), (100, 20), (100, 40), (100, 80)]
plt.figure(figsize = (20,6))
for j,i in enumerate(ratios):
plt.subplot(1, 4, j+1)
X_p=np.random.normal(0,0.05,size=(i[0],2))
X_n=np.random.normal(0.13,0.02,size=(i[1],2))
y_p=np.array([1]*i[0]).reshape(-1,1)
y_n=np.array([0]*i[1]).reshape(-1,1)
X=np.vstack((X_p,X_n))
y=np.vstack((y_p,y_n))
plt.title(“Dataset “ + str(j+1)+ “: “ +str(i))
plt.scatter(X_p[:,0],X_p[:,1])
plt.scatter(X_n[:,0],X_n[:,1],color=’red’)
plt.show()
这段代码将创建 4 个不同的数据集。这些数据集如下所示:
Figure 9
现在,您已经看到了我们的数据集的样子,让我们继续。
现在我们要画一个分离这些点的超平面。我们将考虑正则项的 3 个不同值,并在不平衡数据集上观察超平面如何随着正则项的变化而变化。
我们只需要添加几行代码来完成我们的代码。因此,更新后的代码如下所示:
def draw_line(coef,intercept, mi, ma):
points=np.array([[((-coef[1]*mi — intercept)/coef[0]), mi],
[((-coef[1]*ma — intercept)/coef[0]), ma]])
plt.plot(points[:,0], points[:,1])
上面的代码是画出分隔点的线。
c = [0.001,1,100]
plt.figure(figsize = (20,30))
ratios = [(100,2), (100, 20), (100, 40), (100, 80)]
num=1
for j,i in enumerate(ratios):
for k in range(0, 3):
model=LinearSVC(C=c[k])
plt.subplot(4, 3, num)
num=num+1
X_p=np.random.normal(0,0.05,size=(i[0],2))
X_n=np.random.normal(0.13,0.02,size=(i[1],2))
y_p=np.array([1]*i[0]).reshape(-1,1)
y_n=np.array([0]*i[1]).reshape(-1,1)
X=np.vstack((X_p,X_n))
y=np.vstack((y_p,y_n))
model.fit(X,y)
plt.scatter(X_p[:,0],X_p[:,1])
plt.scatter(X_n[:,0],X_n[:,1],color=’red’)
plt.title(‘C = ‘+ str(c[k])+str(i))
draw_line(coef=model.coef_[0],intercept=model.intercept_,ma= max(X[:,1]), mi= min(X[:,1]))
plt.show()
输出:
Figure 10
观察
- 当 c = 0.001 时
由于 c 非常小,模型无法对数据进行分类,我们可以观察到超平面位置离数据点非常远。数据平衡或不平衡在这里没有任何区别,因为 c 值非常小。
2.当 c = 1 时
超平面远离数据点,可以说该模型不能对不平衡数据集进行分类。在最后一种情况下,数据集几乎是平衡的,我们可以看到,该模型可以分类有位错误,但这似乎只有在数据平衡的情况下才能很好地工作。
3.当 c = 100 时
即使 c 值很高,该模型也无法对高度不平衡的数据集进行分类。因此,我们可以得出结论,该模型效果不佳,或者当数据集高度不平衡时,不建议使用该模型。随着数据的增加,模型在分类方面做得非常好。
参考资料:
在机器学习中,支持向量机(SVMs,也称为支持向量网络)是一种有监督的学习模型
en.wikipedia.org](https://en.wikipedia.org/wiki/Support-vector_machine)
应用人工智能课程—https://www.appliedaicourse.com/
从零开始的核支持向量机
从最大间距分隔符到内核技巧的逐步数学和实现
从 20 世纪 90 年代末,直到深度学习的兴起,具有非线性核的支持向量机(SVM)一直是领先的算法。他们能够解决像逻辑回归这样的线性分类器无法解决的许多非线性问题。最简单和最著名的例子是一个数据集,其标签分布类似于异或(XOR)真值表。
SVM 是由机器学习的主要理论家之一 Vladimir Vapnik [1]于 1992 年至 1995 年提出的。他与人合著了 Vapnik-Chervonenkis 机器学习理论[2]。
SVM 背后有三个主要想法:
- 最大空白分隔符:画一条线或超平面,使分隔符和训练数据之间的距离最大化,从而引入一个空白层
- 软页边距分隔符:当不同标签的数据混淆时,考虑页边距内的样本,画出最佳分隔线
- 内核技巧:对于数据分离边界不是线性的更复杂的模型,允许使用高阶多项式甚至非多项式函数
Dataset looking like the exclusive-or (XOR) truth table © the author
为了更好地理解这些想法,我们将按顺序逐一解释。每次我们都会提供支持数学的摘要。完整的 Python 笔记本在 Github 上有 HTML 或者 木星 。
有两种方法来安装 SVM:
- 通过使用更新规则的梯度下降
- 使用求解器和拉格朗日原始或对偶形式的问题陈述
在本文中,使用的是第二种解决方案。
1.最大边距分隔符
使用几何解释可以更好地理解 SVM。给定一个 p 维的向量空间,我们想用一个超平面(如果 p=2,则是一条直线,即 2D 平面)来分隔它,使得标签为 1 的训练数据在超平面的一侧,标签为-1 的训练数据在超平面的另一侧。
超平面方程是:
其中 w 是与超平面正交的向量,b 是相对于原点定位超平面的偏差。
给定一个向量 x 和{-1,1}中相应的二进制标号 y,到超平面的有符号距离是:
© the author
宽度 M 的最大边距分隔符的表达式为:
这个优化问题可以被重写为对偶拉格朗日问题,并且由求解器提供解决方案。
Maximum margin separator © the author
边距边界上的点称为支持向量。
这种分类器非常接近于逻辑回归,但是不能处理由于噪声(一种无法解释的量)而导致数据类混合的数据集。这导致了以下改进。
2.软利润 SVM
为了克服当数据类混合时的优化问题,添加了一个新的约束来容忍误分类的数据点:位于分离超平面的错误侧的点,在边缘板之内或之外。
在下图中,我们看到分隔线现在位于两个类的数据点内。支持向量现在包括边缘板内的点。
Soft margin linear SVM © the author
这个分类器分离超平面非常接近逻辑回归或线性判别分析(LDA)的分类器分离超平面。即使决策函数看起来不同,性能也是一样的。
我们仍然无法解决异或数据集。需要第三个也是最后一个技巧。
3.内核技巧
到目前为止,SVM 与其他线性分类器如逻辑回归或线性判别分析没有太大的不同。
然而,观察到 SVM 的拟合和预测仅依赖于 x 样本的内积,出现了使用替代产品的新想法,好像通过变换 h(x) 对 x 进行了预处理。
以下产品功能应是对称的和正的:
其范围从简单的二次函数到更复杂的函数,如高斯径向核函数(RBF):
由于需要新的 x 值与训练样本的乘积,预测变得更加复杂。然而,我们可以将这种计算限制到支持向量。
XOR problem solved by an SVM with Gaussian RBF kernel © the author
有了具有非线性内核的 SVM,我们已经能够解决 XOR 问题,这是在 60 年代感知机发明之后第一个人工智能冬天[3]的原因之一。
完整的 Python 笔记本在 Github 上有HTML或者Jupyter的版本。它包含了更详细的数学,一个用 Python 定制的实现使用 Scipy 通用解算器**,**与实现 Scikit 的比较学习,与与逻辑回归和线性判别分析的比较
这篇帖子是 Github“循序渐进学习数据科学 ”中开发的系列文章的一部分。如果你喜欢它,请访问我们的知识库,并在项目中添加一颗星来提高它的可见性。
参考资料:
- [1]支持向量网络,Cortes,C. & Vapnik,载于 v . Mach Learn(1995)20:273—【https://doi.org/10.1007/BF00994018
- [2]维基百科上的 Vapnik Chervnonenkis 机器学习理论—https://en.wikipedia.org/wiki/Vapnik–Chervonenkis_theory
- [3]艾冬天上维基—https://en.wikipedia.org/wiki/AI_winter
- [4]朱庇特本帖笔记本—https://medium.com/r/?URL = https % 3A % 2F %2F nio 73 . github . io % 2f 数据-科学% 2f 分类% 2f 分类 SVM.ipynb
支持向量机——软间隔公式和核技巧
学习一些使支持向量机成为强大的线性分类器的高级概念
SVM’s soft margin formulation technique in action
介绍
支持向量机(SVM)是最流行的分类技术之一,旨在直接最小化误分类错误的数量。有许多可访问的资源可以理解支持向量机(SVM)如何工作的基础知识,然而,在几乎所有的现实世界应用中(其中数据是线性不可分的),SVM 使用一些高级概念。
这篇文章的目的是解释软边界公式的概念和支持向量机用来分类线性不可分数据的核心技巧。
如果你想先重温一下 SVM 的基础知识,我推荐你看看下面这篇文章。
从零开始的 SVM 模式
towardsdatascience.com](/support-vector-machine-introduction-to-machine-learning-algorithms-934a444fca47)
线性不可分性
在我们继续讨论软余量和核心技巧的概念之前,让我们先确定它们的必要性。假设我们有一些数据,可以在 2D 空间中描述如下:
Figure 1: Data representation where the two classes are not linearly separable
从图中可以明显看出,没有特定的线性判定边界可以很好地分离数据,即数据是线性不可分的。在更高维度的表现中,我们也可以有类似的情况。这可以归因于这样一个事实:通常,我们从数据中获得的特征不包含足够的信息以便我们可以清楚地区分这两个类别。在许多现实世界的应用程序中通常都是这种情况。幸运的是,研究人员已经提出了能够处理这种情况的技术。让我们看看它们是什么以及它们是如何工作的。
软边界公式
这个想法是基于一个简单的前提:允许 SVM 犯一定数量的错误,并保持尽可能大的差距,以便其他点仍然可以正确分类。只要修改 SVM 的目标,就可以做到这一点。
动机
让我们简要回顾一下采用这种提法的动机。
- 如前所述,几乎所有现实世界的应用程序都有线性不可分的数据。
- 在数据是线性可分的极少数情况下,我们可能不想选择一个完美分离数据的决策边界来避免过度拟合。例如,考虑下图:
Figure 2: Which decision boundary is better? Red or Green?
这里的red
决策边界完美地分隔了所有的训练点。然而,拥有如此少的余量的决策边界真的是一个好主意吗?你认为这样的决策边界会在看不见的数据上很好地推广吗?答案是:不。green
决策边界有更宽的边界,这将允许它对看不见的数据进行很好的概括。从这个意义上说,软余量公式也有助于避免过度拟合问题。
它是如何工作的(数学上)?
让我们看看如何修改我们的目标,以达到预期的行为。在这种新环境下,我们的目标是最大限度地降低以下目标:
equation 1
这与第二任期的最初目标不同。这里,**C**
是一个超参数,它决定了最大限度地提高利润和最小化错误之间的权衡。当**C**
较小时,分类错误的重要性较低,重点更多地放在最大化裕度上,而当**C**
较大时,重点更多地放在避免错误分类上,代价是保持裕度较小。
在这一点上,我们应该注意到,然而,并不是所有的错误都是相同的。与距离较近的数据点相比,远离决策边界错误一侧的数据点应该招致更多的惩罚。让我们看看如何在下图的帮助下实现这一点。
Figure 3: The penalty incurred by data points for being on the wrong side of the decision boundary
想法是:对于每个数据点**x_i**
,我们引入一个松弛变量**ξ_i**
。**ξ_i**
的值是**x_i**
到对应类的边距的距离,如果**x_i**
在边距的错误一侧,否则为零。因此,在错误一侧远离边缘的点将得到更多的惩罚。
有了这个想法,每个数据点**x_i**
需要满足以下约束:
equation 2
这里,不等式的左边可以被认为是分类的置信度。置信度得分≥ 1 表明分类器对该点进行了正确分类。但是,如果置信度得分< 1, it means that classifier did not classify the point correctly and incurring a linear penalty of 【 。
鉴于这些限制,我们的目标是最小化以下功能:
equation 3
其中我们使用了拉格朗日乘数的概念来优化约束条件下的损失函数。让我们把它与 SVM 处理线性可分情况的目标相比较(如下所示)。
equation 4
我们看到,在修改后的目标中,只有**ξ_i**
项是额外的,其他都是相同的。
注意:在最终解决方案中,对应于最接近边缘和边缘错误侧的点(即具有非零的
**ξ_i**
)的**λ_i**
将是非零的,因为它们在决策边界的定位中起关键作用,本质上使它们成为支持向量。
内核技巧
现在让我们探索使用“内核技巧”来解决线性不可分性问题的第二种解决方案。但首先,我们应该了解什么是核函数。
核函数
核函数是将两个向量(任何维度)作为输入并输出表示输入向量相似程度的分数的广义函数。你已经知道的一个简单的核函数是点积函数:如果点积小,我们得出向量不同的结论,如果点积大,我们得出向量更相似的结论。如果您有兴趣了解其他类型的内核函数,这个将是一个很好的来源。
“诡计”
让我们看看线性可分情况的目标函数:
equation 5
这是
equation 4
中物镜的修改形式。这里,我们代入了**w**
和**b**
的最佳值。这些最佳值可以通过对这些参数求微分equation 4
并使其等于 0 来计算。
我们可以从equation 5
中观察到,目标依赖于输入向量对的点积(***x_i . x_j***
),它只不过是一个核函数。现在这里有一件好事:我们不必局限于像点积这样简单的内核函数。我们可以使用任何花哨的核函数来代替点积,它具有在更高维度中测量相似性的能力(在这种情况下,它可能更精确;稍后将详细介绍),而不会增加太多的计算成本。这基本上被称为内核技巧。
它是如何工作的(数学上)?
核函数可以用数学方法写成如下形式:
equation 6
这里**x**
和**y**
是输入向量,***ϕ***
是变换函数,< , >
表示点积运算。在点积函数的情况下,***ϕ***
只是将输入向量映射到自身。
核函数本质上采用变换后的输入向量的点积。
现在让我们考虑下面figure 4
中描述的情况。我们看到,在 2d 空间中没有可以完美分离数据点的线性决策边界。圆形(或二次型)决策边界可能可以完成这项工作,但是,线性分类器无法得出这些类型的决策边界。
Figure 4: Points in 2D space are separable by a circular decision boundary.
在figure 4
中,每个点P
由 2D 空间中形状(x,y)
的特征表示。查看理想的决策边界,我们可以将点P
的转换函数***ϕ***
定义为***ϕ***(P) = (x^2, y^2, √2xy)
(我们为什么要进行这样的转换一会儿就清楚了)。让我们看看对于两点P_1
和P_2
的这种类型的变换,核函数是什么样子的。
equation 7
如果我们观察内核函数的最终形式,它无非是一个圆!这意味着我们改变了相似性的概念:我们不再通过点的接近程度(使用点积)来衡量相似性,而是根据点是否在一个圆内来衡量相似性。在这个意义上,定义这样的变换允许我们在 2D 空间中有一个非线性决策边界(它在原始 3D 空间中仍然是线性的)*。*要跟踪的内容可能很多,因此以下是我们所做决定的简要总结:
**1** - Each point P is represented by (**x**,**y**) coordinates in 2D space.**2** - We project the points to 3D space by transforming their coordinates to (**x^2**, **y^2**, **√2xy**)**3** - Points which have high value of **x**.**y** would move upwards along the z-axis (in this case, mostly the red circles). [This video](https://www.youtube.com/watch?v=3liCbRZPrZA) provides a good visualization of the same.**4** - We find a hyperplane in 3D space that would perfectly separate the classes.**5** - The form of Kernel function indicates that this hyperplane would form a circle in 2D space, thus giving us a non-linear decision boundary.
主要的要点是:
通过将数据嵌入到更高维的特征空间中,我们可以继续使用线性分类器!
这里需要注意的是,这些变换可能会大幅增加特征空间,从而增加计算成本。有什么方法可以在不增加计算成本的情况下获得上述好处呢?原来是有的!
让我们尝试重写equation 7
中的内核函数:
equation 8
哇哦。因此,核函数的值(因此,3D 空间中的点之间的相似性)正好是 2D 空间中的点之间的点积的平方。很棒,对吧?!但是这是怎么发生的呢?
原因是我们明智地选择了我们的转换函数***ϕ***
。只要我们继续这样做,我们就可以绕过变换步骤,直接从 2D 空间中的点之间的相似性来计算核函数值。这反过来也会抑制计算成本。我们有许多流行的内核函数,它们都有这种良好的特性,可以开箱即用(我们不需要搜索完美的***ϕ***
)。
结束语
到此为止,我们已经完成了这篇文章。希望本文提供的细节能让您深入了解是什么让 SVM 成为一个强大的线性分类器。如果你有任何问题或建议,请在评论中告诉我。干杯!🥂
如果你喜欢这篇文章,并对我未来的努力感兴趣,可以考虑在 Twitter 上关注我:https://twitter.com/rishabh_misra_