深度学习:从基础到实践(上、下册)

978-7-115-55451-2
作者: 安德鲁·格拉斯纳(Andrew Glassner)
译者: 罗家佳
编辑: 吴晋瑜

图书目录:

详情

本书从基本概念和理论入手,通过近千张图和简单的例子由浅入深地讲解深度学习的相关知识,且不涉及复杂的数学内容。 本书分为上下两册。上册着重介绍深度学习的基础知识,旨在帮助读者建立扎实的知识储备,主要介绍随机性与基础统计学、训练与测试、过拟合与欠拟合、神经元、学习与推理、数据准备、分类器、集成算法、前馈网络、激活函数、反向传播等内容。下册介绍机器学习的 scikit-learn 库和深度学习的 Keras 库(这两种库均基于 Python 语言),以及卷积神经网络、循环神经网络、自编码器、强化学习、生成对抗网络等内容,还介绍了一些创造性应用,并给出了一些典型的数据集,以帮助读者更好地了解学习。 本书适合想要了解和使用深度学习的人阅读,也可作为深度学习教学培训领域的入门级参考用书。

图书摘要

版权信息

书名:深度学习:从基础到实践(上册)(下册)

ISBN:978-7-115-55451-2

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

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

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

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


版  权

   著 [美] 安德鲁·格拉斯纳(Andrew Glassner)

   译 罗家佳

责任编辑 吴晋瑜

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

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

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

读者服务热线:(010)81055410

反盗版热线:(010)81055315

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e55451”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。

内 容 提 要

本书从基本概念和理论入手,通过近千张图和简单的例子由浅入深地讲解深度学习的相关知识,且不涉及复杂的数学内容。

本书分为上下两册。上册着重介绍深度学习的基础知识,旨在帮助读者建立扎实的知识储备,主要介绍随机性与基础统计学、训练与测试、过拟合与欠拟合、神经元、学习与推理、数据准备、分类器、集成算法、前馈网络、激活函数、反向传播等内容。下册介绍机器学习的scikit-learn库和深度学习的Keras库(这两种库均基于Python语言),以及卷积神经网络、循环神经网络、自编码器、强化学习、生成对抗网络等内容,还介绍了一些创造性应用,并给出了一些典型的数据集,以帮助读者更好地了解学习。

本书适合想要了解和使用深度学习的人阅读,也可作为深度学习教学培训领域的入门级参考用书。

译 者 序

深度学习(或称深度神经网络)是一种使用了特殊分层计算结构的机器学习方法。近年来,深度学习在计算机视觉、语音识别、自然语言处理和机器人等应用领域取得了惊人的突破。2019年3月27日,美国计算机协会(ACM)将“计算机界的诺贝尔奖”图灵奖授予了3位深度学习之父(Yoshua Bengio、Geoffrey Hinton和Yann LeCun),以表彰他们给人工智能带来的重大突破——这些突破使深度神经网络成为计算的关键组成部分。这也意味着深度学习的神秘面纱至此已被揭开。

本书由计算机图形学专家Andrew Glassner撰写,介绍了深度学习的基础知识和实践深度学习的方法。全书分为上下两册:上册介绍深度学习的预备知识,涵盖基本的数学知识和机器学习的基本概念以及通用机器学习库scikit-learn的相关内容;下册深入介绍了各种成熟的深度学习方法和技术以及深度学习库Keras。

正如Andrew Glassner所描述的那样,在本书英文版出版之前,市面上其实已出现了较多的深度学习相关的图书。例如,由Ian Goodfellow等撰写的Deep Learning一书,对算法进行了非常详细的分析,并给出了大量的数学运算;还有一类风格截然不同的书,例如由François Chollet撰写的Deep Learning with Python,主要是针对只想知道如何利用各种机器学习库快速完成某些特定任务的读者。本书介于这二者之间,主要介绍深度学习的基础知识,以帮助读者建立扎实的知识储备,进而了解深度学习实践的进展。Andrew Glassner擅长以类比和图示的方法讲解复杂的理论知识,因此本书对不具备相关理论知识的读者也会非常有帮助。

非常感谢人民邮电出版社的杨海玲编辑邀请我来负责本书的翻译工作。回想自己首次接触神经网络,已是10余年前的事情了。在我学习神经网络时,市面上几乎没有类似的书,导致我走了不少弯路,也由此深刻感受到一本好书的重要性。在读过本书英文版之后,我认为本书的出现正好填补了深度学习从入门到实践的部分空白,于是欣然接受了本书中文版的翻译邀约。

还要感谢参与本书翻译的诸位同学:他们是上海交通大学密西根学院的王馨怡、付勇、何达、冯飞、梁子云、李鑫路、骆昶旭和卢佳安。其中,何达和冯飞是我指导的直博生,王馨怡、付勇和梁子云是我指导的硕士生,李鑫路、骆昶旭和卢佳安是我指导的高年级本科生。其中,王馨怡同学不仅参与了翻译工作,还负责了翻译协调的工作。在翻译过程中,大家表现出的团队合作与奉献精神以及认真负责的态度都值得高度赞赏。可以说,本书是我们共同努力取得的成果,没有他们的参与,本书的翻译是不可能顺利完成的。

我们将本书的翻译分成了初稿翻译、交叉验证和审校3个步骤,以确保译著的正确性和一致性。全书由我负责统稿和审校。但由于我们的中英文能力水平均有限,难免有翻译不当之处,敬请广大读者批评指正。

最后,再次感谢人民邮电出版社给予的支持!

罗家佳

前  言

欢迎阅读此书。首先,请允许我简单介绍一下这本书,并向那些帮助过我的人们致谢。

本书内容

如果你对深度学习(DL)和机器学习(ML)感兴趣,那么可以在本书里找到一些适合你阅读的内容。

之所以编写本书,是为了帮助你了解足够多的深度学习方面的技能,进而让你成为机器学习和深度学习的高效实践者。

读完本书,你可以:

设计和构建属于自己的深度学习网络体系;

使用上述网络体系来理解或生成数据;

针对文本、图像和其他类型的数据进行描述性分类;

预测数据序列的下一个值;

研究数据结构;

处理数据,以实现最高效率;

使用你喜欢的任何编程语言和DL库;

了解新论文和新理念,并将其付诸实践;

享受与他人进行深度学习讨论的过程。

本书会采用一种严肃而不失友好的讲解方式,并通过大量图示来帮助你加深理解。同时,我们不会在书中堆砌过多的代码,甚至不会使用任何比乘法更复杂的运算。

如果你觉得还不错,欢迎阅读此书!

为什么写这本书

本书的读者对象是那些渴望在工作中应用机器学习和深度学习的人们,包括程序员、艺术工作者、工程师、科学家、管理人员、音乐家、医生,以及任何希望通过处理大量信息来获得洞见或生成新数据的人。

你可以在许多开源库中找到许多机器学习工具(特别是深度学习)。每个人都可以立即下载和使用这些工具。

尽管这些免费工具安装简单,但是你仍然需要掌握大量的技术和知识才能正确使用这些工具。让计算机做一些无意义的事情很容易:它会严格照做,然后输出更多无意义的结果。

这种情况时有发生。虽然机器学习和深度学习库功能强大,但它们对用户来说并不友好。你不仅需要选择正确的算法,还要能够正确地应用这些算法。从技术角度讲,你仍然需要做出一系列明智的决策。当工作偏离预期时,你需要利用自己对系统内部的了解令其回归正轨。

学习和掌握这些基本信息的方法多种多样,这取决于你喜欢怎样的学习方式。有些人喜欢详细的硬核式算法分析,并辅以大量数学运算。如果这是你的学习方式,那么你可以阅读一些有关这方面的书籍,比如[Bishop06]和[Goodfellow17]。为此,你需要付出大量努力。不过,你获得的回报也会很丰厚,即全面了解机器学习的工作方式及原理。如果以这种方式学习,那么你必须额外投入大量的精力来将理论知识付诸实践。

另外一种截然不同的情形是:有些人只想知道完成某些特定任务的方法。有关这方面的速成图书也有很多,你可以从中找到各种机器学习库,比如 [Chollet17]、[Müller-Guido16]、[Raschka15]和[VanderPlas16]。与需要大量运算的方法相比,这种方法难度较低。但是,你会觉得自己缺少对结构信息的掌握——这些信息有助于你理解算法的工作原理。如果未能掌握这些信息及相关词汇,一些你原以为可行的算法可能变得不可行,或者某种算法的结果可能不如预期,而你很难对此找到问题的根源所在。另外,你将无法理解涵盖新理念和新研究成果的文献,因为这些研究往往假设读者拥有相同的知识储备,而只掌握一种库或语言的读者是不具备这种知识储备的。

鉴于上述情况,本书采取了一种折中的方式。我们的目的很实际:给你工具,让你有信心去实践深度学习。希望你在工作的时候不仅可以做出明智的选择,并且能够理解日新月异的新理念。

本书致力于介绍深度学习的基础知识,以帮助读者建立扎实的知识储备。随着深度学习实践的推进,你不仅需要对本书课题的背景有充分了解,还需要充分知悉可能需要查阅的资料。

这不是一本关于编程的书。编程很重要,但是会不可避免地涉及各个细节,而这些细节与本书的主旨并无关联。此外,编程会让你的思考局限于某一个库或者某种语言。尽管这些细节是构建最终学习网络体系的必要条件,但是当你想要专注于某一重要理念时,这些细节可能会让你分心。与其就循环和目录以及数据结构泛泛而谈,倒不如以一种独立的方式讨论某种语言和库相关的所有知识。只要扎实理解了对这些理念,阅读任何库文件都将变得轻而易举。

在第15章、第23章和第24章中,我们将详细讨论机器学习的scikit-learn库以及深度学习的Keras库。这两种库均基于Python语言。我们结合示例代码进行讲解,以期让你对Python库有深度的了解。即使你不喜欢Python,这些程序也会让你对典型的工作流和程序结构有所了解。这些章节中的代码可以在Python手册中找到,并且可用于基于浏览器的Jupyter编程环境[Jupyter16]。你也可以将其应用于更经典的Python开发环境,如PyCharm [JetBrains17]。

本书的其他大部分章节也有配套的可选Python手册。这些章节针对书中每个计算机生成的数字给出代码,而且通常使用其中所涉及的技术来生成代码。由于本书的焦点并非在于Python语言和编程(上述章节除外),因此这些手册仅作参考,不再赘述。

机器学习、深度学习和大数据正在世界范围内产生令人意想不到的、快速而深刻的影响。对人类以及人类文化而言,这是一个既复杂又重要的课题。与此相关的讨论也在一些有趣的图书和文章中得以体现,不过结论大多是喜忧参半。相关的图书和文章参见“参考资料”部分的[Agüera y Arcas 17]、[Barrat15]、[Domingos15]和[Kaplan16]。

本书几乎不涉及数学问题

很多人不喜欢复杂的方程式。如果你也是这样,那么本书非常适合你!

本书几乎不涉及复杂的数学运算。如果你不讨厌乘法,那么本书简直太适合你了,因为书中除了乘法,并无任何复杂的运算。

本书所讨论的许多算法都有丰富的理论依据,并且是经过仔细分析和研究得出的。如果你正打算变换一种算法以实现新目的,或者需要独立编写一个新程序,就必须了解这一点。不过,在实践中,大多数人会用由专家编写的程序。这些程序是经过高度优化的,并且可以从免费的开源库中获取。

我们希望能帮助你理解这些技术的原理,掌握其正确应用,并懂得如何解读结果,但无须深入了解技术背后的数学结构。

如果你喜欢数学或者想了解理论,那么请阅读每一章的“参考资料”部分给出的相关内容。大部分资料是简洁且能够激发灵感的,并且给出了作者在本书中刻意省略的细节。如果你不喜欢数学,可以略过此部分的内容。

本书分上下两册

本书涵盖的内容非常多,因此我们将其分成了上下两册。其中下册是上册内容的拓展和补充。本书内容是以循序渐进的模式组织的,因此建议你先读上册,再去学习下册的内容。如果你有信心,也可以直接从下册开始阅读。

致谢

如果没有众多朋友的支持,本书是无法写就的。这是千真万确的!

非常感谢Eric Braun、Eric Haines、Steven Drucker和Tom Reike对本项目始终如一的大力支持。谢谢你们!

非常感谢为本书提出诸多富有见地的评论的审稿人,他们是Adam Finkelstein、Alex Colburn、Alexander Keller、Alyn Rockwood、Angelo Pesce、Barbara Mones、Brian Wyvill、Craig Kaplan、Doug Roble、Eric Braun、Eric Haines、Greg Turk、Jeff Hultquist、Jessica Hodgins、Kristi Morton、Lesley Istead、Luis Avarado、Matt Pharr、Mike Tyka、Morgan McGuire、Paul Beardsley、Paul Strauss、Peter Shirley、Philipp Slusallek、Serban Porumbescu、Stefanus Du Toit、Steven Drucker、Wenhao Yu和Zackory Erickson。

特别感谢Alexander Keller、Eric Haines、Jessica Hodgins和Luis Avarado,他们阅读了本书所有或大部分手稿内容,并在内容呈现和内容结构方面提出了建设性意见。

感谢Morgan McGuire开发了Markdeep,让我能够专注于本书内容,而无须顾及格式。有了Markdeep的助力,本书的创作出奇地顺利和流畅。

感谢Todd Szymanski就本书内容、封面的设计和布局提出的深刻见解,同时感谢他指出了相关排版错误。

感谢以下读者在出版早期发现的拼写错误等问题:Christian Forfang、David Pol、Eric Haines、Gopi Meenakshisundaram、Kostya Smolenskiy、Mauricio Vives、Mike Wong和Mrinal Mohit。

参考资料

这部分内容在各章均有出现,其中列出了供参考阅读的所有文档。你还可以参阅正文涉及的其他有价值的论文、网站、文件、博客等资源。

[Agüera y Arcas 17] Blaise Agüera y Arcas, Margaret Mitchell and Alexander Todorov, Physiognomy’s New Clothes, Medium, 2017.

[Barrat15] James Barrat, Our Final Invention: Artificial Intelligence and the End of the Human Era, St. Martin’s Griffin, 2015.

[Bishop06] Christopher M. Bishop, Pattern Recognition and Machine Learning, Springer- Verlag, pp. 149-152, 2006.

[Chollet17] François Chollet, Deep Learning with Python, Manning Publications, 2017.

[Domingos15] Pedro Domingos, The Master Algorithm, Basic Books,2015.

[Goodfellow17] Ian Goodfellow, Yoshua Bengio, Aaron Courville, Deep Learning, MIT Press, 2017.

[JetBrains17] JetBrains Pycharm Community Edition IDE, 2017.

[Jupyter16] The Jupyter team, Jupyter官方网站,2016.

[Kaplan16] Jerry Kaplan, Artifical Intelligence: What Everyone Needs to Know, Oxford University Press, 2016.

[Müller-Guido16] Andreas C. Müller and Sarah Guido, Introduction to Machine Leaming with Python, O’Reilly Press, 2016.

[Raschka15] Sebastian Raschka, Python Machine Learning, Packt Publishing, 2015.

[VanderPlas16] Jake VanderPlas, Python Data Science Handbook, O’Reilly Media, 2016.

资源与支持

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

您还可以扫码右侧二维码, 关注【异步社区】微信公众号,回复“e55451”直接获取,同时可以获得异步社区15天VIP会员卡,近千本电子书免费畅读。

配套资源

本书为读者提供书中彩图文件。

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

如果您是教师,希望获得教学配套资源,请在社区本书页面中直接联系本书的责任编辑。

扫码关注本书

扫描下方二维码,读者会在异步社区微信服务号中看到本书信息及相关的服务提示。

与我们联系

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

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

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

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

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

关于异步社区和异步图书

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

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

异步社区

微信服务号

第1章 机器学习与深度学习入门

本章简要介绍贯穿本书的概念、语言和技术。

1.1 为什么这一章出现在这里

本章旨在帮助你熟悉机器学习的重要理念和基本术语。

机器学习(machine learning)这一术语涉及越来越多的技术,这些技术都有一个共同目标,那就是从数据中发现有意义的信息。

其中,“数据”是指任何可以被记录和测量的东西。它可以是原始数据(如连续几天的股票价格、不同行星的质量、小城集市里人们的身高),也可以是声音(如某人的手机录音)、图(如鲜花或猫的照片)、单词(如报纸文章或小说的文本),抑或是我们想要研究的其他任何东西。

“有意义的信息”是指我们可以从数据中提取到的任何信息,在某种程度上,这些信息对我们而言是有用的。我们可以判断哪些信息是有意义的,然后设计一个算法,从数据中找到尽可能多的这样的信息。

“机器学习”一词涵盖了广泛范围内的各种算法和技术,虽然明确定义这个词的精准含义是好的,但由于它对于不同的人来说有不同的用途,因此我们最好把它理解成一个涵盖了越来越多的各种算法和原理的统称,这些算法和原理的目的是对海量训练数据进行分析,并从中提取含义。

近来,有人创造了深度学习(deep learning),用来指代那些使用特殊分层计算结构的机器学习方法(这些分层依次堆叠),这样就形成了一个像堆叠的煎饼一样的“深度”结构。由于“深度学习”指的是所创建的系统的本质,而不是任何特定算法,因此它实际上指的是一种特定的机器学习方式或方法。近几年,人们通过该方法取得了大量研究成果。

现在,让我们来看一下使用机器学习从数据中提取含义的几个典型应用。

1.1.1 从数据中提取含义

邮局每天都需要根据手写的邮政编码整理大量的信件和包裹,目前他们已经开始借助计算机读取这些编码并自动分拣邮件,如图1.1a所示。

银行需要处理大量的手写支票:查看总金额栏内手写的数字金额(如25.10美元)与大写金额栏内的金额是否一致(如贰拾伍美元拾美分),以判断支票是否有效。计算机可以同时读取数字金额和大写金额,并确认两者是否相匹配,如图1.1b所示。

社交媒体网站想要通过照片识别出他们的用户,这意味着不仅要检测给定照片中是否有人脸,还要识别人脸的位置,然后将每张脸与之前看到的人脸进行匹配,由于灯光、角度、表情、衣着和许多其他特质都与先前的照片存在差异,并且同一个人的每一张照片都是独一无二的,因此人脸识别的难度加大了。而社交媒体网站想要的是为任何一个人拍摄一张照片后就可以识别出他的身份,如图1.1c所示。

(a)                          (b)                          (c)

