人工智能算法 卷1 基础算法

978-7-115-52340-2
作者: [美] 杰弗瑞·希顿(Jeffery Heaton)
译者: 李尔超
编辑: 陈冀康

图书目录:

详情

算法是人工智能技术的核心。本书介绍了人工智能的基础算法,全 书共10 章,涉及维度法、距离度量算法、K 均值聚类算法、误差计算、 爬山算法、模拟退火算法、Nelder-Mead 算法和线性回归算法等。书中 所有算法均配以具体的数值计算来进行讲解,读者可以自行尝试。每章 都配有程序示例,GitHub 上有多种语言版本的示例代码可供下载。 本书适合作为人工智能入门读者以及对人工智能算法感兴趣的读者 阅读参考。

图书摘要

版权信息

书名:人工智能算法(卷1):基础算法

ISBN:978-7-115-52340-2

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    [美] 杰弗瑞·希顿(Jeffery Heaton)

译    李尔超

责任编辑 陈冀康

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315


Simplified Chinese translation copyright ©2020 by Posts and Telecommunications Press.

ALL RIGHTS RESERVED.

Artificial Intelligence for Humans, Volume 1:Fundamental Algorithms by Jeffery Heaton

Copyright © 2019 Jeffery Heaton.

本书中文简体版由作者Jeffery Heaton授权人民邮电出版社出版。未经出版者书面许可,对本书的任何部分不得以任何方式或任何手段复制和传播。

版权所有,侵权必究。


算法是人工智能技术的核心。本书介绍了人工智能的基础算法,全书共10章,涉及维度法、距离度量算法、K均值聚类算法、误差计算、爬山算法、模拟退火算法、Nelder-Mead算法和线性回归算法等。书中所有算法均配以具体的数值计算来进行讲解,读者可以自行尝试。每章都配有程序示例,GitHub上有多种语言版本的示例代码可供下载。

本书适合作为人工智能入门读者以及对人工智能算法感兴趣的读者阅读参考。


人工智能(Artificial Intelligence,AI)是一个覆盖许多下级学科的宽泛领域,本系列图书涵盖了当中的部分特定主题,而本书则是系列书的第1卷。接下来几小节将会对本系列图书和本卷一一进行介绍。

本系列图书将向读者介绍人工智能领域的各种热门主题。由于人工智能是一个庞大而繁杂的领域,并且其涵盖的内容与日俱增,任何一本书都只可能专注于特定领域,因此本书也无意成为一本巨细靡遗的人工智能教程。

本系列图书以一种数学上易于理解的方式讲授人工智能相关概念,这也是本系列图书英文书名中“for Human”的含义。此外:

本系列图书的目标读者是精通至少一门编程语言的程序员,且书中示例均已改写为多种编程语言的形式。

编程语言

本书中只是给出了伪代码,而具体示例代码则以Java、C#、R、C/C++和Python等语言形式提供,此外还有社区支持维护的Scala语言版本。社区成员们正在努力将示例代码转换为更多其他的编程语言,说不定当你拿到本书的时候,你喜欢的编程语言也有了相应的示例代码。访问本书的GitHub开源仓库可以获取更多信息,同时我们也鼓励社区协作来帮我们完成代码改写和移植工作。如果你也希望加入协作,我们将不胜感激。更多相关流程信息可以参见本书附录A。

在线实验环境

所有的线上实验环境资料均可在以下网址中找到:

http://www.aifh.org

这些在线环境使你就算是在移动设备上阅读电子书时也能尝试各种示例。

代码仓库

本系列图书中的所有代码均基于开源许可证Apache 2.0发布,相关内容可以在以下GitHub开源库中获取:

https://github.com/jeffheaton/aifh

附带JavaScript实验环境示例的在线实验环境则保存在以下GitHub开源库中:

https://github.com/jeffheaton/aifh-html[1]

如果你发现有任何疏漏抑或不妥之处,欢迎在GitHub上分叉项目并推送提交来进行修订,你也将可以成为日益壮大的贡献者群体之一。更多关于贡献代码的信息请参见本书附录A。

本系列图书的写作计划:

卷1~卷5将会依次出版;而卷0则会作为“提前计划好的前传”,在本系列图书的出版接近尾声之际完成。卷1~卷5会讲解必要的数学概念,卷0则会专注于对这些概念进行回顾,并在此基础上进行一定的拓展。

卷0既可以是阅读本系列图书的开端,也可以作为本系列图书的总结;卷1的阅读顺序最好在后续几卷之前;卷2的部分内容对读者理解卷3的内容又有所助益。图1展示了我们建议的合理的阅读顺序。

本系列图书的每一卷均可独立阅读,也可作为本系列图书整体阅读。但需要注意的是,卷1中列出了后续各卷所使用的各种基本算法,并且这些算法本身既是基础,也不失实用性。

图1 卷目阅读流程

其他资源

当你在阅读本书的时候,互联网上还有很多别的资源可以帮助到你。

首先是可汗学院,上面收集整理了许多讲授各种数学概念的YouTube视频。你要是需要复习某个概念,可汗学院上很可能就有你需要的视频讲解,读者可以自行查找。

