从零开始实现机器学习算法似乎是程序员理解机器学习的好方法。
也许确实如此。
但这种方法也有一些缺点。
在这篇文章中,您将发现一些很棒的资源,可以用来从零开始实现机器学习算法。
您还将发现这种看似完美的方法的一些局限性。
通过我的新书《从零开始的机器学习算法》<强>启动您的项目,包括分步教程和所有示例的Python源代码文件。
您是否曾为了学习而从零开始实现机器学习算法?请留下评论,我很想听听您的经验。

从零开始实现机器学习算法!
照片由Tambako The Jaguar提供,保留部分权利。
从零开始实现机器学习算法的好处
我提倡从零开始实现机器学习算法。
我认为你可以从中了解到很多关于算法如何工作的信息。我还认为,作为一名开发人员,它为学习机器学习中使用的数学符号、描述和直觉提供了一座桥梁。
我之前在文章《从零开始实现机器学习算法的好处》中讨论过从零开始实现算法的好处。
在那篇文章中,我列出的好处包括:
- 您获得的理解
- 它提供的起点
- 它强加的算法和代码的所有权
在那篇文章中,我还评论了如何通过利用现有教程和书籍来缩短这个过程。有很多很好的资源可以帮助您入门,但也有一些需要注意的绊脚石。
在下一节中,我将指出三本您可以用来从零开始实现机器学习算法的书籍。
在过去几年里,我帮助许多程序员入门机器学习。根据我的经验,我列出了我看到程序员最常遇到的5个绊脚石,以及您可以用来克服它们的策略。
最后,您将发现3个快速技巧,帮助您从代码教程中获得最大收益,并从复制粘贴的程序员(如果您碰巧是)真正深入到机器学习算法的兔子洞中。
获取您的免费算法思维导图

方便的机器学习算法思维导图样本。
我创建了一份方便的思维导图,其中包含60多种按类型组织的算法。
下载、打印并使用它。
还可以独家访问机器学习算法电子邮件迷你课程。
您可以用来实现算法的好书
我曾直接从研究论文中从零开始实现过许多算法。这可能非常困难。
从别人的教程开始,会容易得多。
有许多优秀的资源可供您从零开始实现机器学习算法。
也许最权威的是指导您完成教程的书籍。
从一本书开始有很多好处。例如:
- 有人已经搞清楚了算法以及如何将其转化为代码。
- 您可以将其用作一个已知的有效起点,用于修改和实验。
一些指导您逐步实现机器学习算法的优秀书籍包括:
Joel Grus的《从零开始的数据科学:Python第一原理》
这确实是从零开始,涵盖了可视化、统计、概率、数据处理,然后是大约12种不同的机器学习算法。
这是我今年最喜欢的初学者机器学习书籍之一。
Stephen Marsland的《机器学习:算法视角》
这是这本畅销书期待已久的第二版。它涵盖了大量的多样化机器学习算法及其实现。
我喜欢它混合了数学描述、伪代码和可工作的源代码。
Peter Harrington的《机器学习实战》
这本书通过10种最流行的机器学习算法,提供案例研究问题和Python中的工作代码示例。
我喜欢它在代码和描述之间做了很好的努力,通过编号和箭头将它们联系起来。
我是否遗漏了一本提供从零开始实现机器学习算法编程教程的好书?
请在评论中告诉我。
从零开始实现算法时的5个绊脚石(以及如何克服它们)
使用教程从零开始实现机器学习算法非常有趣。
但可能会遇到绊脚石,如果您不小心,它们可能会让您摔倒并扼杀您的动力。
在本节中,我想指出我看到的最常见的5个绊脚石,以及如何应对它们,不让它们阻碍您。我希望您能摆脱困境,继续前进(或者转向另一个教程)。
避免以下绊脚石的一些好的通用建议是,在深入学习教程之前,仔细查看书籍的评论(或博客文章的评论)。您要确保代码有效,并且您没有浪费时间。
另一个通用的策略是无论如何都要深入研究,找出不起作用的部分,并自己重新实现它们。这是一个很好的技巧,可以强迫理解,但它可能不适合初学者,并且您可能需要一份好的技术参考随时在手。
无论如何,让我们深入探讨从零开始的机器学习教程中常见的5个绊脚石
1) 代码无法工作
最糟糕、也许也是最常见的绊脚石是示例中的代码无法工作。
事实上,如果您花一些时间在亚马逊上查看某些书籍的评论或大型博客文章的评论,很明显,这个问题比您想象的更为普遍。
这怎么会发生?有几个原因可能会给您一些线索,帮助您应用自己的修复并继续前进:
- 代码从未工作过。这意味着这本书在出版时没有经过仔细的编辑。除了试图揣摩作者的意图并弄清楚他们想表达什么之外,您也无能为力。甚至可以尝试联系作者或出版商。
- 语言已经过时。这种情况可能会发生,特别是如果帖子很旧或这本书已经出版了很长时间。两个很好的例子是Ruby版本从1.x升级到2.x,以及Python从2.x升级到3.x。
- 第三方库已更新。这适用于那些实现并非完全从零开始,而是使用了一些实用库(例如用于绘图)的情况。这种情况通常没有那么糟糕。您通常只需要更新代码以使用最新版本的库,并修改参数以适应API更改。甚至可能安装旧版本的库(如果您的开发环境中几乎没有或没有依赖项可能被破坏)。
- 数据集已更改。如果数据文件是一个URL并且不再可用(也许您可以在其他地方找到该文件),则可能会发生这种情况。如果示例是针对第三方API数据源(如Facebook或Twitter)编写的,则情况会更糟。这些API可能会频繁且快速地更改。最好的办法是了解API的最新版本,并尽可能修改代码示例。
如果代码不起作用,一个好的通用策略是寻找相关的勘误表(如果是书籍)、GitHub存储库、代码下载或类似内容。有时问题已经解决,并在书籍或作者的网站上提供。简单的谷歌搜索应该能找到它。