图1.1 从数据集中提取含义。(a)从信封中获取邮政编码;(b读取支票上的数字和字母;(c)从照片中识别人脸

数字助手的供应商会聆听人们对其小工具的反馈,以便智能地做出回应。来自麦克风的信号是一系列数字,这些数字用于描述声音撞击麦克风膜时造成的压力,供应商想要分析它们,以便理解产生它们的声音,理解这些声音所属的词语以及词语所属的句子,最终得到这些句子的含义,如图1.2a所示。

科学家从无人机、高能物理实验和深空观测中获得大量数据后,往往需要从这些洪流般的数据中挑选出几个项目实例。这些实例与所有其他的项目都相似,但略有不同。即使不乏许多训练有素的专家,但要人工查看所有数据也是一项不可能完成的任务,所以最好能够通过计算机使这个过程自动化。通过计算机实现数据的彻底梳理,不遗漏任何一个细节,如图1.2b所示。

自然资源保护主义者会随着时间的推移来追踪物种的数量,观察它们的表现,如果物种数量长期下降,那么他们可能就会采取行动进行干预。如果物种数量稳定或有所增长,那么他们可能保持观望。预测一系列值的下一个值也是我们可以训练计算机去做的事情,图1.2c(改编自[Towers15])记录了加拿大西海岸北部虎鲸种群每年的数量,以及对于这些数量的预测值。

(a)                        (b)                            (c)

图1.2 从数据中提取含义。(a)用声音记录,之后转化为文字,最后输出完整的话语;(b)粒子加速器输出的痕迹大多是相似的,需要在其中发现一个不寻常的事件;(c)预测加拿大西海岸北部的虎鲸数量

这6个例子展示了为许多人所熟悉的机器学习的应用,其实机器学习还有很多其他应用。由于机器学习算法能够快速提取有意义的信息,因此它的应用领域也在不断扩展。

在这里,共同的地方是所涉及的大量工作以及它的详细细节。我们可能有数百万条数据需要研究,并从每条数据中提取有用含义。人类会感到疲倦、无聊和心烦意乱,但是计算机可以一直稳定又可靠地完成工作。

1.1.2 专家系统

一种发现隐藏在数据中的含义的早期流行方法涉及专家系统(expert system)的构建。这个想法的本质是:在研究了解人类专家知道什么、做什么以及怎样做后,将这些行为自动化,从本质上说,我们要制造一个能够模仿人类专家的计算机系统。

这通常意味着构建一个基于规则的系统(rule-based system),在这个系统中,我们会为计算机制订大量的规则,使其能够模仿人类专家。例如,如果试图识别邮政编码中的手写数字7,我们就可以设计一套这样的规则:7的形状是在图的顶部有一条近乎水平的线,然后有一条近乎对角线的斜线从水平线的右端点延伸到左下角,如图1.3所示。

(b)

图1.3 设计一套识别手写数字7的规则

(a)我们想识别的一个典型的7;(b)组成7的3条规则,如果有一个形状满足这3条规则,那么它被归为7

对每一个数字,我们都有相似的规则,通常情况下这些规则都可以实现要求,直至遇到图1.4所示的数字。

图1.4 这个7也是一个7的有效写法,但是它不会被图1.3的规则识别,因为多了一条线

我们之前没有考虑到有人会在7的中间加一横,所以现在需要为这种特殊情况添加另一条规则。

手动调整规则来更好地理解数据的过程有时称为特征工程(feature engineering)。这个术语也用于描述使用计算机为我们寻找这些特征的过程,参见本章“参考资料”中的 [VanderPlas16]。

这个术语描述了我们的愿景,也就是想要构造(或设计)人类专家完成工作所需的全部特征(或品质)。总的来说,这是一项非常艰难的工作。正如所看到的那样,我们很容易忽略一个甚至多个规则,想象一下(以下场景有多困难),你试图找到一套规则去总结“放射科医生如何判断X射线图像上的斑点是否是良性的”,或者“空中交通管制员如何处理繁忙的空中交通”,抑或“一个人如何在极端天气条件下安全驾驶汽车”。

诚然,基于规则的专家系统能够胜任一些工作,但是人工设定一个正确的规则集以及确保专家系统在各种各样的数据面前都能正确工作是非常困难的,而这个问题也似乎已经注定了其无法作为一种通用解决方法。对于一个复杂的过程,要清晰地表达其每一个步骤已经是极其困难的了,而在有些情况下,我们还需要考虑人类判断时基于经验和预感所做的决定,那么,除非是最简单的情况,否则这几乎是不可能完成的事情。

机器学习系统的美妙之处在于(在概念层面上):它们可以自动地学习数据集的相关特征。我们不需要告诉算法如何识别2或7,因为系统自己就能够去总结理解,但要做到这一点,系统通常需要大量的数据,即超大的数据量。

这也是机器学习在过去几年大受欢迎并得到广泛应用的一个重要原因,互联网提供的大量原始数据可以让机器学习这一工具从大量数据中提取出更多信息。企业能够利用与每个客户的每次交互来积累更多的数据,然后将这些数据作为机器学习算法的输入,利用它们为客户提供更多的信息。

1.2 从标记数据中学习

机器学习的算法是多种多样的,我们也将在本书中学习许多机器学习算法。许多算法在概念上是很简单的(尽管它们本身的数学或编程基础可能很复杂),例如,假设我们想通过一组数据点找到最佳直线,如图1.5所示。

图1.5 给定一组数据点,我们可以想象一个直线算法,它通过这些点来计算出最佳直线

从概念上讲,我们可以想象一种算法,它可以仅用几个数字来表示任意直线,在给定输入数据点的情况下,它会用一些公式来计算出这些数字。这是一种常见的算法,它通过深入、仔细的分析来找到解决问题的最佳方法,然后将这一方法在执行该分析的程序中实现,这是许多机器学习算法使用的策略。

相比之下,许多深度学习算法使用的策略就不那么为人所熟知了,它们需要慢慢地从例子中学习,每次学习一点点,而后一遍又一遍地学习。每当程序看到要学习的新数据,它就会调节自己的参数,最终找到一组参数值——这组参数值便可以很好地帮助我们计算出我们想要的东西。虽然我们仍在执行一个算法,但它比用于拟合直线的算法更开放。这里运用到的思想是指:我们不知道如何直接计算出正确的答案,于是搭建了一个系统,这个系统可以自己搞明白如何去做。我们之所以要分析和编程,是为了创建一种能够自行求解出属于它自己的答案的算法,而不是去实现一个能够直接产生答案的已知的过程。

如果这听起来很疯狂,那就是它本身真的很疯狂,以这种方式找到它们自己的答案的程序,是深度学习算法取得巨大成功的关键。

在接下来的几节中,我们会进一步研究这种技术,去了解它,但它可能并不像传统的机器学习算法那样为我们所熟悉。最终,我们希望你可以用它来完成一些任务,例如,向系统展示一张照片,然后由系统返回其中每个人的名字。

这是一项艰巨的任务,所以让我们从一些比较简单的事情开始,来看看几个学习的示例。

1.2.1 一种学习策略

现在,让我们来思考一种对于教学生而言糟糕的方式,如图1.6所示。对于大多数学生来说,这并不是实际的教育方式,但这是我们教计算机的方式之一。

图1.6 这是一种很糟糕的育人方式。首先,让学生背诵一组事例,然后测试每个学生的背诵情况,之后测试他们没有接触过的其他事例。虽然学生并没有接触过这些事例,但是如果他们能够较好地理解第一组事例,那么就能推导出新给出的事例。如果学生在测试中取得了好成绩(尤其是第二门),那么他就毕业了;否则,就会再次重复这个循环,重新背诵相同的事例

在这种情景下(希望是虚构的),老师会站在教室前面,重复叙述一系列学生应该记住的事例,之后每个星期五下午学生们都要接受两次测试,第一次测试是根据这些特定的事例对他们进行盘问,以测试他们的记忆力;而第二个测试会在第一次测试之后马上进行,会问一些学生以前从未见过的新问题,以测试他们对事例的整体理解。当然,如果他们只收到一些事例,那么任何人都不太可能“理解”这些事例,这也是这种方式糟糕的原因之一。

如果一个学生在第二次测试中表现出色,那么老师就会宣布他已经学会了这门课,之后他就可以顺利毕业了。

如果一个学生在第二次测试中表现得不好,那么下个星期他将再次重复同样的过程:老师以完全相同的方式讲述同一个事例,然后还是通过第一次测试来衡量学生的记忆力,再通过第二次新的测试来衡量他们的理解或概括能力。每个学生都在重复这个过程,直到他们在第二次测试中表现得足够好,才可以毕业。

对于学生来说,这种教育方式是糟糕的,但这确实是一种非常好的教计算机学习的方式。

在本书中,我们将看到许多其他的教计算机学习的方式,但是现在让我们先来深入了解一下这种方式。我们将看到,与大多数人不同的是,每当计算机接触完全相同的信息,它都会学到一点点新的东西。

1.2.2 一种计算机化的学习策略

从收集我们要教的知识开始:我们需要收集尽可能多的数据。每一项观测数据(如某一特定时刻的天气)称为一个样本(sample);构成观测数据的名称(如温度、风速、湿度等)称为它的特征(feature)[Bishop06],每个被命名的测量数据或特征都有一个关联的值,通常被存储为一个数字。

在为计算机准备数据的过程中,我们需要将每个样本(即每个数据片段,其中的每个特征都被赋予一个值)都交给人类专家,由人类专家检查其特征并为该样本注明一个标签(label)。例如,如果样本是一张照片,那么标签可能是照片中人的名字、照片中所显示的动物的类型、照片中的交通是否顺畅或拥堵等。

以测量山上的天气为例,专家的意见用0~100分表示,它的含义是专家多大程度上认为“这一天的天气有利于徒步旅行”,如图1.7所示。

图1.7 我们从一组样本或数据项目开始对数据集进行标记,每个样本都由描述它的特征列表组成,我们将这个数据集交给一位人类专家,由他逐一检查每个样本的特征,并为该样本注明一个标签

我们通常会取一些带标签的样本并暂时把它们放在一边,并将在不久后用到它们。

一旦有了带标签的数据,我们就可以把它交给计算机,之后就可以让计算机找到一种方法来为每个输入匹配正确的标签。我们并没有告诉计算机如何去完成这个动作,而是给了它一个具有大量可调参数(甚至数百万个参数)的算法。不同的学习类型会使用不同的算法,本书的大部分内容都是致力于对它们的研究以及讲述如何更好地使用它们。一旦选择了一个算法,我们就需要通过它来运行一个输入,从而产生一个输出。这是计算机的预测(prediction),表达了计算机认为该样本是属于哪个专家标签。

当计算机的预测与专家标记的标签相符时,我们什么也不会做,但一旦计算机出错,我们就要求计算机修改它所使用的算法的内部参数,这样当我们再次给它相同的数据时,计算机就更有可能预测出正确的答案。

这基本上是一个反复试验的过程,计算机尽其所能给我们正确的答案,如果失败了,它就会遵循一个程序来改变和改进。

一旦做出预测,我们就只检查计算机的预测与专家的标签是否匹配,如果它们不匹配,我们会计算出一个误差(error),也称为代价(cost)或损失。这是一个数值,用于告知算法离正确结果还有多远。该系统会根据其内部参数的当前值、专家的预测结果(当前已知)以及自己的错误预测来调整算法中的参数,以便在再次看到这个样本时预测正确的标签。稍后我们将仔细研究这些步骤是如何执行的。图1.8展示了上述过程。

图1.8 训练(或者说学习)过程的一个步骤。我们将样本的特征和标签分开,根据这些特征,算法会预测出一个标签。我们将预测值与实际标签进行比较,如果预测标签与我们想要的标签相匹配,我们就什么都不做,否则我们将告知算法去进行修改或更新,这样它就不会再犯同样的错误

我们是通过“(1)分析训练数据集中的样本;(2)针对不正确的预测对算法进行更新”来训练(train)系统学习如何预测数据的标签。

我们将在后续章节中详细讨论应该如何进行选择不同的算法和更新步骤,目前我们需要知道的是,每个算法都是通过改变内部参数来实现预测的。每当出现错误预测,算法就可以对其参数进行修改,但是如果修改太多,就会使得其他的预测变得糟糕起来。同样,算法也可以只对其参数做很微小的修改,但是这样会导致学习速度较其他情况而言更加缓慢。我们必须通过对每种类型的算法和我们所训练的每一个数据集进行反复的试验,才能够在这两种极端之间找到正确的平衡。我们把对参数更新的多少称为学习率(learning rate),所以,如果我们采用一个小的学习率,就代表着谨慎和缓慢;而如果采用一个大的学习率,就可以加速整个过程,但也有可能会适得其反。

打个比方,假设我们在沙漠里,需要用金属探测器找到一个埋在地下的装满东西的金属盒子。我们会把金属探测器晃来晃去,如果在某个方向得到响应,我们就会朝那个方向移动。如果我们谨慎一点,每次只走出一小步,就不会错过盒子或是丢掉信号;但如果我们非常激进,每次迈出一大步,这样我们就能更快地接近盒子。也许我们可以从大步前进开始,但是随着离盒子越来越近,我们可以逐渐减小步幅,这也就是我们通常所说的“调整学习率”,通过调整学习率使得在刚开始训练时对系统的改动很大,但是会逐渐减小这个改动。

有一种有趣的方法可以让计算机在只记住输入而不进行学习的情况下获得高分,为了得到一个完美的分数,算法所要做的就是记住专家为每个样本标记的标签,然后返回那个标签的值。换句话说,它不需要学习如何计算出给定样本的标签值,而只需要在表中查找到正确的答案即可,在前文假设的学习场景中,这就相当于学生在考试中记住了问题的答案。

有时这会是一个很好的策略,稍后我们就会看到,有些非常有效的算法就遵循了这种方法。但是,如果是让计算机从数据中学到一些东西,并能够将所学推广应用到新的数据中,那么使用这种有趣的方法往往会适得其反。这种方法的问题在于:系统已经记住了样本的标签,导致所有训练工作都不会给我们带来任何新的东西,且由于计算机对数据本身一无所知,而只是从表中得到答案,计算机就不知道如何为它从未见过和记住的新数据创建预测。整个问题的关键在于我们需要让系统能够预测以前从未见过的新数据的标签,这样就可以放心地将其应用于会不断出现新数据的实际场景中。

如果算法在训练集上执行得足够好,但是在新数据上执行得很差,就说该算法的泛化能力很差。现在让我们看看如何提高算法的泛化能力,或者说如何学习数据,使得它能够准确地预测新数据的标签。

1.2.3 泛化

我们会用到1.2.2节中提到的暂时搁置的标记数据。

我们通过向系统展示它之前从未见过的样本来评估系统对所学知识的泛化(generalization),而这个测试集(test set)也会向我们展示系统对于新数据的表现。

现在,让我们来看一个分类器(classifier),这种系统会为每个样本分配一个标签(标签描述了该样本所属的类别或类)。假如输入是一首歌,那么它的标签可能是歌曲的流派(如摇滚或古典);假如输入是动物的照片,那么它的标签可能是照片上的动物(如老虎或大象)。而在运行的例子中,我们便可以将每天预期的“徒步旅行经历”归为三类:糟糕的、好的和很棒的。

我们会要求计算机预测测试集中每个样本的标签(这些都是计算机以前从未见过的样本),然后比较计算机的预测和专家的标签,如图1.9所示。

图1.9 评估一个分类器的整个过程

在图1.9中,我们将测试数据拆分为特征和标签两部分,该算法为每一组特征分配(或者说预测)了一个标签。然后,我们通过比较预测的标签和真实标签来衡量预测的准确率。如果预测结果足够好,那么我们就可以部署系统;如果预测结果不够好,那么我们需要继续进行训练。注意,与训练不同,这个过程中没有反馈和学习,在我们回到明确的训练模式之前,算法并不会改变它的参数,不管它的预测结果是否准确。

如果计算机对这些全新的样本(对于算法来说是全新的)的预测与专家分配的标签不匹配,那么我们将回到图1.8所示的训练步骤。我们会把原先训练集中的每个样本再给计算机看一遍,让它继续进行学习。注意,给出的是相同的样本,所以我们要求计算机从相同的数据中反复学习。通常来说,我们会对数据进行洗牌,使得样本以不同的顺序到达,但是不会给算法任何新的信息。

然后我们会要求算法再次预测测试集的标签,如果表现不够好,我们将再次返回原先的训练集进行学习,然后再测试,一遍又一遍地重复这个过程。这个过程往往需要重复几百次,我们一遍又一遍地向计算机展示同样的数据,而计算机每次都多学习一点。

正如我们之前所说的那样,这是一种糟糕的教学方式,但是计算机不会因为一遍又一遍地看到相同的数据而感到厌烦或焦躁,它只是不断学习它能够学会的东西,之后在每次学习中一点点地变得更好。

1.2.4 让我们仔细看看学习过程

我们通常认为数据中存在某种关联,毕竟如果它是完全随机的,我们就不会试图从中提取信息。在1.2.3节中,我们所希望的过程是通过向计算机一遍又一遍地展示训练集,来让它从每个样本中一点点地学习,最终该算法将找到样本特征与专家分配的标签之间的关联,进而可以将这种关联应用到测试集的新数据上。如果预测大部分是正确的,那么我们就说它具有很高的准确率,或者说泛化误差(generalization error)很小。

但是,如果计算机一直无法改进它对测试集标签的预测,我们就会因无法取得进展而停止训练。通常我们会修改算法以期待得到更好的表现,再重新进行训练。但这只是我们的一种期待,无法保证对于每一组数据都有一个成功的学习算法,即便有,我们也无法确保一定能够找到它。好消息是,即使不通过数学运算,计算机也可以通过实践找到泛化的方法,有时得到的结果比人类专家做得更好。

其中一个导致算法学习失败的可能原因是:它没有足够的计算资源来找到样本与其标签之间的关联。有时,我们会认为计算机创建了一种底层数据的模型(model)。例如,如果我们测量到在每天的前3个小时里温度会上升,计算机就可能会构建一个“模型”来表达早上温度会上升。这只是数据的一个版本,就像小型塑料版本的跑车或飞机是大型交通工具的一种“模型”一样,我们在前文中所看到的分类器就是一种模型。

在计算机中,模型是由软件结构和它所用的参数值组成的,更庞大的程序和参数集可以引导模型从数据中学习更多内容,这时我们就说它有更大的容量(capacity),或者说表征能力。我们可以把这看作算法能够学习的东西的深度和广度,而更大的容量使我们有更大的能力从已知的数据中发现含义。

打个比方,假设我们在为一名汽车经销商工作,就需要为所销售的汽车写广告,而市场部已经给了我们一份可以用于描述汽车的“得到认可的词汇”,工作一段时间后,我们也许就可以学会用这个模型(得到认可的词汇表)来完美地描述每一辆车。

假设这时经销商买了一辆摩托车,那么我们现有的词汇(或者说现有的模型)就没有足够的“容量”来描述这个交通工具——我们的容量只能描述之前描述过的那些交通工具。我们并没有足够多的词汇量来指代有两个轮子而不是4个轮子的东西,我们可以竭尽所能,但是结果可能并不理想。如果我们可以使用更强大的、有更大容量的模型(也就是说,更多用于描述交通工具的词汇),就能做得更好。

但是更庞大的模型也意味着更多的工作量,正如我们将在后续章节中看到的那样:相比小一点的模型,更庞大的模型往往会产生更好的结果,但代价是耗费更多的计算时间和计算机内存。

算法中会随着时间的推移自主进行修改的值称为参数(parameter),同时学习算法也会受设定的值所控制(如学习率),这些设定的值称为超参数(hyper parameter)。

参数和超参数的区别在于:计算机会在学习过程中自主调整它自己的参数值,而超参数值则是在我们编写和运行程序时设定的。

当算法学得足够好,能够在测试集上执行得足够好,足以令人满意时,我们就可以将它部署(deploy)(或者说发布)。一旦用户提交了数据,系统就会返回它预测的标签。

这就是人脸图如何变成名字、声音如何变成文字以及对天气的监测如何变为预报的过程。

现在让我们回过头来宏观地看看整个机器学习领域。如果要对机器学习这一广阔且持续发展的领域进行调查,那么需要占用一整本书的篇幅(参见“参考资料”中的[Bishopo6]和[Goodfellow17])。接下来,我们介绍当今大多数学习工具的主要分类。在本书中,我们会反复提到这类算法。

1.3 监督学习

如果样本带有预先设定的标签(就像我们在前文的例子中看到的那样),就说我们正在进行监督学习(supervised learning),这种监督来自标签,它们控制着图1.8中的比较步骤,并告诉算法是否预测了正确的标签。

监督学习有两种类型——分类(classification)和回归(regression)。分类是指遍历一个给定的类别集合,之后找到最适合描述特定输入的类别;回归是指通过一组测量值来预测一些其他的值(通常是下一个值,但也可能是在集合开始之前或中间的某个地方的数值)。

下面让我们依次来看一下。

1.3.1 分类

假设有一组日常用品的照片,照片中有苹果削皮器、烤箱、钢琴等,我们想根据照片所展示的东西来对其进行分类,那么就把对这些照片进行分类归类的过程称为分类归类

在这种方法中,我们通过向计算机提供一个列表开始训练,该列表列出了我们希望计算机学习的所有标签(或类、类别)。通常,这个列表只是简单组合了训练集中所有样本的所有标签,去掉了重复项。

然后我们用大量照片和它们的标签来训练系统,直到确定它能很好地预测出每张照片的正确标签。

至此,我们就可以给系统一些以前从未见过的新照片了。我们希望它能正确地标记它在训练过程中看到的物品的图像,如果出现无法识别的形状或者这个形状在训练集所包含的类别之外,系统就会尝试从它所知道的类别中选出最接近的类别,如图1.10所示。

图1.10 在进行分类时,我们用一组图像训练一个分类器,每个图像都有一个相关的标签。当训练完成后,我们就可以给它一些新的图像,之后它会尝试再去为每个图像选择最好的标签。图中展示的这个分类器没有受过金属勺子或耳机类别的训练,所以它展示了所能找到的最接近的匹配类别

在图1.10中,我们使用一个经过训练的分类器来识别之前从未见过的4个图像[Simonyan14],值得称赞的是,它发现了开瓶器,尽管这个物体被刻意做成一艘船的形状。然而,该系统并没有经过与金属勺或耳机相关的类别训练,因此在这两种情况下,它所找到的都只是最接近的匹配。为了正确地识别这些对象,我们就需要在训练过程中向系统展示更多的相关物品的示例。

另一种看待这种情况发生的方式是:系统只能理解它所学到的东西。传统的分类器总是尽力为每个输入找到最接近的匹配,但是它们只能从所知道的类别中选择。

1.3.2 回归

假设我们对测量值进行了收集,但是收集结果并不完整,而我们又希望能够估计缺失的值。例如,我们在持续跟踪当地体育馆举办的一系列音乐会的到场观众人数,以便根据音乐会的总门票收入,按照一定比例给乐队支付报酬。

然而,我们计算时漏掉了某个晚上的到场观众人数,为了制订预算,我们就要知道明天的观众到场率是多少。测量结果如图1.11a所示,而我们对缺失值的估计如图1.11b所示。

(a)                                             (b)

图1.11 在回归中,我们需要使用一组输入和输出值,这里的输入值是5月5日到13日的音乐会日期,而输出值是到场观众人数。(a)实测数据,缺少5月8日的值;(b)红点是对5月8日缺失点的值的估计,而黄点是对5月13日到场观众人数的预测

我们把这种填充和预测数据的过程称为回归问题。“回归”这个名字可能会让人产生误解,因为“回归”的意思是回到以前的状态,但是在这里似乎没有任何回归的动作。

这一不常见的词来自发表于1886年的一篇论文,一位科学家在研究儿童的身高(参见“参考资料”部分的[Galton86])时发现,虽然有些孩子长得高,有些孩子长得矮,但随着时间的推移,人们的身高会趋于平均。他将此描述为“回归至平庸”,意思是测量趋向于从极端走向平均值。

虽然通常来说“回归至平庸”这个短语会被认为是来源于Galton的,但在发表得更早的一篇关于达尔文《物种起源》[Darwin59]的不太起眼的文章中,也有一个非常相似的评论。一位名叫Fleeming Jenkin的评论家认为:物种多样性会被“让一切回归平庸的普适力量”所“湮灭”。

如今,“平庸”一词带有一些负面的含义,所以现在这个概念通常称为“趋均数回归”。其中“均数”是一种平均值,而“回归”一词仍然用来表示使用数据的统计属性来估计缺失值或预测未来值的概念。

因此,“回归”问题就是我们有一个取决于输入的值(如到场观众人数是某月某日的函数),之后需要为新的输入预测一个新的值。

最著名的回归是线性回归(linear regression)。“线性”指的是这种技术会尝试用直线匹配输入数据,如图1.12所示。

图1.12 用数学形状表示数据点。(a)线性回归是将直线与数据相匹配,但只有一条线无法与数据很好地匹配,其优点是非常简单;(b)更复杂的线性回归将同一组数据与曲线相匹配,这样可以更好地匹配数据,但是其形式更复杂,在计算时需要做更多的工作(从而需要更多的时间)

直线很吸引人,因为它很简单,但在这个例子中可以看到,它无法很好地描述数据——数据是会上下起伏的,这是直线无法捕捉到的。诚然,这不是世界上最糟糕的匹配,但的确也不是一个很好的匹配。

我们可以使用一些更复杂的回归形式来创建更复杂的曲线类型,如图1.12b所示。这些方法可以实现更好的数据拟合,但要耗费更长的计算时间。随着曲线变得越来越复杂,我们往往需要更多的数据支撑。

1.4 无监督学习

当输入数据没有标签时,从这些数据中学习的算法均称为无监督学习(unsupervised learning)。这只是意味着我们没有提供标签来“监督”学习过程,在没有帮助的情况下,系统必须自行解决所有问题。

无监督学习通常用于解决我们称之为“聚类”“降噪”和“降维”(dimension reduction)的问题。下面让我们来依次看一下。

1.4.1 聚类

假设我们正在为盖新房子挖地基,意外发现了很多旧陶罐和花瓶,于是打电话将情况告知给一位考古学家。她意识到我们发现的是一堆古代陶器,而且认为这些陶器显然来自不同的地方,也可能来自不同的时期。

这位考古学家无法认出其中的任何标记和饰纹,所以她不能确定每一个标记来自哪里——有些标记看起来像是某一相同主题的变体,有些看起来则像是不同的符号。

为了解决这个问题,她决定把这些标记拓印下来,然后试着把它们分类。但是她要处理的事情太多了,而她的研究生都在忙其他项目,因此她决定转用机器学习算法,希望能以一种合理的方式自动地将标记分类。

图1.13显示了所拓印的标记以及算法自动进行的分类,我们把这类问题称为聚类(clustering)问题,并将实现这一过程的算法称为聚类算法(clustering algorithm)。在实现这一过程时,有许多算法可供我们选择,稍后我们将看到各种各样的聚类算法。如果用我们刚刚提及的术语进行描述,那就是,因为输入是没有标签的,所以这位考古学家正在用无监督学习算法进行聚类。

(a)                            (b)

图1.13 使用聚类算法来整理陶罐上的标记。(a)罐子上的标记;(b)相似的标记被分到一个簇中

1.4.2 降噪

有时样本会被噪声(noise)污染,如果样本是某人对着手机讲话的音频剪辑,那么噪声可能是街道的嘈杂背景音,这会让人们很难分辨出这个人说了什么。如果样本是电子信号(可能是广播或电视节目),噪声就会以静电形式侵入(静电干扰),造成广播节目中引起注意力分散的声音或电视图像中的闪烁点。在合成的或计算机生成的图像中,我们可以通过省略一些像素来节省时间,这时被省略的部分看起来就是黑色的,对计算机来说,这就是一种“噪声”,尽管实际上它是数据缺失而不是损坏。

我们的眼睛对噪声和缺失的像素很敏感,但是数据往往会得到更多的信息(相比于我们的观察)。图1.14显示了一个噪声图的示例以及一个降噪算法对该示例的处理结果。

(a)                                           (b)

图1.14 降噪(或称为去噪),减少了随机失真对样本的影响,甚至可以填补一些缺失的空白。降噪算法可以在不同程度上成功地恢复图。(a)一张劣质的有大量噪声像素和一些缺失像素的牛的图;(b)原始图

这种情况不仅适用于图,当我们使用任何来源的数据时,样本几乎都带有不准确性或其他失真,这些不准确和失真将掩盖我们想要提取的信息。

如果这里有缺失的值,就可以使用回归算法来填充它们,或者把它们当作另一种形式的噪声,用降噪算法来填充这些值。

数据是没有标签的(例如,在有噪声的照片中,我们有的只有像素),所以降噪在形式上是一种无监督学习。算法通过学习样本的统计数据来评估每个样本,找出噪声部分,然后将其去除,留下更容易学习和解释的纯净数据。

在使用算法学习数据之前,我们往往需要对数据应用降噪算法,来删除输入中的奇异值和缺失值,使得学习过程更快、更顺利。

1.4.3 降维

有时,样本会有一些额外的特征(本身不需要的)。例如,假设我们于盛夏时节在沙漠中采集天气的样本,每天记录风速、风向和降雨量,如果假定在该季节和地区,每个样本的降雨量值均为0,那么在机器学习系统中使用这些样本时,计算机就需要处理和解释每一个样本中无用的、恒定的信息片段。这样做,轻则会降低分析的速度,重则会影响系统的准确性。因为计算机会投入其有限的时间和内存资源中的一部分,去试图从这个不变的特征中学习一些东西。

有时,特征会包含冗余的数据。例如,当一个人走进健康中心时,健康中心会记录下他的体重(单位:kg),然后护士会把他带到检查室,这时护士会再次测量他的体重,而这次是以磅为单位,之后将这个数据也放入图表中。那么这时,相同的信息就重复了两次,但是这很难被识别,因为它们的取值不同,就像无用的降雨量测量一样。当我们试图从这些数据中学习时,这种冗余是没有任何好处的。

下面讲述一个更抽象的例子,它涉及的数据要比实际需要的复杂得多。假设某个国家的森林正在遭受一种未知的传染病侵害,这种传染病会损害树木,林业部门曾试图将树干的一部分放在机器上,让机器转动木头将其刮掉,在此过程中测量木头的密度,并以此研究这种传染病在倒下的树上的扩散情况。这样做会生成一个三维的数据集,如图1.15a所示。树上的每个点都位于这个三维视图中,并且我们还需要一个值来告诉我们树被感染的情况。因此,我们需要4个数字来表示这些数据:3个数字用于描述点在空间中的位置,一个数字用于描述它的值。

这里的立体信息是很重要的,但是如果我们只是想要顺着螺旋的路径获得数据,就可以通过扁平化数据来使工作变得更轻松,如图1.15b所示。现在,对于每个数据点来说,我们需要3个数字来描述它:两个数字用于描述每个点的位置,一个数字用于描述它的值。这将使得我们在不放弃任何对于特定分析来说很重要的数据的情况下,加快对数据的处理速度。

(a)                                            (b)

图1.15 当树干转动和被刮光时,检测它被感染的情况。(a)原始数据为三维形式;(b)我们可以通过将数据展开为二维来简化问题

起初,我们可能可以通过简化对数据的测量来使得工作更轻松,如果做不到,就可以在收集数据之后对它进行简化,去除与所要解决的问题无关的信息,这样计算机就不需要处理这些信息,这不仅节省了时间,甚至可能提高结果的质量。

例如,假设我们正在监测一条新建的、弯曲的、单向的而且单车道的山路上的交通情况,并且想要确保在所关心的特定路段的交通是安全的,所以我们设置了一些监控装置,之后就可以周期性地得到一些快照。图1.16a显示了每辆车的位置、运行的方向及其沿着我们想要监测的路段行驶的速度。

我们可能倾向于用纬度和经度来描述每辆车的位置,但是这里还有一种更简单的方法。由于道路只有一辆车宽,因此我们可以用一个数字来描述每辆车的位置,这个数字可以表明车离这段路的起点有多远,如图1.16b所示。

(a)                               (b)

图1.16 这条路上的车辆在哪里?(a)可以用纬度和经度来测量每辆车的位置,这需要两个数字(用xy进行标记);(b)还可以测量每辆车沿着路的方向所行驶的距离,这只需要一个数字,这种方法使得数据变得更加简单

在上述情况下,我们就可以使用无监督学习来分析样本,并删除对理解隐含信息没有帮助的特征。通过简化数据,学习系统可以通过更少的工作进行学习,从而使训练更快、更准确。

有时候,我们可以通过丢弃一小部分信息来简化数据。比如,当我们只是进行粗略的检查以确保一切正常运行时,如果它能大大简化运算并提高训练速度,放弃一些精度也是值得的。

下面让我们看看如何在监测路况的例子中做到这一点。我们可以在图1.16中看到如何用一个数字而不是两个数字来定位车辆的方法,在这种情况下,我们没有丢失任何信息。在其他情况下,我们也可以将测量数据结合起来,尽管这样做会丢失一些信息,但仍然可以捕获大部分的信息。例如,在修改版本的高速公路上,在每个方向上可能都有两条车道,这样就确实需要用图1.16a所示的纬度和经度这两个数字来准确定位每一辆车。

但如果我们想,也可以使用一个数字来描述车辆的位置,如图1.17所示。这也为我们提供了非常近似的确定汽车位置的值。

图1.17 如果我们愿意舍弃一些准确性,就可以简化计算。根据需要,我们可以用不同的方式来表示这些车辆的位置

为了确定图1.17中车辆的位置,我们可以测量它们到左下方路段或道路起始处的距离,就像图1.16所示的那样。但是,这样做是假设每辆车都位于道路中心的情况,当车辆不再位于道路中心时,我们就可以切换到一个更详尽、更精确的表示方法。这样做的代价是:通常,更简单的版本会给出一个更快的训练和运行的系统,但是往往会包含错误。更精确的系统的训练和运行会更慢,但是更准确。这两种选择都是可行的,这取决于系统所需的准确性和速度。

某些情况下,从图1.17中所得到的近似位置已经足够精确。

在所有例子中,我们的目标都是简化数据,所用的方法是删除不提供信息的特征、组合冗余特征或是用准确性来交换简化的数据结果(通过组合或是其他操作特征的方法)。

在这些情况下,我们都可以使用无监督学习算法来完成工作。

用无监督学习算法来找到一种减少我们描述数据所需要的值(或维度)的方法称为降维,这个名称直观反映了我们正在减少的每个样本的特征 (也称为维度)的数量。

1.5 生成器

假设我们正在拍摄一部电影,一个重要的场景发生在放着波斯地毯的仓库里,我们迫切需要仓库里有几十条甚至几百条的地毯,要地板上有地毯,墙壁上有地毯,中间的大架子上也有地毯,而我们希望每条地毯看起来真实但又与其他地毯有所不同。

但是预算远没有多到可以购买或者租借数百条独一无二的地毯,所以我们只买了几条地毯,然后交给道具部门并告诉他们“做一些类似于这几条的地毯,但是每一条都不一样”。他们可能只是用大而柔软的纸画一些地毯,但是不管怎样,我们只是想让他们做一些独特的东西,而且看起来像真的地毯,可以让我们挂在仓库里。图1.18显示了最初我们购买的地毯。

图1.18 最初我们购买的波斯地毯

图1.19展示了一些根据图1.18“做”出来的地毯,但是与最初我们购买的地毯有所不同。

图1.19 根据图1.18中的地毯制作的一些新地毯

我们可以用机器学习算法做同样的事情,这一过程称为数据增强(data amplification)或数据生成(data generation),由生成器(generator)算法实现。在这个小例子中,我们只从一条地毯开始,以此作为示例,而通常在实际中我们会用大量的例子来训练生成器,这样生成器就能生成拥有许多变体的新版本。

因为不需要使用标签来训练生成器,所以我们可以称之为无监督学习。但是在生成器的学习过程中,我们确实会给它们一些反馈,通过这些反馈来使它们知道是否为我们制造了足够逼真的“地毯”。基于此,我们也可能需要把生成器放到监督学习中。

生成器是处于中间地带的,它不需要标签,但是又从我们这里得到了一些反馈,因此我们把这一中间地带称为半监督学习(semi-supervised learning)。

1.6 强化学习

假设一个没有孩子的单身汉,临时受托去照顾朋友年仅3岁的女儿。他不知道这个小姑娘喜欢吃什么。

第一天晚上,他想给小姑娘做一些比较简单的食物,最终决定做黄油意大利面。小姑娘很喜欢!但是吃了一周的黄油意大利面之后,他们都吃腻了,于是男人往面里加了一些奶酪。小姑娘也很喜欢!最终,他们吃腻了黄油意大利面和奶酪意大利面,于是在某天晚上,他尝试做了香蒜沙司面,但小姑娘一口都不愿意吃。于是,他又重新做起了意大利面——这次使用了纯番茄酱,但小姑娘还是不吃。试过了各种各样的意大利面,他开始尝试用酸奶油来为她做一份烤土豆。

就这样,我们的“新厨师”尝试了各种各样的菜谱,一种又一种地加以改变,试图开发一份小姑娘会喜欢的菜单,他得到的唯一反馈是:要么小姑娘吃,要么小姑娘不吃。

这种学习方法称为强化学习(参见“参考资料”的[Champandard02]和[Sutton17])。

我们可以将厨师重新命名为智能体(agent),将小姑娘重新命名为环境,这样我们就可以使用更加通用的术语来描述上述烹饪故事。智能体可以做决策和采取行动(是故事中的“厨师”),而环境则是宇宙中除智能体外的一切事物(是故事中的小姑娘)。环境在每次行动之后都会给智能体一个反馈(feedback)(或者一个奖励信号),用于描述这个行动产生的结果有多好。在对操作进行评估的同时,这一反馈还会告诉智能体环境是否发生了更改。如果发生了更改,那么环境现在是什么样子。这种抽象描述的价值在于,我们可以描绘出许多智能体和环境的组合,如图1.20所示。

图1.20 在强化学习中,我们想象一个智能体(可以做决策和采取行动)和一个环境(宇宙中除了智能体外的一切事物),智能体采取行动后,环境以奖励信号的形式发送反馈

强化学习不同于监督学习,因为数据没有标签,虽然从错误中学习这一总体思路是相同的,但是作用的机制不同。

相比之下,在监督学习中,由系统生成一个结果(通常是一个类别或一个预测值),然后我们将其与所提供的正确结果进行比较;而在强化学习中,是没有正确结果的,因为数据没有标签,而是通过反馈来告诉我们做得有多好。这种反馈可能只是少许信息,告诉我们刚刚完成的行动是“好”还是“坏”;也可能会深入、细致地用所有可能进行的描述方式来告诉我们刚刚完成的行动所导致的环境变化,包括任何后续的变化。如何用最有效的方式来利用反馈是强化学习算法的核心。

比如,自动驾驶的汽车可能是一个智能体,而环境则是由它行驶的街道上的其他人组成的。汽车通过观察行驶过程中发生的事情来进行学习,并且更倾向于学习那些遵守法律并保护每个人安全的行为。再如,舞蹈俱乐部的DJ就是智能体,而喜欢或不喜欢DJ播放的音乐的舞者就是环境。

本质上,对于任何给定的智能体,环境都是宇宙中除智能体外的其他一切事物。因此,每个智能体的环境都是独一无二的,就像在多人游戏(或其他活动)中,每个玩家所看到的世界都是由他们自己(智能体)、其他所有人和事物(环境)组成的,而每个玩家都是他们自己的智能体,同时也是其他人环境中的一部分。

在强化学习中,我们会在一个环境中创建智能体,然后让这个智能体通过尝试各种行动并从环境中得到反馈来学习要做什么。这里可能存在一个目标状态(如进球得分,抑或找到隐藏的宝藏),也可能我们的目标只是达到一个成功、稳定的状态(例如,俱乐部里开心的舞者或是车辆在城市街道上自动驾驶)。

总体思路是这样的:智能体先采取一个行动,环境接纳了这个行动并且通常会做出相应的改变来响应这个行动;然后环境会向智能体发送一个奖励信号,告诉它这个操作有多好或有多坏(或者没有影响)。

奖励信号通常只是一个数字,越大的正数代表这一行为越好,而越小的负数则可以被视为惩罚。

与监督学习算法不同的是,奖励信号不是一个标签,也不是一个指向特定“正确答案”的指针。我们不如说它只是一个测量值,用于度量行为如何利用某个标准来改变环境和智能体本身,这个标准才是我们所关心的。

1.7 深度学习

深度学习指的是用一种特定的方法来解决一些机器学习的问题。

这种方法的中心思想是:基于一系列的离散的(layer)构建机器学习算法。如果将这些层垂直堆叠,就说这个结果是有深度(depth)的,或者说算法是有深度的

构建深度网络的方法有很多种。在构建网络时,我们可以选择很多不同类型的层。在本书后续章节中,我们会用几个完整的章节来讨论不同类型的深度网络。

图1.21展示了一个简单的示例,这个网络有两层,每一层都用方框显示出来,在每一层中,都有一些称为人工神经元(artificial neuron)或感知器的计算块(见第10章)。这些人工神经元的基本操作是读取一串数字,以特定的方式将这些数字加以组合,然后再输出一个新的数字,并将输出传递到下一层。

这个示例只包含两个层,但神经网络是可以有几十层甚至更多的层的。同时,每一层也不是只有2~3个神经元,它可以包含成百上千个神经元,并以不同的方式排列。

深度学习架构的吸引力在于,我们可以通过调用深度学习库中的例程来构建完整的网络,这些例程将负责所有的构建工作。正如我们将在第23章和第24章中看到的那样,通常只需要短短的一行代码就可以实例化一个新的层,之后使它成为网络的一部分。深度学习库将为我们处理内部和外部的所有细节。

由于这种结构模式搭建方便,许多人将深度学习比作用乐高积木搭建东西。我们只是堆积想要的层,每个层由一些参数来标定,之后对一些选项进行命名,就可以开始训练了。

图1.21 一个两层的深度网络。每一层都用方框表示,方框里的是人工神经元,每一层的输出连接到下一层的输入。在本示例中,提供4个数字作为输入,而2个数字构成输出

当然,这并不容易,因为选择正确的层、选择它们的参数以及处理其他的选择都需要小心谨慎。能够很容易地构建一个网络固然好,但这也意味着我们做的每一个决定都可能会带来很大的影响。如果做错了,那么网络可能就无法运行。也有可能出现更常见的情况——网络不会学习,我们给它输入数据,而它会返回给我们无用的结果。

为了减少这种令人沮丧的情况的发生,在讨论深度学习时,我们会充分详细地研究关键的算法和技术,以便能以一种明智的方式做出所有决定。

我们已经在图1.10中看到了一个深度学习的例子,用了一个16层的深度网络来对这些照片进行分类,下面让我们更仔细地看看这个系统返回了什么。

图1.22展示了4张照片以及深度学习分类器对它们类别的预测,包括它们的相对可信度。系统非常完美地识别出了蜂鸟,但是对于那个船形的开瓶器不太确定;又因为它以前从来没有见过长柄勺或者耳机,所以得到了一个猜测的结果。

图1.22 4张照片以及深度学习分类器对它们类别的预测。这个系统没有经过长柄勺或耳机的训练,所以它正在尽最大努力将这些照片与它所知道的东西相匹配

让我们尝试另一个图像分类任务,这次我们将用手写数字0~9来训练系统,然后输入一些新的图,让系统对其进行分类。这是一个非常著名的数据集,称为MNIST,我们会在本书中多次提到它。图1.23展示了该系统对一些从未见过的新数字的预测。

图1.23 一个深度学习分类器对手写数字的分类

这个深度学习分类器做对了所有归类,就这些数据来说,现代分类器已经能够实现非常好的效果,并且能够达到99%的准确率。10000张图中,我们构建的小系统也能够正确地分类9905张,即分类结果与人类专家提供的标签只有95次不一致。

深度学习系统的一个妙处在于,它们在实现特征工程上表现得很好。回想一下上面的内容,这是一项去寻找让我们做出判断的规则的任务。比如,一个数字是1还是7,一张图是猫还是狗,或者一个演讲片段中的单词是“coffeeshop”还是“movie”。要为一项复杂的工作人工制订这样的规则,几乎是一项不可完成的任务,因为我们必须考虑到所有变化和特殊情况。

但是,深度学习系统可以隐式地学习如何独立自主地实现特征工程。它探索了大量可能的特征并对其进行评估,而后根据评估保留一些特征并丢弃其他特征。它完全是独立地进行这个过程的,没有我们的指导。系统的表征力越强(通常可以总结为拥有更多的层,每层都有更多的人工神经元),就越能发现好的特征,我们称之为特征学习

我们每天都在使用这种类型的深度网络,将其应用于照片中的人脸识别、手机对语音命令的识别、股票交易、汽车驾驶、医学图像分析以及许许多多的其他任务。

只要系统是由一系列用于计算的某些类型层构成的(这些类型我们将在后面的章节中见到),它就可以被称为“深度学习”系统。因此,“深度学习”一词更多的是一种搭建机器学习程序的方法,而不是一种自主学习的技术。

当我们想要解决一些比较庞大的问题时(例如,在一张照片中识别1000个不同对象中的某一个),深度学习网络就会变得很庞大,涉及数千甚至数百万个参数。这样的系统就需要大量的数据进行训练,通常也需要更长的时间。图形处理单元(Graphics Processing Unit,GPU)的普及对这方面的工作起到了很好的辅助作用。

GPU是一种特殊的芯片,它位于中央处理单元(Central Processing Unit,CPU)旁边。CPU用于执行运行计算机所涉及的大多数任务,如与外围设备和网络的通信、内存管理、文件处理等。设计GPU的初衷是通过接管制作复杂图形(如三维游戏中渲染的场景)时的计算来减轻CPU的负担。训练深度学习系统所涉及的操作恰好与GPU执行的任务非常匹配,这也是这些训练操作可以快速执行的原因。此外,GPU的自身设计允许并行计算,即可以同时执行多个计算,专为加速深度学习计算而设计的新芯片也开始出现在市场上。

深度学习理念并不适用于所有机器学习任务,但是恰当地使用它们可以产生非常好的结果。在许多应用中,深度学习方法表现得比其他算法优越得多,从标记照片到用直白的语言与我们的智能手机“交谈”,它正在彻底改变我们可以用计算机来实现的东西。

1.8 接下来会讲什么

在后续章节中,我们将更详细地研究前文描述的所有概念。

前几章将讨论所有现代机器学习算法的基本原理,我们将学习概率论与数理统计以及信息论的基础知识,然后学习基本的学习网络以及如何使它们很好地工作。

虽然所有讨论都将适用于任何机器学习语言或库,但是为了更加具体化的描述,我们将介绍如何使用流行的(并且是免费的)Python语言的scikit-learn库来实现基础的技术。

接下来我们回到宏观的描述。我们将看到机器学习系统是如何学习的,以及人们用来控制这个过程的不同算法。随后我们会关注深度学习,并探究各种流行的深度学习网络。

在接近尾声的时候,我们将进一步应用算法,展示如何使用Keras库(也是Python的免费库)搭建和运行深度学习系统。最后,我们会介绍一些最近被广泛使用的、用于深度学习的强大架构。

这本书是层层推进的,有许多章节是建立在前几章的基础之上的。我们的目的是先呈现使用机器学习和深度学习实现目标所需的一切东西,之后让你能够使用库、理解相关的文档并看懂每天接踵而至的知识更新。

如果你很迫切地想要学习一些具体的东西,可以直接跳到相应的章节去深入学习。如果遇到不熟悉的术语或概念,你可以根据需要去翻看前面章节中的内容。

参考资料

[Bishop06] Christopher M. Bishop, Pattern Recognition and Machine Learning, Springer- Verlag, 2006.

[Bryson04] Bill Bryson, A Short History of Nearly Everything, Broadway Books, 2004.

[Champandard02] Alex J. Champandard, Reinforcement Learning, Reinforcement Learning Warehouse, Artificial Intelligence Depot, 2002.

[Darwin59] Charles Darwin, On the Origin of Species by Means of Natural Selection, November 1859.

[Galton86] Francis Galton, Regression Towards Mediocrity in Hereditary Stature, The Journal of the Anthropological Institute of Great Britain and Ireland, Vol. 15, pgs 246-263, 1886.

[Goodfellow17] Ian Goodfellow, Yoshua Bengio, Aaron Courville, Deep Learning, MIT Press, 2017.

[Simonyan14] Karen Simonyan, Andrew Zisserman, Very Deep Convolutional Networks for Large-Scale Image Recognition, arXiv, 2014.

[Sutton17] Richard S. Sutton and Andrew G. Baro, Reinforcement Learning: An Introduction, A Bradford Book, MIT Press, 2017.

[Towers15] Jared R. Towers, Graeme M. Ellis, John K.B. Ford, Photo-identification catalogue and status of the northern resident killer whale population in 2014, Canadian Technical Report of Fisheries and Aquatic Sciences 3139, 2015.

[VanderPlas16] Jake VanderPlas, Python Data Science Handbook, O’Reilly Media, 2016.

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e55451”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。

第2章 随机性与基础统计学

本章介绍如何在算法中表达随机性,并回顾一些统计学的基本思想——这些都是我们会在本书中用到的。

2.1 为什么这一章出现在这里

我们经常想要讨论不同的数据段之间的关系,但不需要单独讨论每段数据。从某种意义上说,大部分数据是“相同的”的吗?还是它们的分布跨越了一个很广的范围而存在“差异”?是否有一些奇怪的数据看起来不太合群?数据间是否存在某种连接了部分或是所有数据段的模式?

这些问题在机器学习中是很重要的,因为我们对数据了解得越多,就能更好地去选择和设计用于研究和控制数据的工具。

打个比方,假设我们需要把两块木板和一小块给定的金属连接起来,如果给定的金属是钉子,我们就要选用锤子;如果给定的金属是螺丝,我们就要选用螺丝刀。通过分析得到的数据,我们就可以选择最合适的工具来从数据中获得最大的价值。

这些工具给出了语言和概念,让我们可以讨论大型数据集,但它们往往都是和统计学捆绑在一起的。

让我们来直面一个真相:你可能不会读一本机器学习的书,因为你想了解的是统计学。但是这些想法是如此重要,以至于你至少需要熟悉一些机器学习的内容。从论文和源代码注释到馆藏文献,统计的思想和语言在机器学习中无处不在,至少了解一个数据集的基本统计情况对于选择一个合适的用于学习数据的工具和算法来说是不可或缺的。

因此,我们将尽力精简本章的篇幅并突出重点,即涵盖核心思想,但不深入研究数学理论或细节。我们的目标是建立对于统计学的充分理解和直觉,以在进行机器学习时做出正确的决定。

与统计学思想有着紧密联系的是随机数,我们本章会介绍更多有关随机数(random number)的概念,而不仅是库中的一个例程。

即便你已经熟悉统计学和随机数的相关知识,或者确实不在意它们,也应快速浏览一下这部分内容,这样就会知道我们在本书中使用的一些语言,在书中遇到这些概念时,也知道到哪里去找。

2.2 随机变量

随机数在许多机器学习算法中都起着重要的作用,我们会使用各种工具来控制随机数的种类以及对它们的选择,而不是凭空挑选任意的数字。

这种思想是这样的,当有人跟我们说:“从1~10选一个数字”,这时他就把我们的选择限制在这个范围内的10个整数(integer)中。当魔术师让我们“选择一张牌”时,他们通常会给我们一副有52张的牌,让我们从中任选一张。在这两个例子中,我们的选择都来自有限数量的选项(分别是10个和52张)。但是我们也可以有无数个选择。有人可能会让我们“从1~10中选出一个实数”,然后我们就可以选择3.3724或者6.9858302,抑或是1和10之间无限多的实数(real number)中的任何一个。

在谈论数字的范围时,我们经常讨论的是它们的“平均值”,这里有3种不同的常见的平均值类型,让我们在此命名它们,以免日后混淆。

作为示例,我们列出了5个数字:1、3、4、4、13。

均值(mean)是我们日常用语中所说的“平均”,它是由所有条目之和除以列表中的条目数得到的。在上述示例中,我们将所有列表元素相加得到25,有5个元素,那么均值是25/5,也即5。

众数是列表中出现频率最高的值。在上述示例中,4出现了两次,其他3个值都只出现了一次,因此4是众数。如果没有值出现的频率比其他任何值都高,就说列表没有众数。

把列表数字按照从小到大的顺序排列时,中间的数字是中位数(median)。在已经排好序的列表中,左边是1和3,右边是4和13,中间是4,所以4是中位数。如果一个列表包含偶数个条目,中位数就是两个中间条目的平均值,对于列表1、3、4、8,中位数是3和4的平均值,也就是3.5。

让我们用一个类比来进一步研究这些问题。假设我们是摄影师,要给一篇关于汽车垃圾场的文章配上很多报废汽车的照片,为此我们去了一个汽车垃圾场,那里有数百辆报废的车辆,很有冒险的感觉。

我们与汽车垃圾场场主沟通,并谈妥了她为我们寻找每一辆可拍摄汽车的价格。为了让这件事更有趣,她在办公室里放置了一个老式的嘉年华轮盘,每辆车都对应着一个条框,各个条框的大小是相同的,如图2.1所示。

图2.1 汽车垃圾场场主的嘉年华轮盘。每辆车都对应一个大小相同的条框,每个条框都对应一个数字,当轮盘停下来时,她就会带我们去拍指针所指的车

我们一付钱,她就转动轮盘,当轮盘停下来时,她会记下车号,然后出去用拖车把相应的车辆拖到我们面前。

我们拍了几张照片,她就会把车还到停车场。如果我们想再拍一辆车,就需要再付钱,她会再次转动轮盘,重复上述过程。

对于我们而言,她带给我们的每一辆车都是随机选择的,因为我们事先不知道是哪一辆。但汽车也不是完全任意的,因为我们在开始之前就知道一些关于车辆的信息,例如,它不可能是未来的汽车,也不可能是一辆没有停在该停车场的汽车。所以汽车垃圾场场主并没有(通过她的嘉年华轮盘)选择所有可能的车辆,而选择的是她可以选择的特定选项。

假设我们的任务目标是拍摄5种不同类型汽车的照片:轿车、皮卡、面包车、SUV和货车。我们想知道当她每次转动轮盘并从停车场里随机取出一辆车时,该车是其中一种的概率。

为了解决这个问题,假设我们进入汽车垃圾场检查了每一辆车,并把每一辆车归到这5种类型中的一种,结果如图2.2所示。

图2.2 该汽车垃圾场中有5种不同类型的汽车,每种类型的车的数量用条形图加以表示

在这个汽车垃圾场中,有近950辆汽车,其中面包车最多,其次是皮卡、货车、轿车和SUV。因为这里的每一辆车被选中的概率相等,那么旋转一次轮盘后,我们最有可能得到一辆面包车。

但是具体而言,我们有多大可能得到一辆面包车呢?为了回答这个问题,我们可以用每一个条形块的高度除以汽车的总数,就可以得出我们得到选择给定类型的汽车的概率,如图2.3所示。

图2.3 如果我们进入汽车垃圾场,并且随机选择一辆车,那么得到每种类型的车的概率取决于有多少辆这种类型的车,并且与车的总数有关。最终我们一定会得到什么东西,因此所有概率加起来应该等于1。如果将所有可能性包含进来而且所有概率加起来已经为1,就可以称其为概率分布

为了将图2.3中的数字转换为百分比,我们将它们乘以100%,例如,面包车在条形图中的高度是0.34,就说有34%的机会得到一辆面包车。

如果我们把所有5根条形的高度加起来,就会发现其总和是1。每个条形块的高度被称为我们得到这种类型的车的概率(probability)。只有所有条形块相加会得到1,才能使用这个术语,这告诉我们得到某物的概率是1(或100%),或者说是必然的。如果这些条形块加起来不等于1,那么我们可以把这些条形图称为各种各样的非正式名称(如“得到这种车的期望”),但是不能把它们称为概率。

我们将图2.3称为概率分布(probability distribution),因为它将100%的概率“分布”在5个可能选项中。我们有时也会说,图2.3是图2.2的归一化(normalized)版本。这里的“归一化”意味着这些值加起来等于1,在这种情况下,“归一”的用法来自它在数学中的含义。

我们可以将概率分布表示为一个简化的嘉年华轮盘,如图2.4所示。指针指向给定区域的概率是通过占轮盘圆周的部分来表达的,我们在这里所画出的比例与图2.3中的相同。

图2.4 一个简化的嘉年华轮盘。这告诉我们如果汽车垃圾场场主旋转图2.1中的轮盘,我们会得到什么样的车。每种车型的圆周占比遵循图2.3中的概率分布

大多数情况下,在计算机上生成随机数时,我们并没有嘉年华轮盘,而是依赖软件去模拟这个过程。我们会给例程一个值列表,比如图2.3中的各个条形的高度,然后让它返回一个值。我们会设定希望能在34%的情况下得到“面包车”,26%的情况下得到“皮卡”,以此类推。

要从选项列表中“随机”选择一个值(每个选项都有自己的概率),就需要做一些工作。为了方便起见,我们将这个选择的过程打包到一个称为随机变量(random variable)的概念中。这个术语可能会让程序员感到困惑,因为程序员认为“变量”是一种被命名的可以存储数据的存储空间。但是,我们在这里使用的术语是来自它在数学中的用法,有着不同的含义。

随机变量不是一个存储的空间,而是一个函数(function),意味着它将一些信息作为输入,并产出一些信息作为输出[Wikipedia17c]。在这种情况下,随机变量的输入是概率分布(或者说是它能产生的每个可能值的概率),而它的输出则是一个特定的根据概率选择的值,生成这个值的过程称为从随机变量中抽取(draw)值。

我们把图2.3称为概率分布,但也可以把它看作一个函数,也就是说,对于每个输入值(在本例中是车的类型),它会返回一个输出值(得到那种类型的车的概率)。这样想,我们就得到了一个更加完整和正式的名字:概率分布函数(probability distribution function)或者pdf(通常小写)。有时人们也会用更加隐晦的名字来指代这种分布:概率质量函数(probability mass function)或pmf

我们的概率分布函数有着有限数量的选项,每个选项都有一个概率,因此我们也可以进一步专门化它的名称,将其称为离散概率分布(discrete probability distribution)(末尾加不加“函数”都可以)。这个名称表明它的选项是离散的(如整数),而不是连续的(如实数)。

我们可以很容易地创建连续的概率分布。假设我们想知道汽车垃圾场场主展示给我们的每辆车里还剩下多少油,油量就是一个连续的变量,因为它可以取任意的实数(当然,是测量仪器可测范围内的实数。这里假设测量是如此精确,以至于我们可以把它看作连续值)。

图2.5显示了汽油测量的连续图。这幅图展示了不同返回值的概率,不只是一些特定值,而是任意实数,这里这个实数是在0(油箱是空的)和1(油箱是满的)之间的。

图2.5 一个连续范围内值的概率分布,所有概率之和仍然是1。注意,纵轴范围为0~0.018

像图2.5这样的分布称为连续概率分布(continuous probability distribution,cpd)或概率密度函数,后一个术语也被缩写为pdf,但是上下文通常会清楚地表明缩写所指代的内容。

图2.5显示了从0到约0.02的输入值,但输入是可以跨越任何范围的,唯一的条件与之前一样,即图表必须进行归一化,这意味着所有值加起来必须等于1。当曲线连续时,曲线下方面积为1。

大多数情况下,我们是通过选择一个符合自身要求的分布来使用随机数的,然后调用库函数来从这一分布中产生一个值(也就是说,我们从给定分布的随机变量中抽取了一个值)。

我们可以在需要的时候创建自己的分布,但是大多数库会提供一些分布。这些分布基本上可以涵盖大多数情况。这样我们就可以使用这些预先构建的、预先归一化的分布来控制随机数。

实践中的随机数

我们一直在讨论通过一个分布来构建一个随机数,这里有必要暂停一下,来看看这个概念在理论与实践表现中有什么不同。

这里的“随机”指的是“不可预测的”,不仅是说这个数字很难预测,比如一个灯泡能用多久。因为如果有足够的信息,我们就能算出灯泡的使用寿命。但是相比之下,随机数从根本上来说就是不可预测的(要得出一个数字或一串数字何时从“难以预测”转变为“不可预测”是一个很大的挑战,远远超出了本书[Marsaglia02]的范畴)。

使用计算机很难得到不可预测的随机数[Wikipedia17b],问题在于正常运行的计算机程序是具有确定性的(deterministic),这意味着给定的输入总是会产生相同的输出。所以从根本上说,如果我们能够访问源代码,那么一个计算机程序永远不会出乎我们的意料。给我们“随机数”的库的例程也只是一些程序。和其他程序一样,每当我们调用这些例程时,如果足够仔细地观察它在做什么,就能够预测它的返回值,换句话说,这并不是随机的。为了强调这一点,我们有时把这些算法称为伪随机数生成器,称它们产生的是伪随机数(pseudo-random number)。

假设我们正在编写一个使用伪随机数的程序,随后出现了一些问题。为了调试这个问题,我们希望它再次按照相同的操作形式运行,换句话说,我们希望它返回错误发生时使用的伪随机数流。

我们之所以能做到这一点,是因为伪随机数生成器以序列的形式生成它们的输出,每个新的值都建立在对以前的值的计算之上。为此,我们会给这个例程一个名为种子的数字。许多库的程序都是从一个种子开始的,这个种子来自当前的时间,或者是从鼠标指针移动那一刻起的毫秒数,抑或是其他我们无法预先预测的值,这使得第一个输出变得不可预测,并为下一个输出奠定了基础。

因此,在开始要求产生输出之前,我们可以手动设置种子,这样在每次运行程序时,都会得到相同的伪随机数序列。

如果我们不想的话,就不需要设定种子。随机数字可以通过不断变化、不可预知的场景照片来生成,就像熔岩灯墙[Schwab17]那样。真实的随机数也可以通过真实的物理数据来在线获取,例如大气噪声导致的天线上的静电干扰[Random17]。通常,以这种形式获取值要比使用内置的伪随机数生成器慢得多,但是当我们需要真正的随机数时,这就是一种选择。

一种可能的折中方法是从物理数据中收集一组真正的随机数,然后将它们存储在文件中。之后,就像使用只有一个种子的某个伪随机数生成器一样,每次都会得到相同的值,但我们知道这些值是随机的。当然,每次使用相同的数字序列意味着它们不再是不可预测的,因此这种技术在系统的设计和调试阶段可能会显得尤为有用。

在实践中,我们很少使用前缀“伪”来表示软件生成的随机数,但要记住是有这么一个东西存在的,因为每个伪随机数生成器都存在一些风险,它们创建的数字可能具有一些可辨别的模式 [Austin17],而这些模式可能会对学习算法产生影响。幸运的是,一个不可预测的种子和一个精心设计的伪随机算法的结合就可以为我们提供一系列值来很好地模拟所需的真正随机数。也许随着机器学习的发展,一些算法将会出现,它们会对“接近”随机的数字序列和真正随机的数字序列之间的差异表现得很敏感,这可能会迫使我们采取新的策略来生成这些值,而现在似乎还没到那个时候。

2.3 一些常见的分布

目前,我们已经了解了随机数的来源,以及如何使用随机变量从分布中选择值。现在让我们来看看一些流行的分布,这些分布通常用于生成机器学习算法中使用的随机数。

大部分的这些分布都是作为内置例程由主要的库提供的,因此可以很容易加以指定和使用。

我们用连续(continuous)的形式来展示这些分布,而大多数库会提供分布的连续和离散两个版本,或者可能会提供一个通用的例程,让我们可以根据需要将任何连续的分布转换为离散版本。

2.3.1 均匀分布

图2.6所示为均匀分布(uniform distribution)的例子。基本的均匀分布是:除了0和1之间,其他区间的值都是0,0~1的值是1。0和1这两个数字正好在两个定义交界的地方,这里我们把0和1处的值都设为1。

图2.6 一个均匀分布的例子。在这个版本中,0~1的输入(包括0和1)所产生的输出都是1, 而其他输入产生的输出都是0。按照惯例,图中不可见的部分被假定为图两端的输入所显示的值,因此图中所示区域的右侧和左侧的输入处处为0

在这个图中,看起来0处有两个值,1处也有两个值,但其实不是这样的,我们的惯例是:非实心的圈(如下方线上的圈)表示“这一点不是直线的一部分”,而实心圈(如上方线上的圈)表示“这一点是直线的一部分”。因此,在输入值0和1处,图形的输出是1。

这是一个常见的定义,但是有些方式会使得其中一个或者两个输出为0。这通常需要做一些检查。

这种分布有两个基本特性:首先,我们只能得到0~1的值,因为所有其他值的概率都是0;其次,0~1的每个值都是等可能的,我们得到0.25、0.33或0.793718的概率是一样的。

我们说图2.6所示的值在0~1的范围内是分布均匀的,或者说它们是常数(constant),抑或说是平面(flat)的。这告诉我们,这个范围内的所有值是等概率的。我们也说它们有限的(finite),意思是所有非零值在某个特定的范围内(即可以肯定地说0和1是它能返回的最小值和最大值)。

通常,创建均匀分布的库函数会允许我们去选择非零区域开始和结束的地方,而不是固定在0和1。除了默认的0~1的选项,最受欢迎的应该是−1~1,库会对一些细节进行处理,比如调整函数的高度来使其下方的面积始终为1(这是将任何图表转换为概率分布的条件)。

2.3.2 正态分布

在均匀分布之后,下一个最流行的分布可能是正态分布(normal distribution),也叫作高斯分布(Gaussian distribution),或者简单地称其为钟形曲线(bell curve)。与均匀分布不同,正态分布的曲线是平滑的,没有尖锐的拐角或者突然的跳跃。图2.7显示了一些典型的正态分布。

图2.7 一些典型的正态分布。其基本形状可以向左或向右移动,也可以在高低间进行缩放,抑或将其进行拉伸或压缩。总之,经过这些变换后,它也仍然是正态分布的。(a)典型正态分布;(b)正态分布的中心移动到1;(c)正态分布的中心移动到−1,同时形状变得更加狭窄,为了使曲线下方的面积保持在1,库会自动调整图形的垂直比例;(d)正态分布的中心移动到−1,同时形状变得更加宽大,同样,为了使曲线下方的面积保持在1,库会自动调整图形的垂直比例,因为图形更宽了,所以高度降低

图2.7中的4条曲线形状基本相同,形状的变化只是由曲线的水平移动或是水平缩放(即拉伸或压缩)引起的。这种水平缩放使得库自动地在垂直方向缩放曲线,因此曲线下方的面积加起来始终是1。

其实垂直缩放对我们来说并不重要,因为我们只关心样本的输出。图2.8显示了我们从每个分布中提取到的一些有代表性的样本。可以看到,它们聚集在分布的值比较高的地方(也就是说,得到一个有着这些值的样本的概率比较高)较多,而在分布的值比较低的地方(得到一个有着这些值的样本的概率比较低)较少。这些点(代表样本值)在垂直方向的上下起伏是没有意义的,只是为了便于观察。

对于正态分布来说,除了平滑隆起的区域,其他位置都近乎为0。不过,当接近凸起的两端时,其值会越来越接近于0,但从未达到0。所以我们说,这个分布的宽度是无限的(infinite)。在实际操作中,我们有时会将偏离中心点一定距离的值夹断(clamp),并假设超出该距离的部分为0,从而得到一个有限的分布。

正态分布在很多领域(包括机器学习)都很流行,因为从生物学到天气的大量实际测量的观察,人们发现它们的返回值都遵循正态分布。同时,正态分布的数学性质在很广泛的领域都很容易使用。

使用符合正态分布的随机变量产生的值被称为正态分布集(normally distributed),有时也被称为正态偏差(normal deviation)。我们也说它们拟合(fit)或者遵循正态分布。

图2.8 每个点的水平位置展示了从各个分布中提取到的样本值,点的垂直位置没有什么特殊含义,只是为了让它们更容易区分

每个正态分布由两个数字定义:均值(凸起的中心的位置)和标准差(standard deviation)(形状的水平拉伸或压缩)。

均值告诉我们凸起的中心的位置,图2.9显示了图2.7中的4个正态分布以及它们的平均值。正态分布一个很好的性质是:它的均值同时也是中位数和众数。

图2.9 正态分布的均值是凸起的中心的位置,这里用竖线表示

标准差则是一个数字,通常由小写希腊字母σ(sigma)表示,用于表示凸起的宽度。想象一下从凸起的中心开始对称地向外移动,直到囊括曲线下方68%的面积,那么从凸起中心到该区域的任意一端的距离就是标准差,所以“标准差”只是一个距离。图2.10显示了4个正态分布,其中一个标准差是用中心到阴影区域的任意边的距离表示的。

图2.10 标准差是衡量一个正态分布的“拉伸”程度的指标,阴影区域显示的是曲线下方的面积。阴影部分约占总面积的68%,从均值(或者说中心)到阴影区域任意边的距离就是正态分布的标准差

如果再对称地从中心向外移动一个标准差,就会将曲线下约95%的面积封闭起来,再对称地从中心向外移动一个标准差,就会将曲线下约99.7%的面积封闭起来,如图2.11所示。因为是使用的标准差σ,所以这个性质有时会被称为3σ法则,有时也被称为68-95-99.7法则

图2.11 标准差可以帮助我们求出事件发生的概率。沿着横轴距离均值一个标准差的范围内的点(如果均值是0,那么范围就是(−σσ))占所有值的68%左右,而两个标准差范围内的点则占所有值的95%左右,3个标准差范围内的点占所有值的99.7%左右

换句话说,如果由正态分布绘出了1000个样本,就有大约680个样本将分布在距离均值不超过一个标准差的范围内(或者是在−σσ的范围内),大约950个样本将分布在距离均值不超过两个标准差的内(或者是在−2σ~2σ的范围内),大约997个样本将分布在距离均值不超过3个标准差的内(或者是在−3σ~3σ的范围内)。

总之,均值显示了曲线的中心位置,而标准差显示了曲线的伸展情况。标准差越大,曲线就会越宽,因为68%的截断距离会变得更远。

有时人们用一个不一样但与之相关的值来代替标准差,这个值称为方差(variance)。方差就是标准差自身的平方,有时在计算中这个值使用起来会更方便。

正态分布的吸引力不仅在于它的数学性质,还在于它自然地描述了许多真实世界的统计数据。如果我们测量一些地区成年男性的身高、向日葵的大小抑或果蝇的寿命,就会发现这些数据都趋于正态分布。

2.3.3 伯努利分布

另一个有用的特殊分布称为伯努利分布(Bernoulli distribution),这个离散分布只返回两个可能的值:0和1。伯努利分布的一个常见例子是抛掷硬币得到正反面的分布。

我们用字母p来描述得到1的概率。由于两个概率相加必须得1(忽略奇怪的着陆情况,硬币必须正面或反面着陆),这意味着返回0的概率是1−p

图2.12直观地显示了抛掷一枚质地均匀的硬币和一枚质地不均匀的硬币的情况。

(a)                (b)

图2.12 伯努利分布告诉我们得到0或1的概率。(a)在每次抛掷一枚质地均匀的硬币时,获得正面或反面的概率相等;(b)抛掷一枚质地不均匀的硬币出现反面的概率是70%,出现正面的概率是30%

我们可以把这两个值标记为0和1(或者是正面和反面)以外的东西,例如,如果我们在看照片,它们就可能是一张猫的照片和一张不是猫的照片。

如果我们画出了大量的值并找到它们的均值,那么这很可能就是该分布的均值。伯努利分布的均值是p。关于伯努利分布的众数和中位数的描述有点麻烦,此处不再赘述。

伯努利分布似乎有点过于简单了,因为它描述的是一种简单的情况。它的价值在于:它给了我们一种方法来表示得到一个分布的两个值中任意一个的概率,所以使用了与本节中其他分布相同的形式来表达。这意味着我们可以使用与处理复杂分布时相同的方程和代码来处理这种更简单的情况。

2.3.4 多项式分布

伯努利分布只返回两个可能值中的一个,但是假设我们正在做一个实验,需要从更多的数字(或者说更多的可能性)中返回一个呢?例如,我们不再进行只可能出现正面或反面的抛掷硬币,而是改为抛掷一个20面的骰子,就会得到20个值中的任意一个。

为了模拟抛掷骰子的结果,随机变量需要返回1~20中的一个数字。在这种情况下,构建一个列表是很有效的。列表中除了我们取出的那一项(它被设为1),其他项都为0。当我们构建机器学习系统来将输入分为不同的类别时,构建列表会非常有用,例如描述照片中出现的是50种不同动物中的哪一种。

下面我们来演示这个想法。假设我们要从5个值中进行选择,于是将它们标记为1、2、3、4和5。如果要返回的是4,就会返回一个包含5个数字的列表,除了第4个位置的1,其他位置的数字都是0,这个列表是“0,0,0,1,0”。

每当要从这个随机变量中抽取一个值时,我们就会得到一个包含4个0和1个1的列表。每个位置是否为1的概率是由选项1~5中被选择的概率给出的。

这个分布的名称是一个合成词(或者说是两个词的混合),因为这是对两种输出的伯努利分布的推广,将其推广为多项输出。我们可以称之为“多项式伯努利分布”,但是若把这些词混在一起,就称之为多项式分布(multinoulli distribution),有时也简单地称之为类别分布(categorical distribution)。

我们可以使用多项式分布来猜测生日,奇怪的是,所有生日的概率并不都是一样的,至少在美国2000年前后的10年内是这样的[Stiles16]。我们可以用一个多项式分布表示365个可能的生日的概率。如果我们从这个分布中抽取一个随机变量,就会得到一个拥有365个值的列表,除了一个1,其他的都是0。如果我们一遍又一遍地这样做,1就会更频繁地出现在更有可能的出生日期那里。

2.3.5 期望值

如果我们从任意的概率分布中选择一个值,然后选择另一个,之后再选择一个,随着时间的推移,我们就能构建一个包含很多值的列表。

如果这些值是数字,那么它们的平均值就称为期望值(expected value)。注意,期望值可能不是从分布中提取的值!例如,如果1、3、5、7都是等可能的,那么我们对于这些将要提取的随机变量的期望值就是(1+3+5+7)/4(即4),这个值我们永远无法从分布中得到。

2.4 独立性

到目前为止,我们所看到的随机变量都是完全不相关的。我们从一个分布中抽取一个值的动作与我们之前抽取过其他任何的值都没关系,每次都是在一个全新的世界抽取一个新的随机变量。

我们称这些变量为自变量(independent),它们不依赖于任何其他的值。这种变量是最简单的随机变量,因为我们不用考虑两个或多个随机变量是如何相互影响的。

相反,有的随机变量是相互依赖的。例如,假设我们有几种不同动物的毛发长度的分布:狗、猫、仓鼠等。我们需要先从动物列表中随机选择一种动物,然后据此来选择适当的毛发长度分布,之后从这个分布中得到一个值并以此作为动物毛发的值。在这里,对动物种类的选择不依赖于其他因素,所以它是一个自变量。但是毛发长度取决于所选择的动物,所以它是一个因变量(dependent)。

独立同分布(i.i.d)变量

许多机器学习技术中的数学和算法都是被设计来处理从具有相同分布的随机变量中提取的多个值的,并且这些值之间相互独立。

这种要求已经非常普遍了,以至于这些变量都有了一个特殊的名称i.i.d,即独立同分布(independent and identically distributed)(这个首字母缩略词很不同寻常,因为它几乎都是用小写字母书写的,字母之间用句点隔开)。例如,我们可能会看到用这种方法描述的一种技术:“当输入为i.i.d时,该算法会提供最好的结果。”

而短语“同分布”只是“从相同分布中选择”的一种简洁的表达方式。

2.5 抽样与放回

在机器学习中,我们经常通过随机选择现有数据集中的一些元素来构建新的数据集。我们将在2.6节中进行这种操作,并寻找样本集的均值。

让我们考虑两种不同的方法来通过现有数据集生成新数据集,其中关键的问题是:从数据集中选择一个元素时,我们是将它从数据集中移除,还是仅复制这个元素并使用它?

打个比方,假设我们去图书馆找几本短篇书,为了保持趣味性,我们把它们放在桌子上堆成一小堆,之后从中随机挑选。

一种方法是从书堆中随机选择一本书,之后把它带回并放到桌子上,然后再回到书堆进行挑选,这样我们就可以挑选出一堆随机选择的书了。注意,因为我们已经把挑选出的每一本书都放在桌子上,所以不可能选到同一本书两次(我们可以选择已经选过的书的另一印本,但已经不是同一本书了)。

另一种方法是从书堆里选择一本书,并将整本书复印(只是做一个比喻,我们暂时忽略法律和道德问题),然后把书放回它原来的地方,并把影印本放在桌子上。然后我们返回书堆,再一次随机拿起一本书、复印、归还之后把它放入书堆里,一遍又一遍,这样我们就拥有一堆复印的书了。注意,我们将在复印之后把每本书还回书堆,这种情况下,是有可能选到同一本书并把它复制两次的。

在机器学习中,构建新数据集时,我们可以遵循这两种方法中的任何一种。每从训练集中选择一个数据,我们可以从数据集中删除它(这样我们就不能再选择它了),也可以只是复制它并将它返回到数据集(这样我们就可以再次选择它)。

上述两种方法所得到的结果是全然不同的类型,无论是从明显的表面还是从不那么明显的统计数据上都可以看得出。一些机器学习算法被设计成只适用于这两种方法中的一种。那么现在就让我们更仔细地看一看这些备选方案。我们想要创建一个选择列表,而这个列表是从一个初始对象中选择出来的。

2.5.1 有放回抽样

首先,让我们看一下对元素进行复制的方法,在这里,初始状态是保持原样的,如图2.13所示。我们把这种方法称为有放回抽样(或称为SWR),因为我们可以认为是将元素取出,为其制作一个副本,用副本替换原来的元素。

有放回抽样最明显的一个含义是:我们可能会多次使用同一个元素。在极端情况下,整个新建立的数据集都是一个元素的多个副本。

第二个含义是,我们可以创建一个比原始数据小的、大小相同的抑或更大的新数据集。由于原始数据集并不发生改变,因此只要我们愿意,就可以不断地选择元素。

图2.13 有放回抽样。每从池中移除一个元素,都会将它的一个副本放入选择区域中,然后再把原来的元素放回池中。通过这种技术,我们可以建立选择列表,但是原始的池是不会改变的,所以我们就有机会多次选择一个相同的项。在这个例子中,我们两次选择了元素C

这一过程的统计学含义是:选择是相互独立的。没有任何过去的背景,选择完全不受之前的选择的影响,也不会影响未来的选择。

要明白这一点,让我们看看图2.13所示池中的8个元素,每个元素被选中的概率都是1/8。可以看到,我们首先选择的是元素C。

现在新数据集里有了元素C,但是在选择之后,我们会把这个元素“重置”回原来的数据集中,再次查看原始数据集时,8个元素仍然全部存在,如果再次进行选择,每个元素仍有1/8的概率被选中。

这种采样的一个日常例子是:在库存充足的咖啡店里点一杯咖啡,比如我们点了一杯香草拿铁之后,香草拿铁这个选项也不会从菜单上被删除,还可供其他顾客选择。

2.5.2 无放回抽样

另一种通过随机选择去构建新数据集的方法是:从原始数据集中删除所选择的元素,并将其放到新数据集中。因为没有进行复制,所以原始数据集丢失了一个元素。这种方法称为无放回抽样(又称为SWOR),如图2.14所示。

图2.14 无放回抽样。每从池中移除一个元素,我们就会将其放入所选择的区域。因为没有把它重新放回池中,所以无法再次选择这一元素

让我们比较一下SWR与SWOR的含义。首先,在SWOR中,对任何元素的选择都不能超过一次,因为我们从原始数据集中删除了它。其次,在SWOR中,新数据集可以比原来的更小,或者是大小相同,但是不能变得更大。最后,在SWOR中,选择是相互依赖的。图2.14中,每个元素第一次被选中的概率为1/8。但是当选择元素C后,我们没有用副本替换它,所以如果回到原始数据集,就只剩下7个元素可用,即每个元素有1/7的概率被选中。选择这些元素中的任何一个的概率都增加了,因为可供选择的元素变少了。

如果再选择另一个元素,剩下的每个元素就都有1/6的概率被选中,以此类推。在选择了7个元素后,最后一个元素被选中的概率就有100%。

无放回抽样的一个常见示例是玩扑克牌游戏,每发一张牌,它就会从整副牌中“消失”,在重新收回牌或是洗牌之前是无法再发出的。

2.5.3 做选择

假设我们想通过从原始数据集中选择来构建一个比原始数据集小的新数据集,可以采用有放回抽样和无放回抽样两种方式。

与无放回抽样相比,有放回抽样可以产生更多可能的新数据集,让我们来看看这一点。假设原始数据集中只有3个对象(A、B和C),而我们需要一个包含两个对象的新数据集。采用无放回抽样只能得到3种可能的新数据集:(A,B)、(A,C)和(B,C);而采用有放回抽样,不仅可以得到这3个,还可以得到(A,A)、(B,B)和(C,C)。

一般来说,有放回抽样总是可以为我们提供一组有更多可能性的新数据集。还有很多关于统计特性的有趣差异,但是我们不展开讨论。

要记住的重要一点是:“是否放回”会对构建新数据集产生影响。

2.6 Bootstrapping算法

有时我们想要知道某个数据集的一些统计数据,但是这个数据集太大了,对它进行操作并不可行。打个比方,假设我们想知道现在世界上所有活着的人的平均身高。对于这个问题,没有一种切实可行的方法去测量每个人的身高,所以我们需要另一种方法。

通常我们会选取数据集的一部分来解答这类问题,然后对这一部分进行测量。我们可以求出几千人的身高,然后通过计算这些测量值的均值来近似求出所有人的平均身高。

我们把世界上的所有人称为总体(population)。因为人数太多,所以我们会从中归纳出一个规模合理的群体。我们希望这个群体能代表总体,故将这个较小的群体称为样本集(sample set)。样本集是在无放回的情况下构建的,因此每从总体中选择一个值并将其放入样本集,这个值在总体中就会被删除,不能再次被选择。

通过仔细认真地构建样本集,我们希望就所要度量的属性而言,这个样本集可以成为总体的合理代表。图2.15用21个元素表达了总体的概念,样本集则包含了来自总体的12个元素。

(a)                          (b)

图2.15 从总体中创建了一个样本集。(a)总体,在本例中,总体包含21个元素;(b)样本集,在本例中,样本集只包含12个元素

现在我们测量样本集的均值,以此作为总体均值的估计值。在这个小例子中,我们可以计算出总体的均值,大概是4.3,而样本集的均值约为3.8,这一匹配并不是很完美,但也不算是大错特错。

大多数情况下,我们无法测量总体的值(这是一开始我们构建样本集的原因),所以只能通过找到样本集的均值得到答案。但是,这个样本集表现得有多好呢?它是我们可以依赖的对总体的一个好的估量吗?很难说。

如果可以用置信区间(confidence interval)来表示结果,就更好了。虽然目前我们还没有深入讨论这个概念,但是可以对置信区间做一个表述:“我们有98%的概率确定总体的均值在3.1和4.5之间。”

要做出一个这样的表述,我们就需要知道区间的上界和下界(在这里是3.1和4.5),并衡量我们对该值存在于该区间范围内信心的大小(这里是98%)。通常,我们会为当前的任务设定一个所需的信心,然后再找到该信心所对应的范围的上下值。

Bootstrapping算法可以帮助我们找到让我们表达信心的值[Efron93] [Ong14]。我们可以像之前说的身高的例子那样利用它来讨论均值。同时,我们也可以用Bootstrapping来表示对于标准差的信心,又或者用我们感兴趣的其他统计学度量。

这个过程包括两个基本步骤:第一步是我们在图2.15中看到的那样,根据原始的总体创建一个样本集;第二步则涉及对样本集进行重采样(resampling)以生成一些新数据集,而这些新数据集中的每一个都称为bootstrap

为了创建bootstrap,我们先要确定需要从初始样本集中选择多少元素。尽管我们通常使用较少的元素,但是理论上可以选择小于样本集数据量的任意数量的元素。然后我们会从样本集中有放回地随机抽取多个元素(在这里,我们可能会多次选择相同的元素)。这个过程如图2.16所示。

图2.16 创建bootstrap。样本集有12个元素,而每个bootstrap有5个元素,即每个bootstrap从样本集中有放回地随机选择了5个元素

抽取必须要是有放回的,因为我们可能想要构建与样本集大小相同的bootstrap。在本例中,我们可能会设定每个bootstrap中包含12个值,如果不进行有放回的抽取,那么每个bootstrap都将与样本集相同。

有了这些bootstrap,我们就可以测量它们每一个的均值。如果我们在直方图上画出这些平均值(图2.17),就会发现,如之前讨论过的那样,它们倾向于形成一个高斯分布。这个结果是自然形成的,与选择的具体值无关。就这个图来说,总体是0~1000的1000个整数,之后我们从这个数据集中随机抽取500个值来创建一个样本集,然后又创建了1000个bootstrap,每个bootstrap包含20个元素。

图2.17 直方图展示了具有给定平均值的bootstrap的数量,在490左右的蓝色竖线是样本集的均值,在500左右的红色竖线是总体的均值

既然已经知道了总体,就可以计算它的均值,大约是500。样本集的均值也非常接近总体的均值,大约是490。bootstrap则帮助我们确定:我们应该在多大程度上信任490这个值。

无须进行数学计算,bootstrap均值近似于高斯曲线,它会告诉我们需要知道的一切。假设我们想找到有着80%的置信区间,它将包含总体的均值,就只需要去掉bootstrap值中最低的和最高的10% [Brownlee17]。图2.18显示了一个方框,画出了我们认为置信区间有80%的值,其中包含已知的真实值500。可以看到,我们有80%的信心去确定总体的均值在410和560之间。

回顾一下,我们想知道一些描述总体性质(可能是其均值或方差),假设由于某种原因,我们不能对总体进行操作,因此不能直接测量这种性质。为了得到这些值,我们通过抽取总体中的一些值形成了一个样本集,然后再从中选出一些bootstrap(每个bootstrap通过对样本集元素进行有放回的采样得到)。通过观察bootstrap的统计数据,我们就可以得到一个置信区间,从而知道我们有多大的信心去确定总体的均值是否在某个区间中。

bootstrap是很吸引人的,因为我们可以使用小型的bootstrap(每个bootstrap可能只包含10个或20个元素),这种小容量意味着对每个bootstrap程序的构建和处理都可以非常快地进行。为了弥补这种小容量的缺点,我们经常会构建数千个bootstrap。所构建的bootstrap越多,结果就越接近高斯曲线,也就越能精确地确定置信区间。

在后续章节中,我们将再次使用bootstrap的思想来从更简单的工具集合中构建强大的机器学习工具。

图2.18 我们有80%的信心去确定这个方框里包含总体的均值

2.7 高维空间

我们通常会认为各种各样的物体占据着(或者说“生活在”)一个或另一个想象的、抽象的空间。有些空间会有成百上千的维度,以至于我们无法绘制出。但是,因为我们将经常谈论这样的“空间”,所以需要对此类空间的含义有一个大致的了解,这很重要。

这一空间的基本含义是,空间的每个维度(或者轴)都指向一种单独的度量方式。如果我们有一段数据,这段数据中只有一个测量值(如温度),就可以用一个只有单个值的列表来表示它。从视觉上,我们仅用一条线就可以表示测量值的大小,如图2.19所示。我们将这条线称为一维空间(one-dimensional space)。

(a)                         (b)

图2.19 具有单个值的数据段只需要一个轴(或者说维度)就可以绘制。(a)我们通常用x表示横轴;(b)包含3段数据,其相对应的线表示它们的大小,从x轴的左边开始测量

如果我们有两段信息,如温度和风速,那么需要两个维度(或者一个有两项的列表)来保存数据。我们可以通过两个轴进行表示,如图2.20所示。点的位置是这样确定的,沿x轴移动测量得到第一个度量值,然后沿y轴移动测量得到第二个度量值。我们称之为一个二维空间(two-dimensional space)。

(a)                    (b)

图2.20 如果数据有两个值,我们就用两个维度(或者说轴)来绘制它。(a)我们通常用y表示垂直方向;(b)包含4段数据,每段数据在二维空间中的位置都由两个值确定,一个值代表x,而另一个值代表y

如果每段数据有3个值,那么需要一个可以容纳3个值的列表,而这3个维度可以用3个轴来表示,如图2.21所示。我们称之为三维空间(three-dimensional space)。

(a)                        (b)

图2.21 如果每段数据有3个值,就用3个维度(或者说轴)去绘制它。(a)一般第3个轴的方向是垂直于纸面进出的,并标记为z;(b)三维空间中的一些点,我们通过它们所在位置沿xyz轴的长度定位它们。其中的盒子只是为了帮助我们看到点在立方体中的位置

如果有4个值呢?尽管做出了很多大胆的尝试,但是仍然没有一种可以被广泛接受的方法来绘制四维空间,尤其是在二维空间上进行绘制([Banchoff90]和[Norton14])。当上升到五维、十维或是二十维的空间时,二维空间更是限制我们的一大原因。

这些高维度空间看起来似乎很深奥、很罕见,但实际上它们很常见,我们每天都可以见到。为了证实这一点,让我们考虑一下用什么样的空间来表示一张照片。

假设有一个灰度图像是500像素×500像素的,那么该用多大的空间来表示这个图像呢?一条边上有500个像素,那么整个图像就是500像素×500像素=250000个像素。其中的每个像素都包含一个值,或者说它们都包含一个度量值。从整个空间的一个角落开始,向右移动(沿着x轴)第一个像素值给定的距离,然后向上移动(沿着y轴)第二个像素值给定的距离,再向后移动(沿着z轴)第三个像素值给定的距离,之后沿着第四个轴移动由第四个像素给定的距离。以此类推,随后是第五个轴、第六个轴等,让每个像素都沿着它们相对应的轴移动,这些轴都是不同的。

因为有250000个像素,所以需要250000个维度。这是一个很大的维度!有时,每个像素也可能需要3个值,就需要3 × 250000=750000个维度。

我们画不出750000维的图像,甚至无法在脑海中描绘出一个维度如此多的图像。但是,机器学习算法可以像处理二维或三维空间那样轻松地处理这样的空间。数学和算法并不关心一个空间有多少个维度。

要记住的关键是:在这个庞大的空间中,每条数据都是单独的点,就像二维空间中的点用两个数字告诉我们它在平面上的位置一样,750000维空间中的点只是用750000个数字告诉我们它在这个庞大空间中的位置。因此可以说,图像是由一个巨大的“图像空间”中的一个点表示的。

我们把有很多维度的空间称为高维空间(high-dimensional space),而对于多少维才算“高”维这一点,目前还没有一个正式的、统一的规定,但是这个短语常用于描述那些超出我们可以合理绘制的范围的空间,也就是高于三维的空间。当然,大多数人认为数十或数百个维度才称得上“高”维。

本书所用算法最大的优点之一就是:它们可以处理任意维度的数据,甚至可以处理近一百万维的图像。当涉及更多的数据时,算法的运行速度会变慢,但是它运行的流程不会发生任何更改。

本书频繁使用的数据可以被抽象成高维空间中的点。我们会侧重于对刚刚看到的概念进行直观的概括,而不是深入数学中。我们会把“空间”看作对直线、正方形和立方体的巨大(无法可视化的)类比,其中每段数据都由用一个点表示。

2.8 协方差和相关性

有时变量之间可能相互关联,例如,一个变量告知我们室外温度,另一个变量告知我们是否会下雪。如果温度很高,就不会下雪,所以通过对其中一个变量的了解可以知道另一个变量的一些信息。在这种情况下,这种关系是负相关的:随着温度的升高,下雪的可能性降低;反之,下雪的可能性升高。

而另一个变量也可能是在告诉我们在当地河里游泳的人的人数,温度和游泳人数之间的联系就是正相关的,因为在温暖的日子里我们会看到更多人游泳,反之,则没有那么多人游泳。

能够找到这些关系并确定两个变量之间的联系的紧密程度是很有用的。

2.8.1 协方差

假设有两个变量,我们注意到它们之间有一个特定的模式:当其中任意一个变量的值增加时,另一个变量的值就会以这个增加数量的固定倍数增加;而当任意一个变量减小时,同样的事情也会发生。例如,假设变量A增加3,变量B就增加6;之后,B增加4,A会增加2;然后A减小4,B会减小8。在每一个例子中,B增加或减小的量都是A增加或减小的量的2倍,所以固定倍数是2。

如果我们在两个变量之间发现了这样的一种关系(任何倍数都可以,而不仅是2),就称这两个变量是共变的,我们用协方差(covariance)来衡量两个变量之间的这种联系的强度。

如果我们发现一个值增加而另一个值也增加,那么协方差就是一个正数。这两个变量的步调越一致,协方差就越大。

讨论协方差的经典方法是绘制一个图,并在这个二维图形上绘制一些点,如图2.22所示。这种图称为散点图。坐标轴被标记为xy,用于替代我们感兴趣的两个变量。

(a)                       (b)

图2.22 对协方差的阐述。(a)沿x轴从左到右的每一对点在y轴方向上的变化量大致相同,这是正的协方差;(b)x轴方向的值有一点多变,说明正协方差较弱

假设x是第一个值,y是第二个值。如果x增加时(在图2.22中是指点向右移动)y也增加(在图2.22中是指点向上移动),就说这两个变量有着正协方差(positive covariance)。y的变化与x的变化越一致,协方差就越大。

一个非常大的正协方差表明这两个变量是一起变化的,所以每当它们中的一个改变了一个给定的量,那么另一个也会改变一个不完全相同但是又趋于一致的量。

此外,如果一个值随着另一个值的增加而减小,就说变量有负协方差(negative covariance),如图2.23所示。

(a)                       (b)

图2.23 x轴方向上相邻两点在y轴方向上的变化总是大致相同的,但是当x变大时,y就会变小,这种形式的关联就称为负协方差

如果两个变量之间完全没有一致的、能够相互匹配的变化,就说它们之间的协方差为0,如图2.24所示。

(a)                       (b)

图2.24 这两组数据点的协方差都为0。如果我们沿着x轴从一点移动到另一点,y值在大小和方向上的变化都没有一个统一的规律

我们所说的协方差思想只在变量之间的变化是彼此的倍数时才有效。如图2.24b所示,数据之间可能存在一个清晰的关系(这里的点构成了一个圆的一部分),但是协方差仍然为0,因为它们之间的变化是不一致的。

2.8.2 相关性

协方差是一个有用的概念,但存在一个问题:由于它的定义方式,它没有考虑过两个变量的单位,这使得我们很难确定数据之间的相关性的强弱。

例如,假设我们需要测量一把吉他上的12个变量:木头的厚度、琴颈的长度、音符共鸣的时间、琴弦的张力等。我们有可能找到这些测量值两两之间的协方差,但无法通过比较它们来确定哪一对数据的关系最强(或是哪一对最弱),因为它们的单位不同——木材的厚度可能以毫米为单位,琴弦共振的时间可能以秒为单位,等等。我们会得到每对测量值的协方差,但是无法比较它们。

我们实际能够了解到的只有协方差的符号:正值表示正相关,负值表示负相关,0 表示不相关。

只有符号能为我们提供价值是有问题的,因为我们想要比较不同的变量集。那样我们才能从中找到有用的信息,如哪些变量之间有着最强的正相关和负相关,而哪些变量之间有着最弱的正相关和负相关。

为了得到一个可以进行上述比较的度量值,我们可以通过计算得到一个与之前稍稍不同的数字,称为相关系数(correlation coefficient),或者称相关性(correlation)。这个值只要在计算协方差时增加一个步骤就能得到。通过这步计算,我们会得到一个不依赖于变量单位的数字。我们可以把相关系数看作缩小版的协方差,其值在−1~1。

由于相关系数很好地避免了单位的问题,因此要比较不同变量集合的关系的强度时,相关系数就是一个很好的工具。

因为相关系数永远不能超出−1~1这个范围,所以我们只需要关心1、−1和它们之间的值。“1”说明数据完全正相关(perfect positive correlation),而“−1”说明数据完全负相关(perfect negative correlation)。

完全正相关的数据很容易看出来:所有点都沿着一条直线下降,从东北角到西南角,如图2.25所示。

(a)                      (b)

图2.25 两相邻点之间向右移动和向上移动的量是一样的,这两个图都展现了完全正相关关系(或者说相关系数为1)

那么,点与点之间什么样的关系会得到正相关关系,即相关系数在0和1之间呢?这种情况是:y值会随着x的增加而增加,但是增加的比例不会是常数,我们甚至无法预测这个增加比例会发生多大的变化,但是知道x的增加会导致y的增加,而x的减小也会导致y的减小。图2.26为一些相关系数在0~1的正相关的点的点图,这些点越接近直线,那么它们的相关系数就越接近1。如果这个值接近于0,相关性就很弱(或者说是很低);如果它在0.5附近,相关性就是中等的;如果它在1附近,相关性就很强(或者说是很高)。

(a)                     (b)                     (c)                       (d)

图2.26 正相关性逐渐降低的示例。从(a)中接近1的值开始,(b)、(c)、(d)中的相关性相继变低。一般来说,点离直线越近,相关性越高

现在我们看看相关系数为0时的情况。不相关意味着一个变量的变化与另一个变量的变化没有关系,我们无法预测接下来会发生什么(或者说下一个点的位置)。回顾一下就会发现,相关性只是协方差的缩小版,当协方差为0时,相关性也为0。图2.27展示了一些相关性为0的点。

(a)                           (b)

图2.27 这些点的相关性为0。这些点向右移动时,垂直方向上并没有出现一致的运动

负相关和正相关一样,只是变量是反向变化的:当x增加时,y减小。一些负相关的例子如图2.28所示。

(a)                (b)                (c)               (d)

图2.28 (a)为相关系数接近-1的情况。从(b)到(d),负相关系数逐渐向0靠近

与正相关类似,如果相关系数接近于0,相关性就很弱(或者说是很低);如果它在−0.5附近,相关性就是中等的;如果它在−1附近,相关性就很强(或者说是很高)。

最后,图2.29展示了数据集完全负相关的(或者说相关系数为-1)的情况。

(a)                       (b)

图2.29 这些图均为完全负相关(或者说相关系数为-1)。每向右移动到下一个点,下降的量均相同

还有几个术语值得一提,因为它们会不时地出现在文档和文献中。如前所述,对于两个变量的讨论通常称为单相关(simple correlation)。我们也可以找到更多变量之间的关系,这称为多重相关(multiple correlation)。如果我们有一堆变量,但是只研究其中两个变量是如何相互影响的,就称为偏相关

如果两个变量呈现完全正相关或是完全负相关关系(即相关系数的值为+1和−1),就称这两个变量是线性相关(linear correlation)的,因为(正如我们所看到的那样)所有点位于一条线上。其他任何相关系数描述的变量则称为非线性相关(non-linear correlation)的。

图2.30总结了线性相关中不同值的含义。

(a)                (b)                (c)                (d)              (e)

图2.30 线性相关中不同值的含义

2.9 Anscombe四重奏

本章的统计数据告诉了我们关于数据的很多信息,但并不意味着统计数据告诉了我们一切。

有一个我们被统计数据愚弄的著名例子:有4个不同的二维数据集合,它们看起来一点都不像,但都有相同的均值、方差、相关系数和拟合直线。这些数据以发明这4个数据集的数学家命名([Anscombe73]),称为Anscombe四重奏(Anscombe’s quartet)——它们的值可以在网上很轻松地获得([Wikipedia17a])。

图2.31展示了这4个数据集以及它们的最佳拟合直线。

图2.31 Anscombe四重奏中的4个数据集以及它们的最佳拟合直线

这4个数据集的惊人之处在于每个数据集中x值的均值均为9.0,y值的均值均为7.5,每组x值的标准差均为3.16,每组y值的标准差均为1.94。每个数据集中xy之间的相关系数均为0.82,而每个数据集的最佳拟合直线在y轴的截距均为3,斜率均为0.5。

换句话说,4个数据集的7个统计度量都具有相同的值。实际上,如果我们在这4幅图上延伸出更多数据,有的统计度量值就会产生不同,但是它们依然非常接近,所以几乎可以认为它们是一样的。

图2.32叠加了4个数据集中的所有点以及它们的最佳拟合直线。因为4条最佳拟合直线是一样的,所以我们在图中只能看到1条。

图2.32 Anscombe四重奏的4个数据集以及其最佳拟合直线的叠加

Anscombe四重奏的寓意是:不要认为统计数据透露了关于任何一组数据的全部情况。得到了一组数据的统计信息是一个很好的起点,但是统计数据不能告诉我们需要知道的一切。要想很好地利用数据,我们还需要仔细观察并且深入理解它。

这4个数据集虽然有名,但并不特别。如果我们想,就可以制作出更多具有相同(或近乎相同)统计数据的不同数据集([Matejka17])。

参考资料

[Anscombe73] F. J. Anscombe, Graphs in Statistical Analysis,American Statistician, 27. 1973.

[Austin17] David Austin, Random Numbers:Nothing Left to Chance, American Mathematical Society, 2017.

[Banchoff90] Thomas F. Banchoff, Beyond the Third Dimension: Geometry, Computer Graphics, and Higher Dimensions, Scientific American Library, W H Freeman, 1990.

[Brownlee17] Jason Brownlee, How to Calculate Bootstrap Confidence Intervals for Machine Learning Results in Python, Machine Learning Mastery blog, 2017.

[Efron93] Bradley Efron and Robert J. Tibshirani, An Introduction to the Bootstrap, Chapman and Hall/CRC Monographs on Statistics & Applied Probability (Book 57), 1993.

[Marsaglia02] George Marsaglia and Wai Wan Tsang, Some Difficult-to-pass Tests of Randomness, Journal of Statistical Software, Volume 7, Issue 3, 2002.

[Matejka17] Justin Matejka, George Fitzmaurice, Same Stats, Different Graphs: Generating Datasets with Varied Appearance and Identical Statistics through Simulated Annealing, Proceedings of the 2017 CHI Conference on Human Factors in Computing Systems, pgs 1290–1294, 2017.

[Norton14] John D. Norton, What is A Four Dimensional Space Like?, Department of History and Philosophy of Science, University of Pittsburgh, 2014.

[Ong14] Desmond C. Ong, A Primer to Bootstrapping, Department of Psychology, Stanford University, 2014.

[Random17] Random.org, Random Integer Generator, 2017.

[Schwab17] Katharine Schwab, The Hardest Working Office Design in America Encrypts Your Data-With Lava Lamps, Co.Design blob, 2017.

[Stiles16] Matt Stiles, How Common is Your Birthday? This Visualization Might Surprise You, The Daily Viz, 2016.

[Wikipedia17a] Wikipedia authors, Anscombe’s Quartet, 2017.

[Wikipedia17b] Wikipedia authors, Random Number Generation, 2017.

[Wikipedia17c] Wikipedia authors, Random Variable, 2016.

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e55451”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。

第3章 概率

概率用于描述我们对数据有多大的信心,以据此得出可以多大程度上信任系统所产生的结论。

3.1 为什么这一章出现在这里

概率是一种工具,用来帮助我们确定事件发生的可能性。零概率意味着事件不会发生,而100%的概率意味着事件肯定会发生。我们也可以用概率来表达信心,例如相信某个水果有80%的概率熟了,或者某支球队会赢得一场比赛。

概率是机器学习的支柱之一,许多论文会使用概率论的语言去描述技术,许多文档也会采用这种方式,例如,一些库函数会要求其输入数据具有一些基本的概率属性。为了正确地使用库以获得优质的结果,我们需要先对概率有足够的了解,然后再去阅读和理解这些描述。

概率是一门庞大的学科,有许多深奥的门类。像所有深奥的科目一样,学习概率中的新技巧意味着掌握新的知识,然而学得越多,就越能够意识到还有很多东西要去学习!

我们的重点是明智且良好地使用机器学习工具,因此只需要掌握一些基本术语和概念。本章涵盖了所有这些内容。换句话说,本章介绍的不是我们计算自己的统计数据可能用到的工具,而是一些概念——这些概念帮助我们更好地理解如何基于数据去使用工具,以达到预期。

本章将重点介绍概率的一些基本概念、我们经常使用的度量方法以及一个称为混淆矩阵的特殊应用。关于本章讨论的所有内容以及概率这一领域诸多其他内容的更广泛、更深入的讨论,读者可以参考专门研究概率的书([Jaynes03]和[Walpole11])。

3.2 飞镖游戏

飞镖游戏(dart throwing)是讨论基本概率时的经典示例。

这个例子最基本的想法是:我们在一个房间里,面对一堵墙站着,手里拿着若干枚飞镖。我们没有在墙上挂软木靶子,而是画了一些不同颜色和大小的区域。我们会把飞镖投掷到墙上,然后记下飞镖击中的颜色区域(背景也算是一个区域),如图3.1所示。

在这个场景下,假设飞镖总是会落到墙上的某个地方(而不是落到地板或天花板上),所以飞镖击中墙壁某处的概率是100%,这是一个确定的事情。

本章用数字和百分比来描述概率,1.0的概率对应100%,0.75的概率对应75%,以此类推。

现在,让我们更仔细地看一下投掷飞镖的场景。在现实场景中,飞镖更有可能投掷到正对着我们的那部分墙,而不是投掷到离我们很远的地方。但是为了当前的讨论,我们假设投掷到墙上的任何点的概率都是一样的。也就是说,墙上的每一个点都有同样的机会被飞镖击中。换言之,正如我们在第2章中讨论的,任何点被击中的概率都是由均匀分布给出的。这并不是很符合现实情况,但我们只是用飞镖游戏作为一个比喻,所以也不需要它和现实情况一样精确。如果我们考虑从很远的距离向一面很小的墙投掷飞镖,那么这种约束(假设)可能更容易被接受。

图3.1 向墙上投掷飞镖。墙上是各种颜色的颜料

接下来讨论的核心将以“对不同区域的比较”和“击中不同区域的概率”为基础。记住,背景也是作为一个区域存在的(在图3.1中,它是白色的墙)。

这里有一个例子,图3.2中的墙上有一个圆,当我们投掷飞镖时,已知击中墙的概率是1,那么击中圆的概率是多少?

图3.2 一定可以击中墙壁的前提下,击中圆的概率是多少

假设墙的面积是2m2,而圆的面积是1m2,即圆覆盖了墙的面积的一半。我们的规则是击中墙上每个点的可能性都相同,那么投掷飞镖时,就会有50%的机会(或者说0.5的概率)让飞镖落在圆内。这个值是通过面积的比值得到的。圆越大,它所包围的点就越多,被击中的可能性也就越大。

我们可以用一张已经绘制出面积比的图来说明这一点:如果将一个图画在另一个上面,那么击中上面圆形的概率就是圆的面积与墙的面积的比值。

举个例子,图3.3展示了圆的面积相对于墙的面积的比值,圆的面积是1,而墙的面积是2,所以比值是1/2(或者说0.5)。其实在这里,准确的数字并没有那么重要。这些图只是提供一种可视的方式来帮助我们找到所讨论的区域,让我们对它们的相对大小有一个直观的感受。

图3.3 飞镖击中图3.2中的圆的概率是由圆的面积与墙的面积之比给出的,这里用“分数”符号表示

图3.3准确地展示了相关区域,上方圆的面积是下方方框的面积的1/2。当其中一个图比另一个大得多时,使用完整尺寸的图就可能会使图解很尴尬,因此我们有时可能会缩小区域以使结果图更适合页面。因为面积比不会改变,所以这样做是可行的。需要记住的是:设置这些概率是为了阐明一种图形的面积与另一种图形的面积的对比关系。

3.3 初级概率学

在谈论概率时,我们经常会用大写字母来命名抽象事件,如ABC等。“A的概率”就是指事件A发生的概率。我们可以通过“在墙上画圆”来代表这个概率。这时,圆的面积与墙的面积的比值就是事件A发生的概率。

回想一下,当我们向墙上投掷飞镖时,它总是会击中墙上的某处,而且它击中墙上的任何位置的机会都是相同的。所以如果事件A是“飞镖落在圆里”,那么“A发生的概率”就是另一种表达“把飞镖投掷向墙壁后,它会落在圆里”的概率的方式。图3.4以图形的方式展示了这一点。

图3.4 我们把“飞镖落在圆里”称为“事件A”,那么事件A发生的概率就由图3.3中面积的比值给出,我们把这个概率写成P(A)

为了节省空间,我们通常只说“事件A的概率”而不说“事件A发生的概率”。进一步简化,我们通常将“事件A的概率”写成P(A)[一些作者会使用小写的p,写作p(A)]。

在本例中,P(A)是圆的面积除以墙的面积。这一概率是指,当投掷飞镖时,飞镖落在圆里而不是墙的其他部分的概率。

我们把P(A)称为简单概率(simple probability),有时也称其为A边际概率。稍后我们会看到“边际”这个词的来源。

3.4 条件概率

现在我们讨论的事件不是一个而是两个。这两个事件中的任何一个都可能发生,也可能同时都发生,抑或两者都不发生。

例如,我们可能想要知道若某人正在喝水,他出于口渴喝水的概率。这两件事是相关的,但它们不一定同时发生。有的人可能会出于多种多样的原因喝水,比如为了缓解咳嗽,或者为了吞下一颗药丸。毋庸置疑,出于以上原因喝水时,他们不一定口渴。我们称两个不以任何方式相互依存的事件是独立的

我们的目标是在假设某一事件已经发生(或正在发生)的情况下,找到另一事件发生的概率。我们可能会问“假设有人在喝水,那么他口渴的概率是多少?”或者“假设有人渴了,那么他喝水的概率是多少?”。

换句话说,我们知道一个事件发生了,想知道另一个事件发生的概率。

为了尽可能简略,我们把两个事件写成“A”和“B”。A代表“渴”,如果A是真的,那么这个人就是口渴的;如果A是假的,那么这个人就不口渴。B代表“喝水”,如果B是真的,那么这个人就是在喝水;如果B是假的,那么这个人就没在喝水。与之前类似,我们可以讨论P(A)的大小,它在这种情况下简洁地表达了一个人口渴的概率,也可以讨论P(B)的大小,即指一个人喝水的概率。

在已知B为真的前提下,求A为真的概率,我们把它写成P(A|B),这称为给定B的条件下A条件概率(conditional probability)。换句话说,是“在已知B为真的条件下,A为真的概率”,或者更简单地表达为“在给定B的条件下,A为真的概率”。如果我们对另一种情况感兴趣,也可以讨论P(B|A),即已知A为真的条件下,B为真的概率。

我们可以用图示来说明这一点。图3.5a是墙,上面有两个重叠的斑点,被标记为ABP(A|B)是指已知飞镖落在B上,它也落在A上的概率。图3.5b形象地展示了这一比例,比例上方的形状是AB的共有部分,也就是它们重叠的部分。

(a)                   (b)

图3.5 条件概率告诉我们在假设一件事已经发生的情况下另一件事发生的概率。在这个场景中我们想知道,当已知飞镖落在B上时,它也落在A上的概率。(a)被画上了两个斑点的墙面;(b)已知事件B发生的情况下,事件A发生的概率是AB重叠的面积除以B的面积

图3.5告诉我们如何在已知飞镖落入B区域的情况下,求它落在A区域的概率,即用AB重叠的面积除以B的面积。

P(A|B)是一个可以通过使用飞镖对其进行估计的正数。想法如下:每一个飞镖都会落在墙上的某个区域(在本例中,有4个区域:“A”“B”“AB的重叠区域”以及“AB之外的墙面”)中。通过计算所有落在AB的重叠区域以及B区域的飞镖,我们可以得到一个关于P(A|B)的粗略的值。落在重叠区域的飞镖数量与落在B区域的飞镖数量的比值可以告诉我们:飞镖落在B区域的前提下也落在A区域的概率。

让我们来看看这是怎么回事。在图3.6中,我们向图3.5a中的墙上投掷一些飞镖,投掷点遍及整个区域,且没有哪两个点距离非常近。飞镖尖是如此小,以至于我们可以把它们近似看作一个不容易看到的点。为了便于观察,我们用一个黑色的圆圈代替它,圆圈的中心表示飞镖投掷到的位置。

(a)                 (b)                (c)                 (d)

图3.6 通过向墙上投掷飞镖来找到P(A|B)。(a)飞镖被投掷到墙上;(b)落在A区域或B区域的所有飞镖;(c)落在B区域的所有飞镖;(d)落在AB重叠区域的所有飞镖

在图3.6a中,我们看到了被投掷到墙上的全部飞镖;在图3.6b中,我们分离出了落在A区域或B区域的飞镖(记住,只有每个黑圈的中心才算数);在图3.6c中,我们可以看到有66个飞镖落在了B区域;在图3.6d中,我们可以看到有23个飞镖落在AB的重叠区域。至此,我们可以求出所需要的比值为23/66(约0.35)——这个比值估算了飞镖落在B区域的情况下也落在A区域的概率。

现在我们就可以知道为什么之前说“墙上的每个点都有相同的被击中的可能性”:这样就可以根据落在某个区域的飞镖数量去估计该区域的相对大小。

注意,这并没有告诉我们彩色区域的绝对面积(如带平方厘米这样的单位的数字)。它只是告诉我们一个区域对于另一个区域的相对大小,这也是我们唯一真正关心的度量值(如果墙的尺寸翻倍,那么带颜色区域的面积也会翻倍,飞镖落在每个区域的概率不会改变)。

AB重叠的面积越大,飞镖同时落在两个区域中的可能性就越大。如果A区域涵盖了B区域,如图3.7所示。那么当飞镖落在B区域的时候,它就一定也落在A区域上,这时飞镖同时落在两个区域中的概率就是100%,或者说P(A|B)=1。

(a)               (b)

图3.7 (a)墙上有两个新的斑点;(b)因为A区域涵盖B区域,所以已知飞镖落在B区域的情况下,其落在A区域的概率为1。AB的重叠区域的面积等于B区域的面积

此外,如果AB区域完全不重叠,如图3.8所示。那么在已知飞镖落在B区域中的情况下,它也落在A区域中的概率就是0,或者说P(A|B)=0。

(a)                 (b)

图3.8 (a)墙上又有两个新的斑点;(b)已知飞镖落在B区域的情况下,它也落在A区域的概率为0,因为A区域和B区域并不重叠。形象化的比例显示重叠区域为0,0除以任何东西都仍旧得0

为了好玩,让我们换一种方式,求解一下P(B|A),即已知飞镖落在A区域中,求它落在B区域中的概率。使用与图3.5的墙上相同的斑点分布,结果如图3.9所示。

(a)                 (b)

图3.9 条件概率P(B|A)是在已知飞镖落在A区域的前提下,求出它落在B区域中的概率。所以我们需要找到重叠的面积,然后除以A区域的面积

这种方式的求解逻辑是不变的,使用重叠区域的面积除以A区域的面积。得到的比值可以告诉我们B区域与A区域重叠面积的相对大小。重叠的面积越大,飞镖同时落在A区域和B区域中的可能性就越大。

注意,区域命名的顺序很重要。从图3.5和图3.9可以看出,P(A|B)不等于P(B|A)。已知A区域、B区域和它们重叠面积的大小的情况下,P(A|B)要大于P(B|A)。

在不知道具体值是多少的情况下,我们也可以使用诸如P(A|B)这样的表达式。甚至我们可能不知道AB的形状是什么,更不知道AB的面积是多大。当我们说诸如P(A|B)这样的表达式(在没有明确给出AB的值的情况下)“告诉我们”或是“给了我们”已知B发生的情况下A发生的概率时,所指的是:如果弄清楚AB是什么,我们就可以通过AB的区域大小去计算P(A|B)。

换句话说,表达式P(A|B)是一种简写(或者说规范),以供输入为AB并且返回概率的算法使用。

同样的说法也适用于P(A)、P(B)以及我们会在这一章中看到的其他类似的表达式。它们是对产生数值的算法的引用,这些数值是当我们得到输入值时计算出来的。

3.5 联合概率

在3.4节中,我们学习了一种方法,可以在已知一个事件已经发生的情况下,求得另一个事件发生的概率,那么如果我们不知道这两个事件是否已经发生了呢?

在事先不知道其中任何一个事件发生概率的情况下,知道两个事件同时发生的概率会很有帮助。

回到我们的饮水的例子,一个人既口渴又在喝水的概率是多少呢?或者回到我们投掷飞镖的例子,落在墙上的飞镖有多大概率同时落在A区域和B区域中呢?

我们把AB同时发生的概率写为P(A,B),在这里,我们可以把逗号看作“和”的意思。P(A,B)代表着“AB都为真的概率”,让我们大声读出它的名字“AB的概率”。

我们把它称为AB联合概率(joint probability)。

回到投掷飞镖的例子,在这里,通过找到A区域和B区域重叠的面积与墙的面积的比值,我们就可以得到联合概率P(A,B)。我们要求的是飞镖同时落在A区域和B区域的概率,也就是“落在两个区域重叠的地方的概率”与“落在任何地方的概率”的比较,如图3.10所示。

(a)                  (b)

图3.10 AB同时发生的概率称为它们的联合概率,写作P(A,B)。这个值可以通过用AB重叠的面积除以整个墙的面积得到。P(A,B)指的是随机投掷飞镖时飞镖同时落在A区域和B区域的概率

还可以从另一种方式来看待这个问题,这个方式有点微妙,但是很有趣也很实用。它是基于我们在3.4节所说的条件概率。

条件概率P(A|B)指的是在已知飞镖击中B区域的情况下击中A区域的概率。但从概念的另一个角度看,如果知道击中了B区域,那么条件概率就给出了这种情况下我们同时也击中A区域的概率,并且假设我们可以知道随机击中B区域的概率是P(B),那么我们是否可以据此得到同时击中A区域和B区域的联合概率呢?

让我们仔细思考一下这个问题,假设B区域的面积覆盖了一半的墙面[即P(B)=1/2],而A区域的面积可以覆盖1/3的B区域[即P(A|B)=1/3]。那么一半的飞镖都会落在B区域上,而这一半中的1/3又会落在A区域中。假设我们投掷了60支飞镖,就有一半(或者说30支飞镖)落在B区域中,然后这一半中的1/3(或者说10支飞镖)会落在A区域中,所以同时落在AB区域[即P(A,B)]的概率就是10/60(或者说1/6)。

这个例子向我们展示了一条一般规律:我们可以通过找到 P(A|B),然后乘以 P(B)来发现P(A,B)。这里有非常值得我们注意的一点:仅使用P(A|B)和P(B),就可以求出P(A,B)!我们把它写成P(A,B)=P(A|BP(B)。而在实践中,我们通常不会写出乘法符号,而是写为P(A,B)=P(A|B)P(B),在这样的表达式中,乘法符号是隐含的。

图3.11展示了我们刚才通过面积图来完成的工作。

(a)                                   (b)         

图3.11 另一种考虑联合概率P(A,B)的方法。P(A,B)就是飞镖同时落在A区域和B区域的概率(或者说AB事件同时发生的概率),如图3.10所示

图3.11中使用的小技巧是把这些符号的概率当作实际的分数,这样我们就可以消去B区域。为了更清楚地看到这一点,在图3.12的第三行中,我们对等号右边的项进行了重新排列。第三行最右边的部分是“B区域的面积”除以“B区域的面积”,也就是1,所以这一项可以被忽略,从而等号左右相等。

图3.12 我们可以重新排列图3.11中的各项,以便更好地看到B区域的面积是如何被抵消的。第一行是原始公式;第二行是我们在图3.11中看到的符号版本;在第三行,我们将两个绿色区域重新排列到了右边(在这里我们把它们当作真正的分数)。这样,最右边的项就是1,等号左右是一样的

我们也可以用另一种方式来做:通过求解P(B|A)来求出已知飞镖落在A区域的情况下落在B区域的概率,然后乘以落在A区域的概率[或者说P(A)],即P(A,B)=P(B|A)P(A)。图3.13直观地展示了这一点。结果和以前一样,是我们所期望的。在符号表示上,P(B,A)=P(A,B),因为它们都表示同时落在A区域B区域中的概率,在这个表达式中,AB的顺序是无关紧要的。

图3.13 就像我们在图3.12中所做的那样,这幅图也求解了P(A,B)的联合概率。这次是从飞镖落在A区域的概率开始,然后乘以(假设已经落在A区域)落在B区域的概率[P(B|A)]。第一行是原始公式;第二行是公式的形象表达;第三行与图3.12中相同,对公式的项进行了重新排列,表明公式的正确性

这些想法可能有点难以接受,通常需要编造一些小场景应用来辅助理解。想象一下不同的区域以及它们之间如何进行重叠,或者甚至可以把AB想象成实际情况。

例如,让我们想象一个冰淇淋店的场景,人们可以在那里买到各种口味的冰淇淋,蛋筒装冰淇淋或是杯装的冰淇淋都可以。我们可以这样假设:如果有人订购香草冰淇淋,我们就说V事件为真;如果有人订购蛋筒装冰淇淋,我们就说C事件为真。至此,P(V)代表任意一位顾客订购香草冰淇淋的可能性,而P(C)代表任意一位顾客订购蛋筒装冰淇淋的可能性。P(V|C)则告诉我们一位订购蛋筒装冰淇淋的顾客选择香草口味的可能性有多大,而P(C|V)则告诉我们一位订购香草冰淇淋的顾客选择蛋筒装的可能性有多大。P(V,C)则告诉我们任意一位顾客订购香草蛋筒装冰淇淋的可能性有多大。

3.6 边际概率

到这里,我们遇到了本节标题所说的边际概率(marginal probability)。这似乎是一个奇怪的搭配:“边际”与概率有什么关系?“边际”一词来自包含预计算概率表格的书,其思想是:我们(或者打印机)需要去汇总概率表的每一行,并将汇总后的总数写在页面的边缘处([Andale17])。

让我们回到冰淇淋店这个例子来阐述这个想法。在图3.14中,我们展示了一些顾客最近的订购行为。需要说明的是:冰淇淋店刚刚开张,只供应香草和巧克力两种口味的冰淇淋,有蛋筒装和杯装两种样式可选。根据昨天来的150人的订购情况,通过将每行或每列中的数字相加(相加后的数字在“边缘”处给出)并除以总顾客数量,我们就可以知道某位顾客购买杯装或蛋筒装冰淇淋的概率,也可以知道他购买香草或巧克力口味的冰淇淋的概率。

注意,某位顾客买杯装蛋筒装冰淇淋的概率加起来是1,因为每位顾客都会选择一种样式。同样,每位顾客都会选择一种口味的冰淇淋(香草或巧克力),所以购买香草冰淇淋和巧克力冰淇淋的概率加起来也是1。总的来说,任何一个事件的各种结果的概率加起来都会是1,因为我们可以百分之百地确定其中一个选项会发生。

图3.14 统计最近前来冰淇淋店的150位顾客的订购行为的边际概率

3.7 测量的正确性

在后续章节中,我们经常需要对数据进行分类。本节将关注最简单的情况,即探寻一段数据是否属于某个特定类别。

例如,我们可能会想要知道“一张照片中是否有狗”“飓风是否会袭击陆地”“股票是否会发生重大变化”抑或“我们的高科技围场是否牢固到可以容纳基因工程创造的超级恐龙”(提示:它们不能)。

理所当然地,我们会尽最大努力做出最准确的决定,而“如何定义我们所说的‘准确’”就成为至关重要的一环。

衡量“准确”最简单的方法就是计算“判断错误的结果”的数量,但这个方法不是很有启发性。如果我们想要通过错误来改进表现,就需要去明确做出错误预测的原因。

这种讨论的应用范围远远不止于机器学习范畴。下面所说的内容可以帮助我们去诊断和解决各种各样的问题,不管这些问题是来自特定的任务还是日常生活(在那里,我们根据自己为事物分配的标签做出判断)。

在深入讨论之前,我们需要注意这里所使用的两个术语:精度(precision)和准确率(accuracy。它们在不同的领域有着不同的含义。在本书中,我们会坚持用它们在概率和机器学习领域通常使用的含义,并会对它们进行详细的定义(在本章中)。要注意的是,这些术语在很多地方都有着不同的含义(或者只是作为模糊的概念出现)。

3.7.1 样本分类

让我们来具体看看手头的任务。我们想要知道一段给定的数据片段(或者说样本)是否在给定的类别中。以问题的形式叙述,那就是:“这个样本属于这个类别吗?”。你只能回答“是”或“否”,不能回答“可能是”。

如果答案是“是”,我们就称样本为阳性;如果答案是“否”,我们就称样本为阴性

我们对从分类器中得到的结果与观察到的真实(或者说正确)结果进行比较,借此来讨论准确率。我们把手动赋予样本的阳性或阴性称为它的真值(ground truth)或实际值(actual value,而将分类器(无论是人还是计算机)返回的值称为预测值(predicted value)。在完美的情况下,预测值总是与基础真值相匹配,然而在现实世界中,经常会有错误发生,我们的目标就是描述这些错误。

我们用二维数据进行说明。也就是说,我们所用的每个样本数据点(data point)都有两个值。这两个值可能是一个人的身高和体重,也可能是天气测量中的湿度和风速,还有可能是音符的频率和音量。然后,我们会在二维网格上绘制每一个数据,其中x轴对应一个测量值,y轴对应另一个测量值。

每个样本都将属于两个类别(或者说)中的一个,我们称之为类别0类别1(或0类1类)。为了表明样本类别,我们用了不同的颜色和形状标注。图3.15显示了两个类别的二维数据示例。

(a)                                   (b)

图3.15 来自两个不同类别的二维数据。(a)每个样本都有x值和y值,可以将它们放在同一个平面上,我们用不同的颜色和形状标注了两组不同类别的样本;(b)我们可以通过在两组数据之间划一条界线来把它们分开。图中绘制的只是无数可能边界中的一个

无论是通过人工还是计算机,我们最终都会展示分类结果:绘制一条边界(或者说曲线)去区分这些数据点的集合。边界可能是平滑的,也可能是曲折的,但绘制它都是为了代表分类器。我们可以把它看作对分类器决策过程的一种总结,曲线一侧的所有点将被预测为一个类别,而另一侧的所有点将被预测为另一个类别。

有时,我们说边界有“阳性”的一面和“阴性”的一面。当我们认为分类器在回答问题时,这样对边界进行说明就是与分类相匹配的,“这个样本属于给定的分类吗?”,如果回答是“真”,或者说阳性,那么预测值就是“是”,反之就是“否”。

边界的性质可以通过一个指向“阳性”一侧的箭头来表示,如图3.16a所示。但如果把样本也绘制进去,标记箭头就会使得图表很混乱。因此,我们可以借用天气图中的一些符号来进行表示(见[MetService16])。在天气图中,我们用等压线表示冷热锋面的交界处,并用一些小符号来指向感兴趣的温度区域。在图3.16b中,我们用暖锋等压线替换箭头,小三角形指向边界的“阳性”的一侧。

(a)                                        (b)

图3.16 这条曲线把空间分成两个区域。(a)我们可以用箭头来指出边界的“阳性”的一侧;(b)我们也可以用暖锋等压线符号来指出边界的“阳性”的一侧

这里用来进行说明的原始数据集包含20个样本,如图3.17所示。我们将一个类别的样本手动标记为绿色圆圈,将另一个类别的样本标记为红色方块。所以这里的颜色或形状都是对应于它们的基础真值的,而不是分类器为它们划分的值。

分类器的边界将图分割成两个区域,我们用浅色阴影表示“阳性”区域,用深色阴影表示“阴性”区域。浅色区域内的每个点都被归类为“阳性”,而深色区域内的每个点都被归类为“阴性”。

(a)                                            (b)

图3.17 原始数据集包含20个样本,用暖锋等压线符号指向“阳性”方向。我们已经给绿色圆圈贴上了“阳性”标签,给红色方块贴上了“阴性”标签。(a)分类器的曲线可以很好地对样本进行分类,但也会出错;(b)同一个图表的示意图

完美的情况应该是所有绿色圆圈都在浅色区域内,而所有红色方块都在深色区域内。但从图3.17可以看到,这个分类器也犯了一些错误。

图3.17a展示了我们测量过的数据。但是现在,我们不关心点的位置或者曲线的形状,而是关心有多少点被正确地分类,又有多少点被错误地分类,导致它们落在了边界的正确的一边和错误的一边。因此,在图3.17b中,我们对图形进行了整理,这样可以更容易对样本进行计数。

在图3.17b中,10个圆圈中有6个被正确识别为“阳性”,而10个方块中有8个被正确识别为“阴性”,分别有两个方块和4个圆圈被分到了错误的一侧。

图3.17指出了我们在真实数据集上运行分类器时常常会发生的情况:一些数据被正确分类,而另一些数据没有。如果分类器(对于我们来说)不能足够准确地对数据进行分类,我们就需要采取一些行动去修改分类器(甚至是放弃它,再创建一个新的)。所以,能够有效地去衡量一个分类器的表现是很重要的。

接下来,让我们探索一些解决这件事情的方法。

3.7.2 混淆矩阵

我们希望能够以某种方式去描述图3.17中的错误,从而说明分类器的性能(或者说它的预测与给定的标签相匹配的程度)。

我们可以创建一个有两列两行的小表格,每一列表示一个预测值,而每一行表示一个实际值。这样我们就得到了一个2×2的网格,这个网格通常称为混淆矩阵(confusion matrix)。这是个有点奇怪的名字,指的是矩阵会如何向我们展示分类器对某些数据的预测发生错误(或者说混淆)。图3.18复现了分类器的输出结果,并生成了它的混淆矩阵。

(a)                                       (b)

图3.18 (a)复现了图3.17b中的内容,并由此总结出了一个混淆矩阵;(b)这个混淆矩阵可以说明这4个类别各有多少个样本

图3.18b中共有4个单元格,每个单元格都有一个惯用名称——这个名称描述了预测值和实际值的特定组合。6个被正确地标记(或者说预测)为“阳性”的圆圈被归类到真阳性(true positive)类别。换句话说,它们的预测值为“阳性”,而它们本身的值也为“阳性”,对于“阳性”的预测是正确(或者说真)的。

4个被错误地标记为“阴性”的圆圈被归类到假阴性(false negative)类别。换句话说,它们被错误(或者说假)地贴上了“阴性”的标签。8个红色方块被正确地分类为“阴性”,所以它们都属于真阴性(true negative)类别。

那两个被错误预测为“阳性”的红色方块就属于假阳性(false positive)类别,因为它们被错误(或者说假)地标记为“阳性”。

我们可以将这4个类别全部用两个字母的缩写来代表,这样可以更简洁地进行表达,并用一个数字来表述每个类别中有多少样本。图3.19展示了混淆矩阵的常规表达形式。然而需要注意的是,人们对于标签放置的顺序并没有普遍的共识。有些人把预测值放在左边,而把实际值放在上面;有些人则会将“阳性”和“阴性”两种类别放在明显相反的位置。遇到混淆矩阵时,最重要的就是去查看标签以确保我们知道每个框代表什么。

图3.19 用常规形式展现了图3.18中的混淆矩阵。注意,并不是所有人都将各个标签如图中所示的位置放置,所以遇到一个混淆矩阵后,检验标签位置是很重要的

3.7.3 混淆矩阵的解释

混淆矩阵可能会让人感到迷惑。现在我们用一个全新的、具体的例子来介绍它的各个类别。

讨论混淆矩阵的经典方法是用医学诊断的方式进行的,其中“阳性”表示某人处在某种特定状态,“阴性”则表示健康。让我们设想以下场景。

假设我们作为公共卫生工作者来到一个小镇,这里的人患上了一种可怕的(但是完全是想象出来的)疾病(称为Morbus Pollicus,又名MP)。任何患有MP的人都需要立即进行切除拇指的手术,否则会在数小时内死于此疾病。

我们必须正确诊断出谁患有MP,而谁并未患病。拇指对人很重要,但如果要活下来的唯一方法是失去拇指,那么可能有大多数人愿意接受手术。但是,如果一个人的生命没有受到威胁,那么我们绝对不会想要去做出任何导致其拇指被切除的错误诊断。

假设有一个检测MP的测试,这个测试缓慢且昂贵,但是我们知道这种测试方法是完全值得信赖的。“阳性”的诊断结果代表这个人患有MP,“阴性”的诊断结果则代表他们并未患病。

通过这个测试,我们对镇上的每个人进行了检查,然后知道他们是否患有MP。但是这个可靠测试是缓慢且昂贵的,并且需要一个有专门设备的实验室才能进行,不够便捷。我们担心未来这种疾病暴发,于是根据刚刚得到的数据开发了一种快速、便宜、便携的新血液测试设备,这样就可以立即预测受试者是否患有MP。

我们的目标是尽可能地使用便宜且快速的血液测试方法,而只在必要的时候使用昂贵而缓慢的测试。理想的情况是:如果血液测试结果为“真”,受试者就真的得了这种病,需要马上进行切除拇指的手术;如果血液测试结果为“假”,受试者就没有得这种病,不用采取任何治疗措施,可以回家。由此可以看出,血液测试的结果是非常重要的!

实际上,我们还需要对血液测试进行完善,因为这个测试结果并不完全可靠。这个便宜且快速的测试存在两个问题:首先,它可能会漏诊患病者,当受试者患有MP时,测试也可能呈现为“阴性”;其次,它可能在受试者未患病的情况下给出“阳性”结果,例如这个受试者最近吃了(或喝了)一些东西,导致血液测试出现了错误的诊断。

我们知道血液测试尚有缺陷,但是在疫情现场,这是我们检测受试者是否患上MP的唯一手段。所以,在找到更好的测试方法之前,我们需要确定这个测试的正确率、错误率、错误发生的时间以及错误发生的方式。

综上所述,我们去到一个小镇(那里有一些人患有MP),并特意为昂贵、缓慢但准确的测试建立了一个实验室,然后用昂贵的和便宜的两种方法来检测每一个人。通过将所有测试结果放入混淆矩阵的4个类别中,我们就可以对比通过快速血液测试得到的结果和(通过缓慢且昂贵的测试得到的)真实结果的差别。

(1)真阳性意味着受试者患有MP,快速血液测试也表明他们患有MP,那么我们就需要采取行动来挽救他们的生命。

(2)真阴性意味着受试者并未患有MP,快速血液测试也表明他们未患有MP,那么这个人没有生命危险,不需要救治。

(3)假阳性意味着受试者未患有MP,但快速血液测试表明他们患有MP。这会导致我们切除了健康人的拇指——这是一个很严重的错误。

(4)假阴性意味着受试者患有MP,但快速血液测试表明他们未患有MP。这会导致我们不会采取行动,而这个患者将死亡——这是一个更严重的错误。

真阳性和真阴性都是“正确”的预测,而假阴性和假阳性都是“不正确”的预测。假阳性意味着我们对未患病者采取治疗措施,而假阴性则意味着某人有死亡的危险。快速血液测试越精确,它所返回的真阳性和真阴性类别的预测就会更多,其他选项会更少。

虽然我们喜欢使用缓慢且昂贵的测试,但这是不实际的,所以需要了解快速血液测试。

图3.20展示了一个关于MP测试的定性的混淆矩阵。

图3.20 一个关于MP测试的定性的混淆矩阵。这些面部表情显示了一个人对于测试结果的反应。图中的点表示这个人是否真的患有MP。其中,真阳性和真阴性都是正确的诊断结果,但是假阴性意味着我们没能检测出一个患病的人,他将面对死亡,而假阳性意味着我们会给一个健康的人做手术。后面我们会统计每个类别的样本数量

我们可以把每个类别的数量加到混淆矩阵的各个单元格中,之后利用这些值来回答关于群体和测试的问题。最后的结果以数值形式给出,来告知我们做得怎么样。这一部分我们会在后续章节中讲解。

但在深入研究这些数字和得分之前,我们看一个与混淆矩阵相关的很重要的问题。这个问题常常被忽视,由此可能会带来可怕的现实后果,因此我们必须密切关注这个问题。

看上去,有些问题提出得非常合理,但是如果我们不小心,这些问题就可能会导致一些非常错误的结论。

假设我们现在问这样一个问题:“有多少患有MP的人做了测试并且被正确地分类?”从表面上看,这是一种很有用的衡量准确率的方法,但它可能是非常具有误导性的。

先假设测试总是返回“真”,那么上述问题的答案就是:测试正确地预测出了所有(100%)患有MP的人。换句话说,对于上述问题来说,测试做得简直完美。但是,在这个测试中,我们可能会得出很多错误的答案,因为一部分未患有MP的人也会被诊断为阳性,这些错误的结果将导致许多不必要的操作。

这种情况下,我们根本不需要测试。“测试”可能只是一张印着“真”的纸。听起来我们有一个很棒的测试,因为它排除了其他可能的诊断结果。如果我们只是想要对某种特定的诊断结果进行完美的记录,只需要对每个进门的人都做出这样的诊断就可以了,这是一个很可怕的过程。

或者,我们也可能会问:“测试将多少人正确地分类为健康?”与之前一样,我们也只看一个诊断结果,所以可以简单地给每个受试者诊断为“假”,那么测试在这个问题上就是100%准确的。毕竟,每个健康的人都被判断为未患病,但是那些真正患病的人都会死。

我们非常容易犯“问错问题”这样的错误,特别是当情况变得复杂的时候。为此,人们开发出了另一套术语,使得我们不容易偶然提出错误的问题。

3.7.4 允许错误分类

在学习如何对系统的性能进行正确的衡量之前,请注意,我们有时也需要假阳性或假阴性。

例如,假设我们在一家公司工作,这家公司的业务是生产几十个流行电视角色的玩具雕像。这种产品很畅销,所以生产线都是满负荷运营,这样可以尽可能多地去生产雕像。我们负责包装雕像,并将其运送给零售商。这些小雕像运到工厂时都被混杂放置在运输箱里,所以我们需要先把它们分类,并为每一组找到合适的包装,然后把每个小雕像放进正确的包装里,把包装放进对应的运输箱,并运送到零售商店。

突然有一天,我们被告知公司失去了一个角色的销售权,这个角色叫Glasses McGlassface。如果我们不小心运出了这种小雕像,就会被起诉。所以,防止这种雕像被运出工厂是很重要的。然而,生产线仍在运转,如果我们去更新机器,将无法完成其他订单。我们能想出的首选办法是继续制作这些已经被禁止销售的小雕像,待制作完成后,我们会找出它们并将其扔进一个箱子中,以确保没有Glasses McGlassface被运出工厂。图3.21展示了这种情况。

图3.21 Glasses McGlassface是第一行的第一个人物。我们需要移除任何有可能是这个角色的雕像。第一行:所有雕像。第二行:因为可能是Glasses McGlassface而被我们移除的雕像。第三行:将要运出去的雕像。在中间一行中,有一个假阳性,或者说有一个不是Glasses McGlassface的雕像被移除了

为了使检测这些雕像的过程更有效率,我们安装了一个摄像头,去检测每一个传送带上的雕像。每当它看到一个被禁止的角色,就会有一只机器手臂把它捡起来,并放到箱子里。

我们应该如何为这个摄像头编程呢?只要运出一个已经被禁止的角色,我们就会被起诉,需要赔偿一大笔钱,所以最好谨慎行事。如果摄像头认为一个雕像可能是被禁止的角色,就应该把它移除。我们可以在后期将被错误移除的雕像重新装箱售卖。

在这种情况下,假阳性(被错误归类为禁止类别的玩具雕像)只是一个小小的插曲,但假阴性(意外运送违禁玩具雕像)是要付出巨大代价的。因此,在这种情况下,我们可以采取这样的策略:在一定程度上允许假阳性的存在(只要没有太多的假阳性)。

假设下一步是质量控制,在这一步中,我们要确保正确绘制每个雕像。我们刚刚收到来自工厂的备注,说画眼睛的机器人可能出问题了,所以我们需要特别注意眼睛,只有眼睛被正确绘制的雕像才能够通过这一步。如果雕像没有眼睛,就要把这个雕像从生产线上拿下来。所以我们需要去寻找眼睛的部分,如果找不到雕像的眼睛,就会有另一只机器手臂把雕像从生产线上拿下来,并放到另一个箱子里,如图3.22所示。

图3.22 一组新的雕像。我们正在寻找眼睛被漏画的雕像,想要避免将这类雕像运送出去。我们在寻找眼睛,而“阳性”的结果是雕像有眼睛。第一行:被扫描的雕像。第二行:有眼睛的雕像。第三行:分类为缺少眼睛的雕像。其中有一个雕像有眼睛,但被认为是缺少眼睛的,所以他是假阴性

在这种情况下,我们是要找出肯定有眼睛的雕像——它们将被判别为“阳性”。这意味着我们要移除任何没有眼睛的雕像。因为如果出售了一个没有眼睛的雕像,那么情况将变得很糟糕。

所以我们只会使那些肯定为“阳性”的雕像通过,我们会非常小心,以杜绝“假阳性”(或者说一个没有眼睛的雕像)。在这个例子中,我们错误地将一个有眼睛的雕像归类为没有眼睛,这是一个假阴性。但在这里,假阴性是允许的,因为此后我们可以再把它重新装箱售卖。

所以在这种情况下,我们的规则是:假阳性是非常可怕的,但假阴性只是一个小烦恼。这是与上一次相反的政策。

总而言之,真阳性和真阴性的情况是很容易处理的。我们应该如何应对假阳性和假阴性的情况则取决于实际场景和我们的目标。正确认识“我们的问题是什么”以及“我们的规则是什么”是非常重要的,知道了这两点,我们就能知道如何应对这些错误的分类。

接下来,让我们回到前面说过的术语。这些术语可以帮助我们很好地描述分类器的性能表现。

3.7.5 准确率

我们在本节中讨论的每个术语都是由混淆矩阵中的4个值构建的。为了便于讨论,我们将使用常见的缩写:TP表示真阳性,FP表示假阳性,TN表示真阴性,FN表示假阴性。

描述分类器质量的第一个术语称为准确率(accuracy)。准确率是一个0和1之间的数字,是对于正确预测频率的一般衡量标准。所以它就是两个“正确”的值(即TP与TN的和)除以测量的样本总数,如图3.23所示。与接下来的所有图一样,在这个图中,每一个步骤中涉及的点数都会被展现出来,没有涉及的会被省略。

我们希望准确率是1.0,但通常会低于1.0。在图3.23中,准确率为0.7(或者说70%),这并不是很好。虽然准确率并不能告诉我们预测错误的方式,但是它确实给了我们一个大概的感觉,告诉我们大概有多大程度得到了正确的结果,所以准确率是一个粗略的衡量标准。

图3.23 准确率是一个0和1之间的数字,用于表示正确预测的频率。我们可以通过创建一个分数来找到它。分子是被正确分类的点的个数,而分母则是点的总数。在这里,20个点中有6个圆圈和8个方块被正确地分类,所以准确率是14/20(或者说0.7)

为了更好地控制预测的质量,让我们来看一看另外两种方法。

3.7.6 精度

精度(也称为阳性预测值,或PPV)可以告诉我们:样本中被正确地标记为“阳性”的样本数量占总的“阳性”的样本数量的百分比。从数字上看,它是TP相对于TP+FP的值。换句话说,精度告诉我们有多少被预测为“阳性”的样本真的是“阳性”的

如果精度为1.0,那么由我们预测标记为“阳性”的每个样本实际都为“阳性”。随着百分比的下降,我们对预测的信心也随之下降。例如,如果精度是0.8,我们就只能有80%的信心确定被预测为“阳性”的样本实际上为“阳性”。图3.24直观地展示了这个想法。

图3.24 精度的值是指“真阳性”的样本总数与我们标记为“阳性”的样本总数的商。在这里,我们有6个圆圈被正确地标记为“阳性”,而两个方块被错误地标记为“阳性”,因此精度为0.75(或者说6/8)

精度小于1.0意味着我们将一些样品错误地标记为“阳性”。如果回到之前的医疗案例中,精度小于1.0就意味着我们要去做一些不必要的手术。

精度的一个重要的特点就是:它不能告诉我们是否真的找到了所有“阳性”的对象,即所有患有MP的人。精度忽略了被标记为“阴性”的“阳性”的对象。

我们可以用A类和B类这样更加通用的术语来表述。那么精度小于1.0则告诉我们那些被预测为A类但实际上是B类样本的比例。如图3.25所示,标记为A和B的两个团是由真正在这两类中的样本组成的,而对角分割线表示了我们将样本预测为A类还是B类。

图3.25 精度是指“被正确标记为属于A类的元素数量”与“被标记为A类的元素总数”的比值

3.7.7 召回率

第三个衡量标准是召回率(recall),也称为灵敏度(sensitivity)、命中率真阳性率(true positive rate),它告诉我们被正确预测为“阳性”的样本的百分比。

召回率是1.0表示我们发现了所有“阳性”的样本。召回率越小,表示我们错过的“阳性”样本越多,如图3.26所示。

图3.26 召回率是指被正确标记为“阳性”样本的总数与应该被标记为“阳性”的样本总数的商。这里有6个正确标记的圆圈,但我们错误地把4个“阳性”样本标记为“阴性”,所以召回率为0.6(或者说6/10)

我们也可以用A、B类的方式来考虑这个问题,如图3.27所示。

图3.27 召回率表明了我们对A类样本进行预测的结果好坏。它是一个比值,是由被我们标记为A类的元素数量除以实际为A类的元素数量得到的

当召回率小于1.0时,就意味着我们漏掉了一些实际为“阳性”的样本。如果是前面所述的医疗案例,这就意味着我们会将一些已经被感染的MP患者误诊为未患病,导致即使那些人正处于危险之中,我们也不会给这些人做手术。

3.7.8 关于精度和召回率

让我们用一个具体的例子来看看精度和召回率。假设我们有一个包含500个页面的内测版维基百科,然后对短语“犬只训练”进行搜索。

假设搜索引擎返回的每一个关于“犬只训练”的页面都是真的与“犬只训练”相关的,就称这个结果是“阳性”的。从某种意义上来说,这是我们想看到的。而每个不应该返回的页面都是“阴性”的,因为我们不想看到它。图3.28为按页面相关度划分的4类结果,以及我们给出的“真/假”与“阳性/阴性”组合的4类结果。

(a)                                     (b)

图3.28 用返回的网页搜索结果来描述我们的4个类别。中间圈出的区域是搜索的结果。(a)可以看到,在维基百科中有与“犬只训练”相关的和不相关的页面,并会在搜索中得到每种页面中的一些结果,其他的则被遗漏。(b)展示了这4个类别是如何与真、假、阳性和阴性的组合相对应的

先介绍准确率,它是有着正确标签的页面相对于维基百科中页面总数的比值。系统判定每个页面是否相关越精准,准确率就越能够接近1.0,如图3.29所示。

图3.29 准确率是指系统正确判断出的与搜索词相关或不相关的页面数量与维基百科中页面总数的比值

接下来介绍精度。在这种情况下,精度是指搜索结果中与“犬只训练”相关的结果数量与总的搜索结果数量的比值,如图3.30所示。搜索引擎的精度越高,得到的相关搜索(真阳性)就越多。如果搜索引擎的精度低,就会得到很多不相关的结果(假阳性)。

图3.30 精度是“得到的相关的结果的数量”与“得到的所有结果的数量”的比值

最后来看召回率,看完我们就会明白这个看似奇怪的名字的意义。在这种情况下,召回率是“返回的相关结果的数量”与“整个数据库中应该返回的全部结果的数量”的比值。也就是说,如果召回率是1.0,那么系统将100%召回(或者说检索出)它应该获得的全部页面。如果召回率是0.8,那么系统将丢失20%它应有的页面。那些被遗漏的页面就是“假阴性”:系统将它们标记为“阴性”,并且没有召回(或者说检索出)它们,但这些页面是应该被召回的,如图3.31所示。

图3.31 召回率是“系统召回(或者说返回)的相关结果的数量”与“系统应该召回的结果总数量”之比

3.7.9 其他方法

我们已经知道了准确率、召回率和精度的衡量标准,而在讨论概率和机器学习时,还会用到许多其他术语(见[Wikipedia16])。除了接下来会讨论的f1分数,其余大多数术语在本书的其他地方都不会出现,但我们会对它们加以总结并给出一个“一站式”的参考,如表3.1所示。

不需要费心去记忆任何不熟悉的术语及其含义,这张表的目的只是在你需要的时候提供一个能够方便查找这些东西的途径。

这张表理解起来有些复杂,我们提供了另一种图形化的展示方法,使用的是我们在图3.17中的样本分布,如图3.32所示。

表3.1 混淆矩阵中常见的术语

名称

别名

简写

定义

解释

真阳性

击中

TP

标记为阳性的“阳性”样本

被正确标记的“阳性”样本

真阴性

拒绝

TN

标记为阴性的“阴性”样本

被正确标记的“阴性”样本

假阳性

假警报,错误类型Ⅰ

FP

标记为阳性的“阴性”样本

被错误标记的“阴性”样本

假阴性

漏掉,错误类型Ⅱ

FN

标记为阴性的“阳性”样本

被错误标记的“阳性”样本

召回率

灵敏度,真阳性率

TPR

TP/(TP+FN)

被正确标记的“阳性”样本的百分比

特异性

真阴性率

SPC,TNR

TN/(TN+FP)

被正确标记的“阴性”样本的百分比

精度

阳性预测值

PPV

TP/(TP+FP)

被标记为“阳性”实际也为“阳性”的样本的百分比

阴性预测值

NPV

TN/(TN+FN)

被标记为“阴性”实际也为“阴性”的样本的百分比

假阴性率

FNR

FN/(TP+FN) =1−TPR

被错误标记的“阳性”样本的百分比

假阳性率

误检率

FPR

FP/(FP+TN) =1−SPC

被错误标记的“阴性”样本的百分比

错误发现率

FDR

FP/(TP+FP) =1−PPV

实际为“阴性”但是被标记为“阳性”的样本的百分比

正确发现率

TDR

FN/(TN+FN) =1−NPV

实际为“阳性”但是被标记为“阴性”的样本的百分比

准确率

ACC

(TP+TN)/(TP+TN+FP+FN)

被正确标记的样本百分比

f1分数

f1

(2*TP)/((2*TP) +FP+FN)

当错误减少时,f1会接近1

图3.32 图3.17中的数据分为真阳性(TP)、假阳性(FP)、假阴性(FN)和真阴性(TN)4个类别

从上至下看图3.32,有6个“阳性”样本被标记正确(TP=6),2个“阴性”样本被标记错误(FP=2),4个“阳性”样本被标记错误(FN=4),8个“阴性”样本被标记正确(TN=8)。

有了这些点,我们就可以用不同的方式去组合这4个数字(或者说它们的图)来解释表3.1中的各种度量方法。图3.33展示了我们是如何使用相关的数据片段来计算出各种度量的。

图3.33 我们用图3.32中的数据将表3.1中的统计度量方法以可视化的形式展现出来

3.7.10 同时使用精度和召回率

准确率是一种常见的度量方法,但在机器学习中,精度和召回率出现得更频繁,因为它们更有助于描述分类器的性能,并以此去与其他分类器进行比较。但是,如果单独考虑它们其中的一个,精度和召回率就都可能会产生误导,因为极端条件可以单独给予精度或召回率一个完美的值,但整体表现非常糟糕。

为了了解这一点,我们重新讨论一下两种极端情况:完美精度完美召回率

有一种方法可以创建具有完美精度的边界曲线,那就是检查所有样本,然后找到最肯定为“真”的那一个并画出曲线,这样所选择的点就是唯一的“阳性”样本,而其他的都是“阴性”样本,如图3.34所示。

(a)                        (b)

图3.34 (a)这条边界曲线为这次分类提供了一个完美的精度。可以注意到,所有方块都被正确地分类为“阴性”样本,但是只有一个圆圈被正确地分类为“阳性”样本,而其他9个圆圈都被错误地分类为“阴性”样本。(b)(a)的示意图

这样的分类是怎么提供完美精度的呢?记住,精度是指真阳性样本的数量(这里只有1个)除以被标记为“阳性”的样本的数量(同样是1个),所以得到的分数是1/1(或者说是1),这是一个“完美”的结果。但是它的准确率和召回率都很糟糕,如图3.35所示。

图3.35 这些结果都有一条相同的边界曲线,这条曲线把一个圆圈分类为“阳性”,把其他的都分类为“阴性”。由于精度的定义,这样的划分使得我们获得了完美的精度1,但准确率是0.55,召回率则是0.1,这两种评估方式的结果都很糟糕

我们对召回率使用同样的方法。创建一条有着完美召回率的边界曲线更加容易,我们要做的就是给每件事都贴上“阳性”的标签,如图3.36所示。

(a)                          (b)

图3.36 (a)这条边界曲线为这次分类提供了一个完美召回率。需要注意的是,10个圆圈全部被正确地分类为“阳性”,但10个方块也全部被错误地分类为“阳性”。(b)(a)的示意图

这样做让我们获得了完美的召回率。因为召回率是指被正确分类为“阳性”样本的数量(这里是10个)除以“阳性”样本总数(同样也是10个),所以10/10是1,得到了完美的召回率。而这种情况下的准确率和精度都很差,如图3.37所示。

3.7.11 f1分数

同时观察精度和召回率是很有帮助的,但在结合一些数学知识后,我们可以形成单一的衡量标准,即f1分数(f1 score)。这是一种特殊类型的“平均”,我们称之为调和平均数。它为我们展示了一个结合精度和召回率的单一数字(公式出现在图3.32和图3.34的最后几行)。

图3.37 这些结果都有一个相同的边界曲线,这个曲线将所有样本都分类为“阳性”。因为每个“阳性”样本都被正确分类了,所以我们获得了完美的召回率。然而,最终得到的准确率和精度都非常差

一般来说,当精度或召回率较低时,f1分数也会较低,而当两项指标都接近1时,f1分数才会接近1,如图3.38所示。

图3.38 当精度或召回率为0时,f1分数为0;而当两者均为1时,f1分数为1。在这两个状态之间,随着两种衡量标准的值的增加,f1分数会慢慢上升

3.8 混淆矩阵的应用

回到MP疾病的例子,在混淆矩阵中加入一些数字,并就这些数字对快速但不准确的血液测试的质量水平提出一些问题。回想之前说过的,我们会同时用缓慢但准确的测试(可以为我们提供基础真值)和快速但不准确的血液测试来为镇上的每个人做检测。

检测结果显示血液测试似乎有很高的召回率。我们发现99%的情况下,MP患者都可以被正确诊断。因为召回率(TPR)是0.99,所以假阴性率(FNR)是0.01,其中包含了我们没有正确诊断出的MP患者。

对于那些未患有MP的人来说,这个测试的效果有一点差。特异性(TNR)是0.98,也就是说,如果我们诊断出100个人未患有MP,那么其中就有98个人真的未患病,这意味着假阳性率(FPR)是0.02,也就是说,其中会有2人被误诊为患有MP。

假设我们刚刚听说,在一个有10 000人的新城镇暴发了一场疑似MP的疫情。根据以往数据,我们预计有1%的人已经被感染。

这是至关重要的信息。我们不是盲目地去测试每一个人,而是已经知道大多数人未患有MP,只有1/100的人患病。但是,即使只有一个人患病,那也是一条生命,所以我们要以最快的速度到达那里。

到达镇上后,我们让每个人都到市政厅来进行测试。假设有一个人的测试结果出现“阳性”,他应该怎么想?他又有多大的可能性真的患有MP?如果相反,有一个人的测试结果出现“阴性”,那他又有多大的可能性真的未患有MP?

我们可以通过构建一个混淆矩阵来回答这些问题。这时,如果我们掉进了陷阱,就可能会将上述的值直接放入相应的框中来构建混淆矩阵,如图3.39所示。但这个矩阵是不完整的,这会使我们得到错误的答案

图3.39 这不是我们要找的混淆矩阵,这个矩阵假设患有MP和未患有MP的概率各占50%。我们知道事实并非如此,但这个图忽略了“只有1%的人患病”这个已知信息

这个矩阵存在的问题是忽略了我们上面提到的关键信息:现在镇上只有1%的人患有MP。图3.39中的混淆矩阵假设患有和未患有MP的机会均等,而事实并非如此。

绘制正确的矩阵需要考虑镇上的10 000人,然后根据我们对感染率和血液测试结果的了解来分析我们能够通过测试得到什么。

先粗略看一下图3.40。我们从左边开始,镇上有10 000个人。最基本的已知信息是:根据以往的经验,每100个人中就有1个人(或者说1%的人)患有MP。这一点体现在图上方的那条路径上。我们划分出了10 000人中的1%(或者说100人)患有MP,而血液测试会正确地诊断出其中的99个人患病、1个人未患病。看完这条路径后,让我们回到初始的人群,在下方的路径上跟踪另外99%的没有被感染的人。通过血液测试将正确诊断出这9900人中的98%(即9702人)为阴性,而这9900人中将有2%的人(即198人)得到不正确的诊断结果——他们将被诊断为患有MP。

图3.40告诉我们应该使用哪些值来填充混淆矩阵,因为这些值的计算是包含了我们已知的1%的感染率的。我们预计(平均)有99个真阳性、1个假阴性、9702个真阴性以及198个假阳性。通过这些值我们可以绘制出如图3.41所示的正确的混淆矩阵。

现在我们有了正确的表格,可以回答下面的问题了。

假设某人的测试结果呈“阳性”,那么他真的患有MP的概率是多少?也就是在已知测试结果呈“阳性”的情况下,一个人真的患有MP的条件概率是多少?

图3.40 通过对感染率和测试结果的了解来计算得到我们预期的结果分布

图3.41 结合已知的1%的感染率,为血液测试绘制的正确的混淆矩阵。混淆矩阵中的值均来自图3.40

换句话说,得到的阳性结果中有多少人是真正的患者?也就是TP/(TP+FP)的比值,我们看到的这个式子是精度的定义。

这种情况下,是99/(99+198)(或者说0.33、33%)。这说明测试有99%的概率正确诊断人们的患病情况。但是,当得出一个阳性结果时,这个人有2/3的概率患病。换句话说,大多数的阳性诊断结果都是错误的

之所以会得出这一令人惊讶的结果,是因为健康人口基数太大,而每个人都有一定的概率(很小的)被误诊为患病。这两者合起来的结果就很惊人。

由此我们得到这样的结论:如果有人的诊断结果为阳性,我们不应该立即采取行动。换言之,我们应该将这个结果看作一个做缓慢但准确的测试的信号。

让我们用区域图来看看这些数字。我们不得不改变区域的大小,以便能够看清它们,并在图3.42中对它们进行标记。

之前讨论过,精度告诉我们诊断结果为“阳性”的人实际上真的患有MP的概率。图3.42也说明了这一点。我们可以从精度中看到,血液测试错误地将198名未患有MP的人标记为阳性。虽然这只是镇上10 000人中很小的一部分,但与仅有100人患了MP相比,这足以引起我们的重视,我们应该更加仔细地审视每一个阳性诊断。

(a)                                        (b)

图3.42 (a)所有人中有100人患有MP,9900人未患有MP。(b)测试结果。它几乎正确地诊断了所有患有MP的人,但是也错误地将198个没有患病的人诊断为“阳性”。注意:图中的区域并没有按照实际比例绘制

如果有人得到一个阴性结果,会发生什么?能说明他们真的未患病吗?TN/(TN+FN)的值可以说明这一点,我们称之为阴性预测值。在这种情况下,阴性预测值的大小是9702/(9702+1),它大于0.999(或者说99.9%)。所以如果有人的诊断结果是“阴性”,血液测试就只有1/10 000的概率出错(这个人患有MP)。

总而言之,一个阳性的诊断结果意味着某人确实患有MP的概率是33%,而阴性的诊断结果则意味着99.9%的概率某人未患有MP。

图3.43还展示了一些其他的度量方法。召回率告诉我们被正确诊断为阳性的人占实际为阳性的人的百分比。因为我们只漏掉了一个人,所以这个值是99%。而特异性告诉我们被正确诊断为阴性的人占实际为阴性的人的百分比。因为我们只将1个人误诊为阴性,所以这个结果也非常接近1。

图3.43 根据图3.42的结果,描绘出了4个与我们的血液测试相关的统计数据

因此,在10 000人中,我们只会漏掉1个MP病例,但会得到近200个误诊为阳性(即假阳性)的病例,这可能会让人们陷入过度的恐慌和担忧。有些人甚至可能立即去进行手术,而不去等待另一个更加漫长的测试。

MP疾病的例子是虚构的,但现实世界中充满了人们基于错误的混淆矩阵或错误的问题来做出的决定,并且很多决定都与非常严重的健康问题有关。例如,因为外科医生错误地理解了乳房检查的结果,向病人提出了糟糕的咨询建议(见[Levitin16]),导致许多女性做了不必要的乳房切除手术。男性也有类似的问题,许多医生会因为对不断升高的PSA水平(诊断前列腺癌的证据,见[Kirby11])的统计数据存在误解,而提出一些不好的建议。概率和统计学是微妙的,从始至终,我们都需要确保使用了正确的数据并合理地对这些数据进行解释。

现在我们意识到,不应该被一些“99%准确率”甚至是“正确识别出99%的阳性病例”的测试所欺骗。在这个只有1%的人被感染的小镇上,任何一个被诊断为阳性的人都很可能没有真正感染这种疾病。

这意味着,从广告到科学,任何情况下,统计数据都需要被密切关注,并且需要被放到应用环境中去理解。通常,像“精密”和“准确”这样的术语的应用是非常口语化(或者说很随意)的,这使得它们更难被理解。即使这些术语在技术场景中被使用,对准确率和其他相关度量方法的无力的解释很容易误导人们做出错误的决定。正如我们之前看到的那样,可以通过测试只找到一个明显患有MP的人,然后宣布他是阳性的,而其他人都是阴性的,这样我们就可以非常诚实地说测试有着100%的精度。图3.44再次展示了这个想法。

图3.44 测试仅识别了一个明显的患有MP的病例(左上角的绿色圆圈)并判断它为阳性。而其他所有人都被归为阴性,不管他们是患有MP(绿色圆圈)还是未患有MP(红色圆圈)。这时,我们仍然可以诚实地说,测试有着100%的精度

参考资料

[Andale17] Andale, Marginal Distribution, Statistics How To Blog, 2017.

[Jaynes03] E. T. Jaynes, Probability Theory: The Logic of Science, Cambridge University Press, 2003.

[Kirby11] Roger Kirby, Small Gland, Big Problem, Health Press, 2011

[Levitin16] Daniel J. Levitin, A Field Guide to Lies: Critical Thinking in the Information Age, Dutton, 2016.

[MetService16] Meteorological Service of New Zealand Ltd., How to Read Weather Maps, 2016.

[Walpole11] Ronald E. Walpole, Raymond H. Myers, Sharon L. Myers, Keying E. Ye, Probability and Statistics for Engineers and Scientists (9th Edition), Pearson, 2011.

[Wikipedia16] Wikipedia, Sensitivity and Specificity, 2016.

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e55451”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。

相关图书

深度学习高手笔记 卷2:经典应用
深度学习高手笔记 卷2:经典应用
深度学习详解
深度学习详解
ChatGPT原理与应用开发
ChatGPT原理与应用开发
深度学习的数学——使用Python语言
深度学习的数学——使用Python语言
人工智能和深度学习导论
人工智能和深度学习导论
动手学深度学习(PyTorch版)
动手学深度学习(PyTorch版)

相关文章

相关课程