ITPub博客

首页 > 人工智能 > 机器学习 > 从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究

原创 机器学习 作者:李佳惠 时间:2018-10-09 09:47:33 0 删除 编辑

写一个机器学习算法是一次非常有意义的学习经历(https://www.dataoptimal.com/machine-learning-from-scratch/)。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


它为你提供了"啊哈!原来是这样"的经历感受。只有你点击它的时候,你才会明白究竟发生了什么。

有些算法比其他算法复杂,所以我们从一些简单的开始,例如单层感知器(https://en.wikipedia.org/wiki/Perceptron)。

我将向你介绍以下6步过程,从零开始编写算法,使用感知器作为案例研究:

1.对算法有基本的了解

2.寻找不同的学习来源

3.将算法分解为块

4.从一个简单的例子开始

5.使用确信的案例进行验证

6.写下你探索的过程

基本了解

这可以追溯到我最初所说的。如果你不了解基本知识,就不要从头开始处理算法。

至少,你应该能够回答以下问题:

它是什么?

它通常用于什么?

我什么时候不能用这个?

对于感知器,让我们继续回答以下问题:

单层感知器是最基本的神经网络。它通常用于二进制分类问题(1或0,"是"或"否")。

一些简单的用途可能是情绪分析(正面或负面反应)或贷款违约预测("将违约"、"不会违约")。对于这两种情况,决策边界都需要是线性的。

如果决策边界是非线性的,那么你不能使用(单层)感知器。对于非线性问题,你需要的是其他东西。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


使用不同的学习来源

在你对模型有了基本的理解之后,就该开始做你的研究了。

有些人通过书本学得更好,有些人通过视频学得更好。

就我个人而言,我喜欢两者合用和使用各种资源。

关于数学细节,教科书做得很好(https://www.dataoptimal.com/data-science-books-2018/),但是对于更多的实际例子,我更喜欢博客文章和YouTube视频。

这里有一些很好的学习资源:

书籍方面

统计学习的要素(SEC)。4.5.1 链接:https://web.stanford.edu/~hastie/Papers/ESLII.pdf

理解机器学习:从理论到算法(SEC)。21.4 链接:https://www.cs.huji.ac.il/~shais/UnderstandingMachineLearning/understanding-machine-learning-theory-algorithms.pdf

博客

如何在Python中从无到有地实现感知器算法。作者:Jason Brownlee 链接:https://machinelearningmastery.com/implement-perceptron-algorithm-scratch-python/

单层神经网络与梯度下降。作者:Sebastian Raschka 链接:https://sebastianraschka.com/Articles/2015_singlelayer_neurons.html

视频

感知器训练(https://www.youtube.com/watch?v=5g0TPrxKK6o)。

感知器算法的工作原理(https://www.youtube.com/watch?v=1XkjVl-j8MM)。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


将算法分解为块

既然我们已经收集了我们的资料,现在是开始学习的时候了。

与其一路上阅读文章或博客,不如从浏览章节标题和其他重要信息开始。

然后写下要点,并试图勾勒出算法。

在查看了众多资料后,我将感知器算法分解为以下5块:

1.初始化权重

2.按输入乘以权重,并将它们加起来

3.将结果与阈值进行比较以计算输出(1或0)

4.更新权重

5.重复

让我们把每一个细节都看一遍。

1.初始化权重

首先,我们将初始化权重向量。

权重的数量需要与特征的数量相匹配。假设我们有三个特性,下面是权重向量的样子

权重向量通常是用零初始化,所以我将继续在这个例子中坚持我的理念。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


2.将权值乘以输入,并将它们加起来。

接下来,我们将把权重乘以输入,然后把它们加起来。

为了便于跟踪,我在第一行中对权重和它们的相应特性进行了着色。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


在我们把权重乘以特征后,我们把它们加起来。这也被称为点积。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


最终结果是0。我将这个临时结果称为"f"。

3.与阈值比较

在计算了点积之后,我们需要将它与阈值进行比较。

我选择了使用0作为我的阈值,但是你可以使用这个,或尝试一些不同的数字。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


由于我们计算的点积"f"不大于我们的阈值(0),所以我们的估计等于零。

我将估计值表示为"y hat",带有0下标,以对应于第一行。你可以用1代替第一行,但这并不重要。我只是选择从0开始。

如果我们将这一结果与实际值进行比较,我们可以看到,我们当前的权重并没有做出正确的预测。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


由于我们的预测是错误的,我们需要更新权重,这就把我们带到了下一步。

4.更新权重

接下来,我们将更新权重。下面是我们将要使用的公式:

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


基本思想是在迭代"n"时调整当前的权重,以便在下一次迭代中使用新的权重,"n+1"。

为了调整权重,我们需要设定一个"学习速率"。这是用希腊字母"ETA"表示的。

我选择使用0.1作为学习速率,但是你可以使用不同的数字,就像阈值一样。

以下是我们到目前为止所做的简要总结:

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


现在让我们继续计算迭代n=2的新权重。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


我们成功地完成了感知器算法的第一次迭代。

5.重复

因为我们的算法没有计算出正确的输出,所以我们需要继续下去。

通常,我们需要多次迭代。循环遍历数据集中的每一行,我们将每次更新权重。

一个完整的扫描数据集被称为"epoch"(轮回)。

因为我们的数据集有3行,所以我们需要三次迭代才能完成一个"epoch"。

我们可以设置总迭代次数或时间来继续执行该算法。也许我们需要指定30次迭代(或10次迭代)。

与阈值和学习速率一样,epoch数(即轮回数)是你可以使用的参数。

在下一次迭代中,我们继续讨论第二行的特性。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


我不会重复每一步,但下面是点积的新计算:

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


接下来,我们将点积与阈值进行比较,以计算一个新的估计值,更新权重,然后继续进行。如果我们的数据是线性可分的,感知器就会收敛。

从一个简单的例子开始

现在我们已经手工将算法分解成块,现在是开始在代码中实现它的时候了。

为了保持简单,我总是喜欢从一个非常小的数据集开始。

这类问题的一个很好的、小的、线性可分离的数据集是NAND gate(https://en.wikipedia.org/wiki/NAND_gate)。这是数字电子学中常用的一个数据集。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


由于这是一个相当小的数据集,我们只需手动将其输入Python。

我将添加一个虚拟特性"X0",这是一个1的列。我这样做是为了让我们的模型计算偏置项。

你可以将偏差看作是截取项,它正确地允许我们的模型分离这两个类。

以下是输入数据的代码:

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


与上一节一样,我将以块的形式逐步完成算法,编写代码,并在我们进行测试时对其进行测试。

1.初始化权重

第一步是初始化权重。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


请记住,权重向量的长度需要匹配特征的数量。对于这个NAND gate例子,长度是3。

2.将权值乘以输入,并将它们加起来。

接下来,我们将把权重乘以输入,然后把它们加起来。

它的另一个名字是"点积"。

同样,我们可以使用Numpy轻松地执行此操作。我们将使用的方法是.dot()。

让我们从权向量和第一行特征的点积开始。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


正如预期的那样,结果是0。

为了与前文保持一致,我将点积赋给变量f。

3.与阈值比较

在计算了点积之后,我们准备将结果与阈值进行比较,从而对输出进行预测。

同样,我将保持与前文一致。

我要让临界值z等于0。如果点积f大于0,我们的预测是1。否则,它就是0。

记住,这个预测通常是用"carat"的顶部来表示的,也被称为"hat"。我将预测赋给的变量是"yhat"。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


正如预期的那样,预测为0。

你会注意到,在上面的注释中,我称之为"激活函数"。这是对我们正在做的事情的更正式的描述。

查看NAND输出的第一行,我们可以看到实际值为1。既然我们的预测是错误的,我们就需要继续更新权重。

4.更新权重

既然我们已经做出了预测,我们就可以更新权重了。

我们需要设定一个学习速率才能做到这一点。为了与前面的示例保持一致,我将为学习率"ETA"赋值0.1。

我将对每个权重的更新进行编码,以便更容易阅读。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


我们可以看到,我们的权重现在已经更新,所以我们准备继续前进。

5.重复

现在我们已经完成了每一步,现在是时候把所有的东西都放在一起了。

我们还没有讨论的最后一个部分是损失函数。这是我们试图最小化的函数,在我们的例子中,这将是平方和的错误。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


这就是我们用来计算错误的地方,看看模型是如何运行的。

将所有内容结合在一起,下面是整个函数的样子:

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


现在我们已经编写了完整的感知器,让我们继续运行它:

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


看一看错误,我们可以看到,在第6次迭代时,错误变为0。对于其余的迭代,它保持在0。

当误差达到0并停留在那里时,我们知道我们的模型已经收敛了。这告诉我们,我们的模型已经正确地"学习"了适当的权重。

在下一节中,我们将在更大的数据上使用计算的权重做预测。

使用确信的案例进行验证

到目前为止,我们已经找到了不同的学习资源,手工完成了算法,并用一个简单的例子在代码中测试了它。

现在是时候将我们的结果与可信的实现进行比较了。为了比较,我们将使用scikit-learn中的感知器(http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html)。

我们将使用以下步骤完成此比较:

1.导入数据

2.将数据分割成训练/测试组

3.训练我们的感知器

4.测试感知器

5.与scikit-learn中的感知器进行比较

1.导入数据

让我们从导入数据开始。你可以获得数据集链接为:https://github.com/dataoptimal/posts/blob/master/algorithms%20from%20scratch/dataset.csv 。

这是一个线性可分离的数据集,我创建它是为了确保感知器能够工作。为了进一步的工作,让我们继续绘制数据。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


看一下这幅图,很容易看出我们可以用一条直线将这些数据分开。

在我们继续之前,我将解释我上面的代码。

我使用Pandas导入CSV,CSV自动将数据放入dataframe中。

要绘制数据,我必须从dataframe中提取值,这就是为什么我使用".values"方法。

特性在第1和第2列中,所以我在散点图函数中使用了这些特性。第0列是我包含的1的虚拟特性,这样就能计算出截距。这与我们在上文中对NAND gate所做的事情一样。

最后,我使用C=df['3'],alpha=0.8在散射图函数中。输出是第3列(0或1)中的数据,因此我"告诉"函数使用'3'列对这两个类进行着色。

如果你想找到更多关于Matplotlib的散点图函数,请点击:https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html 。

2.将数据分割成训练/测试组

现在,我们已经确认数据可以线性分离,是时候将数据拆分了。

在一个独立的数据集上训练一个模型,而不是你测试的数据集,这是一个很好的实践。这有助于避免过度拟合。

做这件事有不同的方法,但是为了保持简单,我只使用一个训练集和一个测试集。

我将从整理我的数据开始。如果你查看原始文件,你将看到数据按行分组,输出为0(第三列),然后是所有的1。我想要改变事物,增加一些随机性,所以我现在要打乱数据。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


我首先将数据从dataframe更改为numpy数组。这使我将要使用的许多numpy函数更容易使用,例如.shuffle(即打乱或洗牌)。

为了使结果可重复,我设置了一个随机数种子(5)。在我们完成之后,尝试改变随机数种子,看看结果是如何变化的。

接下来,我将70%的数据分成训练集,30%的数据分成测试集。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


最后一步是分离训练和测试集的特性和输出。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


为了这个例子,我选择了70%的训练集和30%的测试集,但我鼓励你研究其他方法,例如K折交叉验证(https://en.wikipedia.org/wiki/Cross-validation_%28statistics%29)。

3.训练我们的感知器

接下来,我们将训练我们的感知器。

这很简单,我们将重用我们在前文构建的代码。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


让我们继续看一看权重与平方误差之和。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


现在这些权值对我们来说并不重要,但是我们将在后面使用这些数字来测试我们的感知器。我们还将使用它将我们的模型与scikit-learn模型进行比较。

看一下平方误差之和,我们可以看到我们的感知器已经收敛了,这是我们所期望的,因为数据是线性可分的。

4.测试我们的感知器

现在是时候测试我们的感知器了。为了做到这一点,我们将建造一个小的感知器测试函数。

这和我们已经看到的很相似。这个函数取我们使用perceptron_train函数计算的权值的点积,以及特征,以及激活函数,来进行预测。

我们唯一没有看到的是accuracy_score。这是一个来自scikit-learn的评价度量函数。你可以在这里了解更多。

把所有这些放在一起,下面是代码:

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


得分为1.0表明我们的模型正确地预测了所有的测试数据。这个数据集显然是可分离的,所以我们期望这个结果。

5.与scikit-learn感知器相比

最后一步是将我们的结果与scikit-learn的感知器进行比较。下面是这个模型的代码:

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


现在我们已经训练了模型,让我们比较权重和我们的模型计算的权重。

从零开始编写任意机器学习算法的6个步骤:关于感知器案例的研究


scikit-learn模型中的权重与我们的相同。这意味着我们的模型工作正常,这是个好消息。

在我们结束之前,有几个小问题需要复习一下。在scikit-learn模型中,我们必须将随机状态设置为"None"并关闭洗牌。因为我们已经设置了一个随机数种子并打乱了数据,所以我们不需要再这样做了。

我们还必须将学习速率"eta0"设置为0.1,以与我们的模型相同。

最后一点是截距。因为我们已经包含了一个虚拟的特性列1s,我们正在自动拟合截距,所以我们不需要在scikit-learn感知器中打开它。

这些看起来都是次要的细节,但如果我们不设置这些,我们就无法复制与我们的模型相同的结果。

这一点很重要。在使用模型之前,阅读文档并理解所有不同设置的作用是非常重要的。

写下你的过程

这个过程中的最后一步可能是最重要的。

你已经完成了所有的工作,包括学习、记笔记、从头开始编写算法,并将其与确信的案例进行比较。不要让前期准备白白浪费掉!

写下这个过程很重要,原因有二:

1.你会得到更深的理解,因为你正在教导别人你刚刚学到的东西。

2.你可以向潜在雇主展示它。

证明的天赋与能力,但如果你可以自己从头实现它,那就更令人印象深刻了。

一个展示你作品的好方法是使用GitHub页面组合(https://www.youtube.com/watch?v=qWrcgHwSG8M)。

结语

在这篇文章中,我们学习了如何实现从零开始编写机器学习算法(https://www.dataoptimal.com/machine-learning-from-scratch/)。

更重要的是,我们学会了如何找到有用的学习资源,以及如何将算法分解成块。

然后,我们学习了如何使用较小数据集在代码中训练和测试算法。

最后,我们将模型的结果与可信的案例进行了比较。

这是一个很好的方法,我们可以在更深层次上了解、学习算法,这样你就可以自己实现它。

大多数情况下,你使用的算法都是准确无误的,但是如果你真的想更深入地了解幕后的情况,从头开始学习它是一个很好的练习!


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31545819/viewspace-2215637/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-09-19

  • 博文量
    104
  • 访问量
    186455