从零开始编写机器学习算法。照片由Tambako The Jaguar提供,保留部分权利
2) 代码描述不清
我认为从零开始实现算法时,第二糟糕的绊脚石是代码附带的描述很差。
这类问题对初学者来说尤其不利,因为您正在尽最大努力保持动力,并从练习中真正学到东西。如果代码和文本不一致,所有这些都会化为泡影。
我(也许是好意地)称它们为“糟糕的描述”,因为可能有很多症状和原因。例如:
- 代码与描述不匹配。这可能是由于代码和文本在不同时间准备,并且没有正确地编辑在一起。它可能是一个小问题,比如变量名更改,也可能是整个函数名或函数本身的问题。
- 缺少解释。有时您会得到大段代码,却期望您自行理解。这令人沮丧,尤其是在一本书中,一页又一页的代码,在屏幕上阅读会更容易理解。如果出现这种情况,您最好找到代码的在线下载并直接使用它。
- 解释过于简洁。有时您会得到代码的解释,但它们过于简短,比如“使用信息增益”等等。令人沮丧!您可能仍然有足够的信息来研究该术语,但如果作者在上下文中包含了与示例相关的解释,那会容易得多。
一个好的通用策略是查阅其他资源中算法的描述,并尝试将其映射到您正在使用的代码上。本质上,尝试为代码构建自己的描述。
这可能不适合初学者,您可能需要转向其他资源。
3) 代码不符合习惯用法
我们程序员在“正确”使用我们的语言(例如Python代码不Pythonic)方面可能会很教条。这是一件好事,它表明了对细节和最佳实践的关注。
当示例代码不符合其编写语言的习惯用法时,可能会令人反感。有时它会如此分散注意力,以至于代码难以阅读。
这种情况可能有多种原因,例如:
- 从其他语言移植。示例代码可能是从其他编程语言移植过来的。例如,Java中的FORTRAN或Python中的C。对于训练有素的眼睛来说,这可能很明显。
- 作者正在学习该语言。有时作者可能会利用书籍或教程项目来学习一门语言。这可能会在整个代码示例中表现出不一致性。当示例冗长,对语言特性和API使用不当时,这可能会令人沮丧甚至分散注意力。
- 作者没有专业使用过该语言。这更难发现,可能表现为使用了晦涩的语言特性和API。当您不得不研究或解码奇怪的代码时,这可能会令人困惑。
如果惯用代码对您来说非常重要,那么这些绊脚石可能是一个机会。您可以将代码从“Java-Python”混合体(或其他)移植到纯Pythonic实现。
通过这样做,您将对算法获得更深入的理解,并对代码拥有更多所有权。
4) 代码与数学不关联
一个好的代码示例或教程将提供从数学描述到代码的桥梁。
这很重要,因为它允许您跨越并开始对符号和简洁的数学描述建立直觉。
问题是,有时这座桥梁可能会断裂或完全缺失。
- 数学错误。 对于已经努力将数学与代码联系起来的初学者来说,这是一种隐蔽的危害。不正确的数学可能会误导,甚至更糟,会消耗大量时间而没有任何回报。知道这种情况可能发生是一个好的开始。
- 简洁的数学描述。公式可能散布在示例代码周围,让您自行弄清楚它是什么以及它如何与代码相关联。您几乎没有选择,您可以将其视为一个无数学示例,并参考另一个更完整的参考文本,或者您可以努力将数学与代码自行关联起来。这更可能发生在不熟悉算法数学描述的作者身上,他们似乎只是事后才将其插入。
- 缺少数学。有些参考文献在设计上是无数学的。在这种情况下,您可能需要找到自己的参考文本并自行搭建桥梁。这可能不适合初学者,但这是一项值得投入时间培养的技能。
初学者可能希望坚持使用代码而忽略数学,以建立信心和动力。稍后,投入高质量的参考文本并开始将代码与数学关联起来将是值得的。
您希望擅长将代数与标准代码结构联系起来,并对所涉及的过程建立直觉。这是一种应用技能。您需要付出努力和练习。
5) 不完整的代码列表
我们在第2点看到,您可以没有描述,只有长长的代码列表。这个问题可以反过来,即您没有足够的代码。这就是代码列表不完整的情况。
我非常相信完整的代码列表。我认为代码列表应该为您提供进行“完整”和可工作的实现所需的一切,即使它是最简单的情况。
您可以在简单案例的基础上构建,但无法运行不完整的示例。您必须付出努力并将其全部连接起来。
导致这种绊脚石的一些原因如下:
- 详细的描述。冗长的文字可能是思维不完整的迹象。不总是,但有时。如果某些东西没有被很好地理解,可能会隐晦地试图用一堆文字来掩盖它。如果根本没有代码,您可以将其视为一个挑战,从描述中设计算法,并从其他描述和资源中证实它。
- 代码片段。概念可能被详细描述,然后用一个小的代码片段来演示。这有助于将概念与代码片段紧密联系起来,但这需要您付出大量工作才能将其全部整合到一个工作系统中。
- 没有示例输出。代码示例中经常缺少的一个关键方面是示例输出。如果存在,这可以给您一个明确的预期,当您运行它时会发生什么。如果没有示例输出,那完全是猜测。
在某些情况下,不得不自己将代码组合起来可能会带来有趣的挑战。同样,这不适合初学者,但一旦您掌握了一些算法,这可能是一个有趣的练习。
从算法实现中获得最大收益的3个技巧
您可能会实现相当多的算法。一旦您完成了几个,您可能会再做几个,不知不觉中,您已经构建了自己的算法库,并且对它们了如指掌。
在本节中,我想给您3个快速技巧,您可以利用它们来最大限度地利用您实现机器学习算法的经验。
- 添加高级功能。以您现有的工作代码示例为基础进行扩展。如果教程足够好,它会列出一些扩展的思路。如果没有,您可以自己研究一些。列出一些候选的算法扩展,然后逐一实现它们。这将迫使您至少理解代码,以便进行修改。
- 适应其他问题。在不同的数据集上运行算法。如果出现问题,请修复它们。进一步将实现适应不同的问题。如果代码示例是二分类,则将其更新为多分类或回归。
- 可视化算法行为。我发现实时绘制算法性能和行为是一个非常有价值的学习工具,即使在今天也是如此。您可以从在epoch级别(所有算法在某种程度上都是迭代的)绘制测试和训练数据集的准确性开始。然后,您可以选择算法特定的可视化,例如自组织图的2D网格、回归中时间序列的系数,以及k-近邻算法的Voronoi镶嵌。
我认为这些技巧将使您比教程和代码示例走得更远。
尤其是最后一点,它将为您提供对算法行为的深刻见解,而很少有实践者会花时间去获取这些见解。
您的行动步骤
这是一篇很长的文章,您已经了解了如何从零开始实现机器学习算法以获得最大收益。
重要的是,您已经了解了最常见的绊脚石,它们可能产生的一些框架,以及您可以用来将它们转化为机遇的一些策略。
您的下一步显而易见:开始从零开始实现算法。
不确定从何开始?
从这里开始,我有一个温和的教程,教您如何用Python从零开始实现k-近邻算法。
仍然不确定?
买一本《从零开始的数据科学:Python第一原理》。您不会后悔的。
分享您的经验
留下评论,告诉我您从零开始实现机器学习算法的经验。
读得很棒,我完全同意你的看法,实现算法绝对是一种很棒的学习体验!我总是倾向于说:知识是通过学习获得的,关键是我们的热情,但真正的技能掌握只能通过实践来实现。
但自己实现算法还有一些额外的、重要的动机
1) 您想要尝试添加“新颖”的调整或添加现有“现成”实现中没有的功能。简单但真实的例子:动量学习、衰减常数、正则化等。
2) 优化代码。虽然我们知道唐的伟大建议“过早优化是万恶之源”,但有时我们确实会想要/需要考虑计算效率。例如,作为一名Python开发者,我非常喜欢scikit-learn,但有时充分利用您的硬件(例如GPU)并使用Theano等工具实现算法会带来好处。
3) 您对 API 及其实现方式不满意
4) 您想将其移植到您最喜欢的环境中,以便在您的更大系统中使用该“功能”
……还有很多😉
谢谢您的建议。我目前正在尝试在scikit库中实现一些集成方法。我主要是在相关的文章中处理不完整的伪代码,以及我缺乏编程技能(我不是开发者背景出身……)。我会尝试应用您的方法论😉
我刚刚意识到,我可能一直在创建和实现机器学习而没有意识到!
几年前,我设计并开发了一个圆形键盘(在Google Play上搜索“圆形键盘”,并选择名为“Circkey”的那个)。
首先,我意识到我需要一个规则来实现我的设计,该规则规定每个键将包含3个字母。当选中时,这三个字母将作为单独的键呈现给用户,允许用户选择所需的字母。一旦选择,该字母就会显示在屏幕上。
其次,我意识到我需要一个规则来确定这个字母是否打算构成一个单词或单词的一部分。如果选择了“空格”键,代码将搜索超过35000个单词的文本文件,这些文件被分成单独的文件,每个文件包含以特定字母开头的单词,例如,一个文件包含所有以字母“a”开头的单词,依此类推。这条第二条规则还需要指定,如果单词是句子中第一个单词的第一个字母,则将其大写。
第三,每次选择新字母时,程序都会执行一次排序,以查找所有目前已选择的字母开头的可能单词。
每当剩下 2 个可能的单词时,只会向用户呈现接下来的 2 个可能的字母——这足以区分哪个单词是意图。
每当只剩下一个可能的单词时,该单词会立即显示,用户无需从单个字母中选择。
这听起来不像机器学习,例如,没有从数据中学习模型并将其泛化到新数据。
Java 是一个古老而又很棒的职业入门平台。看来您对 Java 做了很好的研究。
感谢发帖
很高兴它有帮助。