其次是网站“神经网络常见问答”。作为一个纯文本资源,上面拥有大量神经网络和其他人工智能领域的相关信息:

http://www.faqs.org/faqs/ai-faq/neural-nets/

此外,Encog项目的wiki页面也有许多机器学习方面的内容,并且这些内容并不局限于Encog项目:

http://www.heatonresearch.com/wiki/Main_Page

最后,Encog的论坛上也可以讨论人工智能和神经网络相关话题,这些论坛都非常活跃,你的问题很可能会得到某个社区成员甚至是我本人的回复:

http://www.heatonresearch.com/forum

欲建高楼,必重基础。本书会讲授诸如维度法、距离度量算法、聚类算法、误差计算、爬山算法、线性回归和离散学习这样的人工智能算法。这些算法对应于数据中特定模式的处理和识别,同时也是亚马逊(Amazon)和网飞(Netflix)这类网站中,各种推荐系统背后的逻辑。

这些算法不仅是后续各卷所介绍的算法的基础,其本身也大有用处。在本书中,这些算法的讲解均附以可操作性强的数值计算示例。

第1章“AI入门”,介绍了本书或本系列图书其他各卷中会用到的部分人工智能相关的基本概念。大多数人工智能算法是接受一个输入数组,从而产生一个输出数组—人工智能所能解决的问题通常被归化为此类模型。而在算法模型内部,还需要有额外的数组来存储长短期记忆。算法的训练实际上就是通过调整长期记忆的值来产生对应于给定输入的预期输出的一个过程。

第2章“数据归一化”,描述了大多数人工智能算法对原始数据的预处理流程。数据需要以一个输入数组的形式传递给算法,但实践中获取到的数据并不一定都是数值型的,也有一些是类别信息,比如颜色、形状、性别、物种抑或其他一些非数值型的描述性特征。此外,就算是现成的数值型数据,也必须在一定范围内归一化,并且通常是归一化到 (-1, 1) 区间。

第3章“距离度量”,展示了我们比较数据的方法,说起来这种比较方法其实跟在地图上标识出两点间的距离十分相像。人工智能通常以数值数组的形式处理数据,包括输入数据、输出数据、长期记忆、短期记忆和其他很多数据都是如此,这些数组很多时候也被称作“向量”。我们可以像计算两点间距离一样,计算出两个数据之间的差异(二维和三维的点可以分别看作长度为二和三的向量)。当然,在人工智能领域,我们经常要处理的是更高维空间中的数据。

第4章“随机数生成”,讲解了人工智能算法中随机数的生成和使用。本章由关于均匀随机数和正态随机数的讨论切入——出现这种不同的根源在于有的时候算法要求随机数具有等可能性,而有的时候又需要它们服从某种既定的分布。此外本章还讨论了生成随机数的方法。

第5章“K均值聚类算法”,详述了将数据按相似度分类的方法。K均值算法本身可以用来将数据按共性分组,同时也可以被用于组成更复杂的算法—比如遗传算法就利用K均值算法对种群按特征归类,各路网商也利用聚类算法划分顾客,依照同类型顾客的消费习惯调整销售策略。

第6章“误差计算”,演示了评估人工智能算法效果的方法。误差计算的过程由一个用以评估算法最终效果的评分函数执行,其结果决定了算法的效果。一类常用的评分函数只需要给定输入向量和预期输出向量,也就是所谓的“训练数据”;算法的效果则由实际输出与预期输出间的差异决定。

第7章“迈向机器学习”,概述了可以从数据中学习特征来优化结果的简单机器学习算法。大多数人工智能算法是用权值向量将输入向量转化为期望的输出向量,这些权值向量构成了算法的长期记忆,“训练”就是一个调整长期记忆以产生预期输出的过程。本章会演示几个具有学习能力的简单模型的构建方法,也会介绍一些简单但却行之有效的训练算法,能够调整这种长期记忆(权重向量)并优化输出结果—简单随机漫步和爬山算法正是其中之二。

第8章“优化训练”,在前面章节的基础上进行了一定的拓展,介绍了像模拟退火算法和Nelder-Mead法[2]这样用来快速优化人工智能模型权重的算法。本章还说明了如何通过一定的调整,将这些优化算法应用于之前提到过的部分模型。

第9章“离散优化”,解释了如何优化非数值型的类别型数据。并非所有优化问题都是数值型的,还有离散型和类别型问题,比如背包问题和旅行商问题。本章将说明模拟退火算法可以用于处理这两个问题,并且该算法既适用于连续的数值型问题,也适用于离散的类别型问题。

第10章“线性回归”,讲解了如何用线性和非线性方程来学习趋势并做出预测。本章将介绍简单线性回归,并演示如何用它来拟合数据为线性模型。此外还将介绍可以拟合非线性数据的广义线性模型(General Linear Model,GLM)。

作为一次成功的众筹产物,本系列图书才得以在2013年面世。

我衷心地感谢该项目的所有支持者,没有你们的支持就没有这套丛书。我还要特别感谢那些赞助超过100美元的支持者。这些支持者们按赞助顺序排列的名单如下。

