机器学习的三种方法
逻辑回归、反向传播和支持向量机在鸢尾花数据集上的比较
- 下载 Backpropagation.zip - 194.3 KB
- 下载 LogiticRegression_Iris_Test.zip - 341.5 KB
- 下载 LogiticRegression_Iris.zip - 362.4 KB
- 下载 Iris_Data.zip - 3.7 KB
- 下载 SMO_Test_Iris.zip - 374.2 KB
- 下载 SMO.zip - 850.3 KB
- 下载 BackpropagationTest.zip - 1,001.2 KB
引言
在机器学习中,任务通常是尝试创建一个能够根据一些输入数据给出某种结论的算法,而该结论应基于一些早期收集的数据。这类任务的一个简单示例是找出学生为考试学习所需的最低努力。例如,如果我们有7名学生的数据:学习小时数和考试成功率(一个流行的例子 :-))。
计算机程序应该计算出成功通过考试所需的最短学习时间。
好的。这只是一个例子。我不想纠结于如此简单的事情(无论如何:解决方案应该在6.9小时左右)。
我认为对于这类任务,有三个可能值得了解的重要算法:
- 逻辑回归
- 反向传播
- 支持向量机
以及第四个,它是以上两个算法的基础。
- 梯度下降
所有这四种算法做的事情都一样:回答上述问题。但它们的方式不同,能提供的答案也不同。进行一些比较是很有趣的。
应用它们的流程对所有算法都一样:使用现有的数据集,其中包含一些输入特征 x1, x2, x3,…以及一个稍后需要猜测的属性 y,然后训练软件来识别输入特征并正确猜测属性。所有算法的训练都是一个迭代过程。
我实现了这三种算法,并用鸢尾花数据集对它们进行了处理以进行比较。
鸢尾花数据集
鸢尾花数据集是处理这类问题的一个流行数据集。它是一个非常好的数据集,包含150朵鸢尾花的花朵特征数据:花朵的大小。
它在一行中包含以下信息:
- 花萼长度(厘米)
- 花萼宽度(厘米)
- 花瓣长度(厘米)
- 花瓣宽度(厘米)
- 类
- 鸢尾花setosa
- 鸢尾花versicolor
- 鸢尾花virginica
想法是根据花朵的测量值来猜测正确的花朵类别。
对于每种算法,我实现了一个训练应用程序和一个测试应用程序。我将150个样本分为135个样本用于训练,每种花5个用于测试。我知道,只有15个样本用于测试不是很多。但我认为这足以理解 :-)
但首先,对算法进行简要介绍
梯度下降
梯度下降是一种算法,它尝试逼近一个函数,例如
到一个给定的数据集样本 (x1, x2, x3…,y)。根据所需的输出,逼近函数可以是线性的、多项式的,或者只是一个可微分的函数。通过这种逼近,它可以猜测另一个属性 y 未知的数据样本 (x1, x2, x3…,?) 的属性 y。它主要以这种形式用于猜测数据样本的真实值作为属性。例如,如果我们有一些葡萄酒的特征数据,如酒精含量、糖含量、酸度……而属性是1到10之间的质量评分。这将由梯度下降算法解决。
逼近函数 f(x) 应尽可能匹配属性 y。因此,通过计算所有训练样本的偏差,将 f(x) 与属性关联起来,例如:
这个偏差通常被称为优化成本,它是对逼近质量的验证。偏差越小,逼近效果越好。这个成本应该被最小化,梯度下降算法就是这样做的。因此,构建成本函数的梯度,并从一个随机点开始,算法沿着该梯度下降,直到它变为0。移动是通过一个相对小的步长完成的:所谓的学习率。学习率对收敛行为影响很大。如果太大,算法会开始振荡,永远找不到最小值。如果太小,算法会“睡着”,永远达不到最小值。通常,要处理的数据样本越多,它应该越小。
(有关梯度下降算法的详细描述,请参见 http://www.mosismath.com/AI/GradientDescend.html 。)
逻辑回归
逻辑回归是一种基于梯度下降算法的算法,但其目的是逼近一个输出为0或1的数字函数。其输出是一个概率。与梯度下降类似,它尝试逼近一个函数,例如:
但这个函数被输入到一个称为触发器函数中,通常是Sigmoid函数。
这个 g(x) 用于优化,应尽可能匹配属性 y(值为0或1)。现在,通过计算所有训练样本的偏差,将 g(x) 与属性关联起来,例如:
Sigmoid函数对于大的负输入值是0,对于大的正输入值趋近于1。
这会将逼近的输出转换为0到1之间的概率,对于 y = 0 且小于0.5,对于 y = 1 且大于0.5。逻辑回归用于猜测数字属性(有关详细描述,请参见 http://www.mosismath.com/AI/LogisticRegression.html)。
使用逻辑回归处理鸢尾花数据集
要使用逻辑回归处理鸢尾花数据集,首先必须将任务分为三个部分:
算法首先应该检查数据样本是否属于鸢尾花 Versicolor
类别。如果不是,它应该检查样本是否属于鸢尾花 Setosa 类别,如果也不是,它应该最后检查鸢尾花 Virginica 类别。看起来像这样:
这意味着我们需要训练3个设置,并获得3组参数,这些参数可以很容易地从训练应用程序复制到测试应用程序。好的,最后一步可以省略,但我认为这样网络看起来很漂亮。 :-)
需要注意的一个重要问题是:最后一个节点有一个输出“不是鸢尾花 Virginica”。使用这些数据时,它永远不会被激活。算法只能区分训练过的类别,由于不包含任何不是这三种花之一的类别,因此算法永远不会将样本分类为这三种类别之外的任何类别。
我们首先需要确定要使用的逼近函数。由于花朵的测量值仅在一定范围内适合特定花朵类别,因此对于每个特征,逼近函数应该是二次多项式,例如:
为了训练,我准备了三个数据集。一个用于第一个类别,一个用于第二个,一个用于最后一个类别。
通过这些,我得到了以下参数:
鸢尾花 Versicolor
在132772次迭代后,成本为0.0166。
鸢尾花setosa
在5148次迭代后,成本为0.00046。
鸢尾花virginica
在8653次迭代后,成本为0.0116。
将这些参数实现到测试应用程序中,所有15个测试数据样本都被正确识别,平均概率为91%,并且每个训练结果的成本相对较小,这很棒。
反向传播
逻辑回归处理具有一个线性或多项式函数和一个触发器函数的逼近函数。反向传播处理一个复杂的函数网络,该网络包含不止一个触发器函数,以及其输入函数,该输入函数通常是前一层所有节点乘以线性因子的总和:一个神经网络。这个网络包含多个层:输入层(接收一个数据样本的特征),一个或多个隐藏层(包含逼近函数及其触发器),以及一个输出层(将结果传输到外部世界)。这构成了一个由多个节点组成的网络,通常,一层中的每个节点都连接到下一层的每个节点,并且每个连接代表一个输入函数给后续节点,每个节点(除了输入节点)都包含一个触发器函数。
反向传播主要用于逼近具有数字输出的更复杂函数。对于每个数据样本,它首先从左到右在网络中运行,计算一个样本的输出值。然后,它从右到左运行,并根据其输出的偏差计算网络中参数的校正。这两个过程称为前向传播和反向传播,它们对每个数据样本执行。在一个循环结束时,参数会通过所有这些校正的平均值进行校正,并且循环会重复,直到达到最小偏差。
(有关该算法的详细描述,请参见 http://www.mosismath.com/AI/BackPropagation.html 。)
使用反向传播处理鸢尾花数据集
为了处理鸢尾花数据集,我设置了神经网络如下:
具有四个输入,一个隐藏层和两个输出,以二进制形式输出花朵类别的编号,例如:
Iris-setosa => output 1 = 0 ; output 2 = 0
Iris-versicolor => output 1 = 1 ; output 2 = 0
Iris-virginica => output 1 = 1 ; output 2 = 1
基本上,可以使用一个输出并训练3个不同的设置。但反向传播算法在使用更多输出时效果更好。
有了这个设置,我可以一次处理整个数据集。我只需要相应地为训练设置两个输出。
有了这个设置,反向传播算法计算出值:
用
成本 = 0.0145854,固定迭代次数为60000次。
我将它们硬编码到测试应用程序中,所有15个测试样本都被正确识别,平均概率为98%。这比逻辑回归算法做得好一点。
支持向量机
支持向量机与上述算法不同。它不逼近函数,而是分类数据。在一个非常简单的例子中:如果有一个包含特征 x1, x2 和属性 y 的数据集,其中 y 是值 1
或 -1
,那么支持向量机试图在 y=1 的数据样本和 y=-1 的数据样本之间画一条线,例如:
在这个示例图像中,红点是 y=1 的点,蓝点是 y=-1 的点。黑线是分隔线。此外,还有两条灰色的边距线。这三条线应该这样放置,使得没有点落在边距线之间,并且边距线之间的距离尽可能大(向量 u-v 的长度)。好的,这是一个非常简单且不常见的例子。但支持向量机算法能够解决更复杂的任务。在多维情况下,它画的不是一条线,而是一个超平面来分隔样本。
原则上,支持向量机计算一个向量 W 和一个偏移量 b,使得对于每个数据样本:
一个常数 b 被加到属性 y 上,并乘以 W 和 x 的点积,其中 x 是所有输入特征的向量。
现在,情况通常比上面图片所示的要复杂。输入特征由多个维度组成,并且不能通过直线进行分隔。支持向量机算法可以处理多维情况,并且为了在虚拟上弯曲分隔线或超平面,使用了所谓的核技巧。
(有关该算法的详细描述,请参见 http://www.mosismath.com/AI/SMO.html 。)
有几种不同的方法来解决支持向量机的优化问题。我实现了John C. Platt的顺序最小优化算法。这是最简单的方法之一,而且效果很好。
使用支持向量机处理鸢尾花数据集
由于支持向量机在一对设置中将数据分为两类,因此任务必须分为两部分。首先,我想分类数据样本是否属于鸢尾花 Setosa 类别。如果不是,我想分类它是否属于鸢尾花 Versicolor 类别,如果不是,那么它属于鸢尾花 Virginica 类别。因此,我必须准备两个训练数据集。支持向量机需要属性 y 作为值1或-1。因此,对于第一个训练数据集,我必须为所有鸢尾花 Setosa 类别的样本设置属性=1,为所有其他样本设置属性=-1。第二个数据集仅包含鸢尾花 Versicolor 和鸢尾花 Virginica 的数据样本,并且所有鸢尾花 Versicolor 类别的样本都获得属性=1,其余所有样本的属性= -1。
由于训练可能会产生很多支持向量,因此我无法直接将它们从训练应用程序复制粘贴到测试应用程序。因此,它们通过一个 *.Json 文件传输。第一次分类在6次迭代后产生10个支持向量,第二次分类在15次迭代后产生38个支持向量。
有了这些参数,所有测试样本都被正确识别。这里没有概率可用。但分离质量的一个度量是 f(x) 的值。它不应该在 1
和 -1
之间。这是目标。但在大多数情况下,这可能无法实现。因此,如果值不太接近 0
,那也是可以接受的。测试应用程序找到三个值,大约在 -0.6
附近。这相当不错。 :-)
结论
所有三种算法的结果看起来相当简单明了。但这可能会产生误导。所有三种算法都以迭代过程开始于某个特定点来逼近其结果。它们在寻找一个函数的最小值。这个函数的复杂性并不完全相同,它们也并非一次就能找到最佳结果。起始参数的设置以及迭代参数的微调对所有算法来说都不是太简单。
梯度下降算法使用或多或少简单的逼近函数。但有些人认为梯度下降算法收敛速度不快,并且容易发生振荡。我可以说,通过稍微不同的实现,可以避免这种情况。根据文献,逼近函数的偏移量值与所有其他值在同一个循环中更新。这会相互影响,使算法容易发生振荡。如果单独处理偏移量,算法会收敛得快得多,并且似乎振荡得少得多(参见 http://www.mosismath.com/AI/LinregIterative.html)。这使得梯度下降算法成为许多问题的相当有吸引力的方法。
反向传播算法在机器学习中相当花哨。但它通常包含不止一个包含 Sigmoid 函数形式的触发器函数的节点。每个这样的节点都会增加逼近函数的复杂性和局部最小值。这意味着神经网络包含的节点越多,算法就越有可能陷入局部最小值而不是找到我们正在寻找的全局最小值。这使得设置最佳迭代起始点和找到全局最小值变得相当困难。这是触发器函数的输入函数通常只是前一个节点线性乘积的总和而不是多项式的主要原因。那样会给系统带来更多复杂性。反向传播是一个非常强大的算法,但它不是很容易运行。它需要大量的试错来确定起始点和设置触发器函数以找到所需的解。
支持向量机算法是一种相当复杂且智能的算法。但它的成功在很大程度上取决于所用核函数的正确选择和设置。如果算法没有经过良好的微调,它可能会输出大量的支持向量。因此,花一些时间来找到最佳设置总是值得的。对于鸢尾花数据,它收敛得非常快。并非总是如此。当有大量数据样本、许多输入特征以及复杂的核函数组合时,计算可能需要相当长的时间。
相互比较,梯度下降算法无疑是最简单的解决方案(我喜欢 :-))。但并非所有数据集都可以用梯度下降算法(或反向传播)所做的数学函数来逼近。而且并非所有数据集都可以用支持向量机来分类。因此,可能总会需要一些试错和微调。
所有这三种算法都不能简单地输入一些数据,运行并产生有用的结果。它们都需要用户的关注。但这正是使人工智能领域引人入胜的地方。在人工智能开始之前,总会需要一些人类的智慧。 :-)
本文已被翻译成中文并发布在CSDN软件开发网。参见:
https://blog.csdn.net/mzl87/article/details/107126598#%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D
我对此表示赞赏,并非常感谢那位好心的中国同行 :-)
关于最大似然估计的进一步阅读
http://www.mosismath.com/AI/MaxLoglikelihood.html
或
http://www.mosismath.com/AI/BackPropagationMaxLog.html
可能很有趣 :-)
历史
- 2020 年 5 月 1 日:初始版本