此外还要特别感谢Rick Cardarelle,他赞助的358美元一举使项目金额达到了要求的最低数额2500美元。也特别感谢Rory Graves和Matic Potocnik将示例代码转换为Scala代码。

谢谢大家,你们都是最友善的人!

[1] 定向内容已失效,读者可考虑访问另一个网址:https://www.heatonresearch.com/aifh/——译者注。

[2] 也称“下坡单纯形法”“变形虫法”或“多胞形法”,是一种在多维空间中求目标函数最大/最小值的常用数值方法。由John Nelder和Roger Mead于1965年提出。——译者注


本书由异步社区出品,社区(https://www.epubit.com/)为你提供相关资源和后续服务。

本书提供如下资源:

要获得以上配套资源,请在异步社区本书页面中点击,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎你将发现的问题反馈给我们,帮助我们提升图书的质量。

当你发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“提交勘误”,输入勘误信息,点击“提交”按钮即可。本书的作者和编辑会对你提交的勘误进行审核,确认并接受后,你将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

我们的联系邮箱是contact@epubit.com.cn。

如果你对本书有任何疑问或建议,请你发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果你有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。

如果你是学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果你在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请你将怀疑有侵权行为的链接发邮件给我们。你的这一举动是对作者权益的保护,也是我们持续为你提供有价值的内容的动力之源。

“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。

“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。

异步社区

微信服务号


本章要点:

外行人都以为人工智能是人造大脑,并且总把它和科幻电影中的机器人联系起来,而实际上这些科幻场景与现如今的人工智能没什么太大关系。人工智能确实跟人类大脑很相似,但它们的显著差异在于人工智能是人造的——人工智能不必具备生物特性。

在进一步深入学习之前,还要介绍一些与人工智能算法交互的通用概念。人工智能算法也称为“模型”,本质上是一种用以解决问题的技术。现在已经有很多特性各异的人工智能算法了,最常用的有神经网络、支持向量机、贝叶斯网络和隐马尔科夫模型等,本丛书将一一述及这些模型。

对于人工智能从业者来说,如何将问题建模为人工智能程序可处理的形式是至关重要的,因为这是与人工智能算法交互的主要方式。接下来我们将以人类大脑与现实世界的交互方式为引,展开本章关于基本知识的讲解。

人工智能的目标是使计算机可以如人脑一样工作,但这并不意味着人工智能需要在方方面面都向人脑看齐。某个人工智能算法与人脑真实功能的匹配程度称为“生物似真性”。

艾伦脑科学研究所(Allen Institute of Brain Science)的首席科学官Christof Koch曾断言大脑“是已知宇宙中最复杂的东西”[1]。而在人工智能的学科背景下,大脑本质上就是一种深奥、繁复的技术,我们有必要对它进行研究,通过逆向工程来解析它的工作原理和机制,从而模仿它的功能。

当然,大脑并非我们向自然界学习的唯一一种“高深技术”,飞行也是其中一种。早期的飞机试图模仿鸟类扑动的双翼,然而这种被称作“扑翼机”的飞行器效果却不尽人意。图1-1是“灰雁扑翼机”的专利图。

图1-1 灰雁扑翼机专利图(美国专利号1730758)

在20世纪早期,活生生的鸟儿是飞行器唯一参照的模型。这好像也很合理,毕竟它们是飞行专家。然而从飞行器的试飞情况来看,人类不应该试图去完全照搬自然界的解决方案。尽管我们想要模仿的只是“飞行”这个最终结果,但照搬鸟类的飞行姿态却无法制造出一台实用的飞行器。

“仿真”这个抽象概念存在于很多语境中,比如我的MacBook Pro既可以仿真一台Windows PC,也可以仿真一台Commodore 64。而C64的古旧并不仅仅体现在外观上,它的驱动指令集和如今很多电脑通用的Intel x86指令集大不一样,因此Mac在仿真一台C64机器的时候并不会去模拟C64 6510微处理器的实际晶体管结构,而是在更高的抽象层面进行仿真。人工智能与此同理,有一部分算法会模拟神经元,而还有一些算法则是像C64仿真器一样,在更抽象的层面进行仿真——我们只关心在PC环境中提供相应功能的最终目标,而不必模拟大脑中产生功能性的全部过程。

方向比方式更重要。人脑和大多数人工智能算法在高度抽象层面具有很多相似性,本节将就此给出实证。

在开始讨论之前,我们需要从外部视角来看看大脑的工作机制。毕竟,不像我们对大脑内部机理知之甚少那样,我们对大脑的外部工作机制倒是颇有一些了解。

大脑本质上是一个由神经连接的黑箱,这些神经负责在大脑和身体之间传递信号。一组特定的输入信号会产生特定的输出,比如当感觉到手指就要碰到滚烫的火炉时,其他神经就会向你的肌肉发出指令来收回手指。

另外一个需要注意的重点是大脑还存在一种内部状态。想想当你突然听到一声号角,你的反应不仅仅取决于号角声的刺激,同时也取决于你在何时何地听到这声号角——在一场电影中途听到一声号角,和在你穿过熙熙攘攘的大街时听到一声号角会引起截然不同的反应。你所处的环境会为你的大脑设定一个特定的内部状态,从而使大脑对不同情境产生不同的反应。

接受刺激的顺序同样也很重要。有一种常见的游戏就是闭上眼睛,尝试只通过触觉识物。你并不能在抓住物体的第一时间获取到足够的信息来判断出它是什么,而需要通过不断移动手指感受其形状,才能得到足够的信息勾勒出这个物体的图景,判断出它的类别。

你大可以把人脑视为具有一系列输入/输出的黑箱。我们的神经给我们提供了对世界的全部认知,它们本身也是大脑的输入信号,并且对于正常的大脑来说是一个数量有限的输入。

同样,我们与真实世界交互的唯一渠道就是那些从神经到肌肉的输出信号。人脑的输出实际上是一个关于输入信号和大脑内部状态的一个函数,对应于任何输入信号,人脑都会相应调整它的内部状态同时产生输出信号。并且输入信号的顺序影响或大或小,都取决于当时大脑的内部状态。

假如我们与真实世界的唯一交互渠道就是从感受器获得的输入和通过运动神经作用的输出,那么“真实”究竟是什么?你的大脑既可以与你的身体耦合,也可以像电影《黑客帝国》中的场景一样,跟一个仿真装置耦合。假如大脑的输出能够产生预期的输入反馈,那么你又应当如何区别真实与虚幻?

以上正是一个著名的哲学思想实验:“缸中之脑”。图1-2形象地阐释了这个思想实验。图中的大脑认为他的身体正在遛狗,可实际上这个大脑真的有身体吗?甚至这条狗存在吗?“存在”这个词本身又意味着什么呢?我们所知的一切都不过来自神经系统的信号传递[2]

图1-2 缸中之脑

这个思想实验假想某人的大脑可以脱离身体依靠维生系统保持活性。大脑的神经连接到一台可以用电脉冲完全仿真大脑实际接收信号的超级计算机上,之后这台超级计算机将通过对大脑的输出信号产生相应的响应这样的方式,模拟真实世界。这样一来,这个离体的大脑将依旧保持对外部“真实世界”完全正常的认知体验。甚至确实就有哲学理论认为我们生活在一个仿真的世界里[3]

一种尝试对人脑直接建模的算法就是“神经网络”。神经网络是人工智能研究的一个小分支,而它又与你将在本丛书中学到的很多算法惊人地一致。

基于计算机的神经网络不同于人脑,因为它们毕竟不具有通用性。现有的神经网络都只能解决特定的问题,应用范围有限。人工智能算法会基于算法内部状态和当前接收到的输入产生输出信号,并以此来认知现实。因此,算法所谓的“现实”常常会随着研究人员实验的进行而变化。

无论你是在为一个机器人还是为一个股民编写人工智能的程序,输入数据、输出数据和内部状态构成的模型适用于大多数人工智能算法——之所以说“大多数”,是因为当然也存在更加复杂的算法。

掌握将真实世界建模为机器学习算法的方法至关重要。针对不同的问题有不同的算法,在最抽象的层面,你可以按以下4种方式之一为你的问题建模:

当然有时也需要综合多种方式来对问题进行建模。接下来将从数据分类开始,对以上方法逐一进行讲解。

分类问题试图将输入数据归为某一类,通常是监督学习,即由用户提供数据和机器学习算法的预期输出结果。在数据分类问题中,预期结果就是数据类别。

监督学习处理的都是已知数据,在训练期间,机器学习算法的性能由对已知数据的分类效果来评估。理想状态是算法经过训练之后,也能够正确分类未知数据。

包含了鸢尾花测量数据的费雪鸢尾花数据集[4]是一个分类问题样例。这也是最著名的数据集之一,通常被用来评估机器学习算法的性能。完整的数据集可在以下网址获取:

http://www.heatonresearch.com/wiki/Iris_Data_Set[5]

下面是一个该数据集中的小样本。

“Sepal Length”,“Sepal Width”,“Petal Length”,“Petal Width”,“Species”
5.1,3.5,1.4,0.2,“setosa”
4.9,3.0,1.4,0.2,“setosa”
4.7,3.2,1.3,0.2,“setosa”
...
7.0,3.2,4.7,1.4,“versicolor”
6.4,3.2,4.5,1.5,“versicolor”
6.9,3.1,4.9,1.5,“versicolor”
...
6.3,3.3,6.0,2.5,“virginica”
5.8,2.7,5.1,1.9,“virginica”
7.1,3.0,5.9,2.1,“virginica”

上面的数据显示为逗号分隔值文件(Comma Separated Values,CSV)格式,这是一种在机器学习中很常见的输入数据格式。如样本所示,文件首行内容通常是每列数据的定义。在样本中,每朵花都有5个维度的信息:

对分类问题来说,算法需要在给定花萼和花瓣长、宽的情况下,判断花的种属,这个种属也就是这朵花所属的“类”[6]

“类”一般是一种非数值型数据属性,因此类中的成员必须有非常良好的定义。比如说这个鸢尾花数据集中只有3种不同种属的鸢尾花,那么用这个数据集训练的机器学习算法就不能指望它能够辨识玫瑰。此外,所有的类中元素在训练时都必须是已知数据。

在1.2.1节中,我们学习了如何对数据进行分类。但一般来说,所要的输出通常并不是简单的类别数据,而是数值数据,譬如要计算汽车的燃油效率,那么在给定发动机规格和车身重量之后,就应该可以算出特定车型的燃油效率。

下面列举了5种车型的燃油效率:

“mpg”,“cylinders”,“displacement”,“horsepower”,“weight”,
“acceleration”,“model year”,“origin”,“car name”
18.0,8,307.0,130.0,3504.,12.0,70,1,“chevrolet chevelle malibu”
15.0,8,350.0,165.0,3693.,11.5,70,1,“buick skylark 320”
18.0,8,318.0,150.0,3436.,11.0,70,1,“plymouth satellite”
16.0,8,304.0,150.0,3433.,12.0,70,1,“amc rebel sst”
17.0,8,302.0,140.0,3449.,10.5,70,1,“ford torino”
...

完整的数据集可以在下面这个网址获取:

http://www.heatonresearch.com/wiki/MPG_Data_Set[7]

回归分析旨在用汽车相关的输入数据训练算法,使之能够根据输入计算得到特定的输出。在这个例子中,算法需要给出特定车型最可能的燃油效率。

另外需要注意,文件中并不是每个数据都有用,比如“车型”和“产地”两列数据就没什么用处。“车型(car name)”被排除在有效数据之外是因为它跟燃油效率压根儿没什么关系,而“产地(origin)”也同样跟燃油效率关系不大——虽说“产地”这一项以数值形式给出了汽车的生产区域,并且某些地区比较重视燃油效率这一参数,但这个数据实在有些过于宽泛了,因此弃之不用。

聚类问题跟分类问题很像,在这两类问题中,计算机都要将输入数据进行编组。在训练开始之前,程序员通常要预先指定聚类的簇的数目,计算机则根据输入数据将相近项放到一起。由于并未指定给定输入一定属于某个簇,因此在缺乏目标输出数据时,聚类算法极为有用。也因为没有指定的预期输出,所以聚类算法属于非监督学习。

想想1.2.2节中汽车相关的数据,你可以用聚类算法把汽车分为4组,每一组中都会是一些特性相近的车型。

聚类问题和分类问题的不同之处在于,聚类问题给了算法更大的自由度,令其从数据中自行发现规律;而分类问题则需要给算法指定已知数据的类别,从而使它最终能够正确识别不曾用来训练过的新数据。

聚类和分类算法处理新数据的方式大相径庭。分类算法的最终目的是根据训练过的前序数据能够正确辨识新数据;而聚类算法中就没有“新数据”这样的说法,要想在现有的分组中添加新数据,就必须重新划分整个数据集。

机器学习算法的工作原理有些像数学中的函数,将输入值映射为特定的输出值。如果机器学习算法没有“内部状态”的存在,那么给定的输入数据集总会产生相同的输出。然而,许多机器学习算法都不存在可以改变或者影响输出的所谓“内部状态”。譬如说,对汽车数据而言,你会希望分类算法的计算结果拟合了全部数据,而不仅仅拟合它接受的最后几辆车的数据。

一般来说时序都很重要,虽然有一部分机器学习算法支持时序,却也有一部分并不支持这个功能。如果仅仅是对汽车或鸢尾花进行分类,倒也确实不必太过在意时序;但要是仅有的输入是当前股票价格,那时序就有着举足轻重的作用了,因为某天某只股票的单一价格对预测价格走势没有什么帮助,但拉长时间区间,综合数天的股票价格得到的走势可能就大有用处了。

也有一些方法可以将时间序列数据转换到不支持时序的算法上,这样你就要把前几天的数据也作为输入的一部分。比如你可以用5个输入来代表要预测那天的前5个交易日的数据。

在本章前面部分提到过,机器学习算法实际上就是给定输入,产生输出,而输出又受到算法本身的长短期记忆影响。图1-3展示了机器学习算法中长短期记忆如何参与产生输出的过程。

图1-3 机器学习算法抽象图示

如图1-3所示,算法接受输入,产生输出。大多数机器学习算法的输入和输出是完全同步的,只有给定输入,才会产生输出,而不像人脑,既可以对输出做出响应,偶尔也能够在没有输入的情况下自行产生输出。

到目前为止,我们一直在抽象地谈论输入/输出模式,你一定很好奇输入/输出到底长什么样儿。实际上,输入和输出都是向量形式,而向量本质上就是一个如下所示的浮点数组:

Input:[-0.245,.283,0.0]
Output:[0.782,0.543]

绝大多数机器学习算法的输入和输出数目是固定的,就像计算机程序中的函数一样。输入数据可以被视作函数参数,而输出则是函数的返回值。就上例而言,算法会接受3个输入值,返回两个输出值,并且这些数目一般不会有什么变化,这也就导致对特定的算法而言,输入和输出模式的元素数量也不会改变。

要使用这种算法,就必须将特定问题的输入转化为浮点数数组,同样,问题的解也会是浮点数数组。说真的,这已经是大多数算法所能做的极限了,机器学习算法说穿了也就是把一个数组转换为另一个数组罢了。

在传统编程实践中,许多模式识别算法有点儿像用来映射键值对的哈希表,而哈希表在很大程度上与字典又有些相似之处,因为它们都是一个条目对应一个含义。哈希表一般长下面这样儿:

上例这个哈希表是一些单词到定义的映射,其中将字符串形式的键映射为同样是字符串形式的值。你给出一个键(单词),哈希表就会返回一个值(对应单词的定义),这也是大多数机器学习算法的工作原理。

在所有程序中,哈希表都由键值对组成,机器学习算法输入层的输入模式可以类比为哈希表中的“键”,而输出层的返回模式也可以类比为哈希表中的“值”——唯一的不同在于机器学习算法比一个简单的哈希表更为复杂。

还有一个问题是,如果我们给上面这个哈希表传入一个不在映射中的键会怎么样呢?比如说传入一个名为“wrote”的键。其结果是哈希表会返回一个空值,或者会尝试指出找不到指定的键。而机器学习算法则不同,算法并不会返回空值,而是会返回最接近的匹配项或者匹配的概率。比如你要是给上面这个算法传入一个“wrote”,很可能就会得到你想要的“write”的值。

机器学习算法不仅会找最接近的匹配项,还会微调输出以适应缺失值。当然,上面这个例子中没有足够的数据给算法来调整输出,毕竟其中只有3个实例。在数据有限的情况下,“最接近的匹配项”没有什么实际意义。

上面这个映射关系也给我们提出了另一个关键问题:对于给定的接受一个浮点数组返回另一个浮点数组的算法来说,如何传入一个字符串形式的值呢?下面介绍一种方法,虽然这种方法更适合处理数值型数据,但也不失为一种解决办法。

词袋算法[8]是一种编码字符串的常见方法。在这个算法模型中,每个输入值都代表一个特定单词出现的次数,整个输入向量就由这些值构成。以下面这个字符串为例:

Of Mice and Men
Three Blind Mice
Blind Man's Bluff
Mice and More Mice

由上例我们可以得到下面这些不重复的单词,这就是我们的一个“字典”:

Input 0 :and
Input 1 :blind
Input 2 :bluff
Input 3 :man's
Input 4 :men
Input 5 :mice
Input 6 :more
Input 7 :of
Input 8 :three

因此,例子中的4行字符串可以被编码如下:

Of Mice and Men [0 4 5 7]
Three Blind Mice [1 5 8]
Blind Man's Bluff [1 2 3]
Mice and More Mice [0 5 6]

我们还必须用0来填充字符串中不存在的单词,最终结果会是下面这样:

Of Mice and Men [1,0,0,0,1,1,0,1,0]
Three Blind Mice [0,1,0,0,0,1,0,0,1]
Blind Man's Bluff [0,1,1,1,0,0,0,0,0]
Mice and More Mice [1,0,0,0,0,2,1,0,0]

请注意,因为我们的“字典”中总共有9个单词,所以我们得到的是长度为9的定长向量。向量中每一个元素的值都代表着字典中对应单词出现的次数,而这些元素在向量中的编号则对应着字典中有效单词的索引。构成每个字符串的单词集合都仅仅是字典的一个子集,这就导致向量中大多数值是0。

如上例所示,机器学习程序最大的特征之一是会把问题建模为定长浮点数组。下面的小节会用几个例子来演示如何进行这种建模。

你要是读过机器学习相关的资料,就一定见过“XOR”(即逻辑异或,eXclusive OR)这个运算符,模仿异或操作的人工智能程序堪称人工智能界的“Hello World”。本书确实有比XOR运算符复杂得多的内容,但XOR运算符依然是最佳入门案例。我们也将从XOR运算符上手。首先将其视作一个哈希表——如果你对XOR运算符不太熟悉的话,可以类比一下AND和OR运算符,它们工作原理十分相似,都是接受二元输入从而产生一个布尔值的输出。AND运算符当二元输入都为真时,输出则为真;而OR运算符只要二元输入中有一个为真,输出就为真。

对于XOR运算符而言,只有当其二元输入互异时,输出才为真。XOR运算符的真值表如下:

False XOR False = False
True XOR False = True
False XOR True = True
True XOR True = False

将上面的真值表用哈希表形式表示的话,会是下面这样:

[0.0,0.0] -> [0.0]
[1.0,0.0] -> [1.0]
[0.0,1.0] -> [1.0]
[1.0,1.0] -> [0.0]

以上映射展现了这个算法中输入和理想的预期输出间的关系。

机器学习问题通常需要处理一组数据,通过计算来对输出进行预测,或者对一系列行为进行决策。以一个包含以下字段的汽车数据库为例:

假如你已经收集到了以上字段对应的数据,那么你就能够建立模型并基于其余属性对应的值对某个属性的值进行预测了。举个例子,让我们来预测一下汽车的燃油效率。

首先我们要把问题归化为一个映射到输出浮点数组的输入浮点数组,并且每个数组元素的取值范围应该在0~1或-1~1,这一步操作称为“归一化”。归一化将在第2章中详细介绍。

首先我们来看看如何归一化上例数据。考虑一下输入、输出数据格式,我们总共有6个字段属性,并且要用其中5个来预测第6个属性,所以算法要有5个输入和1个输出。

算法的输入和输出大概是像下面这样:

我们需要对数据进行归一化,首先要为每个值选定一个合理的区间,然后再在保持相对大小不变的情况下将这些值转换为(0, 1)区间中的值。下面这个例子就为这些值选定了一个合理的区间:

这些范围对如今的汽车而言取得有些大了,不过却保证了未来不需要怎么重构就可以继续使用这个算法。大范围也有大范围的优点,那就是不至于产生太多极端数据。

现在来看一个例子,怎么样归一化一个900千克的重量数据呢?重量的取值区间大小是2 223千克,在区间中这个重量的相对大小是855(900-45)千克,占取值区间的百分比是0.385(855 / 2 223),因此我们会给算法的输入传入一个0.385的值来代表900千克的重量。这也满足了常见的输入为(0, 1)区间的范围要求。

“混合动力或常规动力”的值是真或假的布尔值,只要用1代表混合动力,用0代表常规动力,就轻易完成了布尔值到1或0两个值的归一化。

图像是算法的常见输入源。本节我们将介绍一种归一化图像的方法,这种方法虽然不太高级,但效果很不错。

以一个300像素×300像素的全彩图像为例,90 000个像素点乘以3个RGB色彩通道数,总共有270 000个像素。要是我们把每个像素都作为输入,就会有270 000个输入——这对大多数算法来说都太多了。

因此,我们需要一个降采样的过程。图1-4是一幅全分辨率图像。

图1-4 一幅全分辨率图像

我们要把它降采样为32像素×32像素的图像,如图1-5所示。

图1-5 降采样后的图像

在图片被压缩为32像素×32像素之后,其网格状模式使得我们可以按像素来生成算法的输入。如果算法只能分辨每个像素点的亮度的话,那么只需要1 024个输入就够了——只能分辨亮度意味着算法只能“看见”黑色和白色。

要是希望算法能够辨识色彩,还需要向算法提供每个像素点的红绿蓝3色(RGB)光强的值,这就意味着每个像素点有3个输入,一下子把输入数据的数目提升到了3 072个。

通常RGB值的范围在0~255,要为算法创建输入数据,就要先把光强除以255来得到一个“光强百分数”,比如光强度10经过计算就会变成0.039(10/255)。

你可能还想知道输出的处理办法。在这个例子中,输出应该表明算法认为图片内容是什么。通常的解决方案是为需要算法识别的每种图片创建一个输出通道,训练好的算法会在置信的图片种类对应的输出通道返回一个值1.0。

在1.3.4节中,我们将以金融算法为例,继续讲解针对实际问题格式化算法的方法。

金融预测是一种时间算法的常见应用。所谓“时间算法”,指的是接受时变性输入值的一种算法。要是算法支持短期记忆(即内部状态)的话,也就意味着自动支持输入范围的时变性。要是算法不具有内部状态,那就需要分别使用一个输入窗口和一个预测窗口——而大多数算法又没有内部状态。下面以预测股市的算法为例来讲解如何使用这两个数据窗口。假设你有了某只股票如下数天的收盘价:

Day 1 : $45
Day 2 : $47
Day 3 : $48
Day 4 : $40
Day 5 : $41
Day 6 : $43
Day 7 : $45
Day 8 : $57
Day 9 : $50
Day 10 : $41

第一步要将数据归一化。无论你的算法有没有内部状态,这一步都是不可或缺的。要将数据归一化,我们把每个数据都转换为对前一天的同比百分比变化,比如第2天的数据就会变成0.04,因为45美元到47美元之间变化了4%。在对每一天的数据都进行相同操作之后,数据集会变成下面这样:

Day 2 : 0. 04Day 3 : 0. 02Day 4 : -0.16Day 5 : 0. 02Day 6 : 0. 04Day 7 : 0. 04Day 8 : 0. 26Day 9 : -0.12Day 10 : -0.18

要创建一个预测后一天股票价格的算法,需要考虑一下怎么样把数据编码为算法可接受的输入形式。而这个编码方式又取决于算法是否具有内部状态,因为具有内部状态的算法只需要最近几天的输入数据就可以对走势进行预测。

而问题在于很多机器学习算法都没有“内部状态”这一说,在这种情况下,一般使用滑动窗口算法对数据进行编码。要达到这个目的,需要使用前几天的股票价格来预测下一天的股票价格,所以我们假定输入是前3天的收盘价,输出是第4天的股价。于是就可以对上面的数据如下划分,得到训练数据,这些数据实例都指定了对于给定输入的理想输出。

[0.04,0.02,-0.16]->0.02
[0.02,-0.16,0.02]->0.04
[-0.16,0.02,0.04]->0.04
[0.02,0.04,0.04]->0.26
[0.04,0.04,0.26]->-0.12
[0.04,0.26,-0.12]->-0.18

上面这种编码方式要求算法有3个输入通道和1个输出通道。

训练的本质是什么?训练是一个算法拟合训练数据的过程——这又不同于前面提到过的“内部状态”了,你可以把“训练”认为是对长期记忆的塑造过程。对神经网络而言,训练改变的就是权重矩阵。

何时训练由算法决定。一般来说,算法的训练和实际应用是鲜明分立的两个阶段,但也确实有训练和应用并行不悖的时候。

在学校里,学生们在学习科目的时候会被打分,这种打分出于很多目的,其中最基本的目的是对他们的学习过程提供反馈。同样,你也必须在算法训练阶段评估你的算法性能,这种评估既对训练有着指引意义,又能提供一种对训练成果的反馈。

一种评估方法是用一个评分函数,这个评分函数会使用训练好的算法并对它进行评估。这个评分函数只会返回一个分数,而我们的目标则是使这个分数达到上限或下限——对任何给定的问题来说,取上限还是下限都完全无所谓,仅仅取决于评分函数的设置。

批量学习(batch training)和在线学习(online training)跟学习过程的类型有关,因此通常在处理训练数据集的时候发挥作用。所谓“在线学习”,就是每输入训练集中的一个元素就进行一次学习;而批量学习则是一次性对特定数量的训练集元素进行学习,并同步更新算法。批量学习中指定的元素数量称为“批量大小”,并且这个“大小”通常与整个训练集的大小相当。

在线学习在必须同步进行学习和训练的情况下很有用,人脑就是以这种模式在工作,但在人工智能领域就不那么常见了,并且也不是所有算法都支持在线学习。不过在神经网络中在线学习倒是比较普遍。

本章浮光掠影式地了解了两种截然不同的训练方法:监督学习(surprised training)和非监督学习(unsurprised training)。当给定算法的预期输出时,就是监督学习;没有给定预期输出的情况就是非监督学习。

此外还有一种混合训练方法,只需要提供部分预期输出即可,常被用于深度置信网络。

确定学习(deterministic training)算法只要给定相同的初始状态,就总会以完全相同的方式运行,在整个算法中一般都没有用到随机数。

而随机学习(stochastic training)则不同,需要用到随机数。因此,即使选用同样的初始状态,算法也会得到全然不同的训练结果,这就使得评估随机算法的性能变得比较困难。但是不得不说,随机算法应用广泛并且效果拔群。

本章介绍了人工智能领域,尤其是机器学习领域的一些基础知识。在本章中,你可以学会如何将问题建模为机器学习算法——机器学习算法与生物过程颇有一些相似之处,但人工智能的目标并非完全模拟人脑的工作机制,而是要超越简单的流程化作业程序,制造出具有一定智能的机器。

机器学习算法和人脑的相似之处在于都有输入、输出和不显于外的内部状态,其中输入和内部状态决定了输出。内部状态可以视作影响输出的短期记忆。还有一种被称作“长期记忆”的属性,明确指定了给定输入和内部状态之后,机器学习算法的输出。训练就是一个通过调整长期记忆来使算法获得预期输出的过程。

机器学习算法通常被分为两个大类:回归算法和分类算法。回归算法根据给定的一至多个输入,返回一个数值输出,本质上是一个多输入的多元函数,其输出可能为单值,也可能是多值。

分类算法接受一至多个输入,返回一个类别实例,由算法基于输入进行决策。比如,可以用分类算法将求职者分为优先组、备选组和否决组。

本章说明了机器学习算法的输入是一个数值型向量。要想用算法处理问题,明白如何用数值向量的形式表达问题至关重要。

第2章将进一步介绍“归一化”的概念。归一化泛指通过预处理将数据转化为算法的输入形式的各种方法。此外,归一化也用于解释机器学习算法的输出。

[1] Koch, 2013。

[2] Sigiel, 1999。

[3] Bostrum, 2003。

[4] 又称“安德森鸢尾花数据集”或“鸢尾花数据集”,由埃德加•安德森建立,在罗纳德•费雪1936年论文《多重测量在分类问题中的应用》之后被广泛使用。——译者注

[5] 定向内容已失效,读者可考虑访问另一个网址:http://archive.ics.uci.edu/ml/datasets/Iris。——译者注

[6] 本书中的“类”无特殊说明一般是“种类”之意。区别于面向对象中的“类”。——译者注

[7] 定向内容已失效,读者可考虑访问另一个网址:https://archive.ics.uci.edu/ml/datasets/auto+mpg。——译者注

[8] Harris, 1954。


相关图书

GPT图解 大模型是怎样构建的
GPT图解 大模型是怎样构建的
扩散模型从原理到实战
扩散模型从原理到实战
大语言模型:基础与前沿
大语言模型:基础与前沿
ChatGPT原理与应用开发
ChatGPT原理与应用开发
人工智能(第3版)
人工智能(第3版)
ChatGPT写作超简单
ChatGPT写作超简单

相关文章

相关课程