概率编程实战

内容简介

概率推理是不确定性条件下做出决策的重要方法,在许多领域都已经得到了广泛的应用。概率编程充分结合了概率推理模型和现代计算机编程语言,使这一方法的实施更加简便,现已在许多领域(包括炙手可热的机器学习)中崭露头角,各种概率编程系统也如雨后春笋般出现。

本书的作者 Avi Pfeffer 正是主流概率编程系统 Figaro 的首席开发者,他以详尽的实例、清晰易懂的解说引领读者进入这一过去令人望而生畏的领域。通读本书,可以发现概率编程并非“疯狂科学家”们的专利,无需艰深的数学知识,就可以构思出解决许多实际问题的概率模型,进而利用现代概率编程系统的强大功能解题。

本书既可以作为概率编程的入门读物,也可以帮助已经有一定基础的读者熟悉 Figaro 这一概率编程利器。

本书的主要内容:

  • 概率建模入门
  • 用 Figaro 编写概率程序
  • 构建贝叶斯网络
  • 预测产品生命周期
  • 决策算法

本书使用的 Figaro 概率编程语言是 Scala 库,这使得概率编程模型更容易与 Java 虚拟机应用集成。同时,Figaro 具备了目前概率编程系统中非常广泛的表现特征和推理算法。Figaro 还是一个开源 GitHub 项目,全新版本号为3.3。

媒体推荐

“概率编程从研究实验室走向现实世界的重要一步。”

——摘自本书序言,Stuart Russell,加州大学伯克利分校教授

“清晰的示例和对困难、复杂主题的详尽解释。”

——Mark Elston,Advantest America

“连贯、实用、易于理解。这是一本不可思议的 Scala 概率编程实战书籍。”

——Kostas Passadis,IPTO

作者简介

[美]Avi Pfeffer(艾维 · 费弗),概率编程的先驱,Figaro 概率编程语言的首席设计者和开发者。在 Charles River Analytics 公司,Avi Pfeffer 致力于 Figaro 在多个问题上的应用,包括恶意软件分析、汽车健康监控、气象模型建立和工程系统评估。在闲暇时,Avi Pfeffer 是一位歌手、作曲家和音乐制作人。他和妻子及三个孩子在马萨诸塞州坎布里奇生活。

本书内容

1814年,皮埃尔 · 西蒙 · 拉普拉斯写道,“在很大程度上,人生最重要的问题就是概率问题。”此后过了100多年,回答这些问题(这一格言依然正确)的唯一方法是用笔和纸分析每个问题,得到结果的公式,手工填入数字以求得公式值。计算机的出现对这一情况并没有很大的改变,只是能够为包含更多数字的更复杂公式求值,纸笔分析也变得更加雄心勃勃,往往用纸数百页。

概率问题的分析需要构思概率模型,这种模型以某种方式规划概率空间,为其指定数值化概率。过去,概率模型用自然语言文本和半正式的数学标记法的组合写下。从模型中,经过进一步数学处理得出计算答案的公式或者算法。这些阶段都十分费时费力、容易出错,而且存在特定于具体问题的难点,使概率理论的适用性受到了严重的限制。尽管拉普拉斯在多年前就已提出,但是这个生活中最重要的问题仍然没有答案。

解决上述问题的第一个重要进步是定义概率模型所用的形式语言的发展,例如贝叶斯网络和马尔科夫网络。形式语言具有定义正确表达式的精确语法,以及定义每种正确表达式含义的精确语义(即每个表达式表示哪种概率模型)。因此,用机器可理解的形式描述概率模型,开发一个算法计算任何可表达概率模型结果都成为可能。

在前面的叙述中,美中不足的是:可表达概率模型的缺乏。实际上,贝叶斯和马尔科夫网络等形式语言表达能力相当有限。从某种意义上说,它们只是布尔电路的概率模拟。为了对这一局限性的含义有所了解,我们考虑一个问题:编写大型公司所用的工资单软件。在 Java 等高级编程语言中,这可能涉及数万行代码。现在,想象一下将许多逻辑门电路连接起来完成相同的功能。这样的任务似乎完全无法完成。这样的电路规模、复杂度和清晰性都无法想象,因为电路缺乏捕捉问题结构的表达能力。

1997年,本书作者 Avi Pfeffer(当时还是个学生)和他的导师 Daphne Koller 以及协作者 David McAllester 发表了一篇关于概率编程语言(PPL)的原创论文,提供了将概率理论与高级编程语言联系起来的关键思路。这一思路是通过引入随机元素使程序成为概率模型,并将程序的意义定义为每个可能执行路径的概率。这一思路以高效的方式结合了数学的两个最重要分支,我们接下来将要开始探索由此产生的新可能性。

本书使用 Figaro 语言阐述这些概念及其应用,逐步引领读者理解上述思路。书中避开了不必要的数学知识,集中于详细构思、认真解释的实例,适合于拥有典型编程背景的读者。通读本书还有一个副产品:读者能够比以往更轻松地熟练掌握贝叶斯推理和统计学的原理及技术。最重要的是,读者将学习建模技能,这是任何科学家或者工程师的最关键技能之一。Figaro 和其他 PPL 使人们可以直接、快速、精确地表现这种技能。

本书是将概率编程从开发它的实验室中转移到真实世界的重要步骤。从某种程度上说,PPL 系统的能力无疑还难以应对这种挑战,那些研究实验室也将停止工作。另一方面,本书的读者一定能找出应用 Figaro 的创新方法,它与各种新问题的相关性也绝非作者所能想象的。

Stuart Russell

加州大学伯克利分校计算机科学教授

前言

概率编程是一个激动人心的新领域,正在快速地引起人们的兴趣,从学术领域进入程序员的世界中。本质上,概率编程是创建概率推理模型的新方法,这种模型用来根据观测预测或者推理未知的事物。概率推理很久以来都是机器学习的核心方法之一,在机器学习中,使用了概率模型来描述从经验中得到的知识。在概率编程之前,概率推理系统局限于包含贝叶斯网络等简单、固定结构的模型。而概率编程提供了编程语言的全部能力以表现模型,使概率推理系统摆脱了这些桎梏。这正如从电路转向高级编程语言。

我从青少年时代用 BASIC 语言开发一个足球模拟程序时就致力于概率编程,只是当时还没认识到。这个模拟程序使用“GOTO 1730+RANDOM*5”这样的指令表示随机的事件顺序。经过精心的调校,模拟程序已经很逼真,足以让我娱乐数个小时。当然,在随后的岁月中,概率编程已经逐渐成熟,不再只是包含随机目标的 GOTO 语句了。

1997年,我和 Daphne Koller、David McAllester 合作编撰了第一篇关于概率编程的论文。这篇论文引入了一种类似 Lisp 的概率语言,但是主要的创新是根据关于输出的证据,推理程序可能特征的一种算法。这一创新不仅提供了运行程序以获得可能执行方式的手段,还反向论证和推理了产生观测结果的原因,从而使概率语言超越了典型的概率模拟语言。

21世纪初,我开发了第一种基于函数式编程的通用概率编程系统 IBAL。IBAL 有很强的表达能力并包含新型推理算法,但是几年之后,我逐渐对其局限性感到不满,主要是难以与数据交互、与应用程序集成。这些局限性促使我在2009年开始开发新的概率编程系统,我将其定名为 Figaro。Figaro 以实用性作为首要目标,同时并没有牺牲概率编程能力。这导致了将 Figaro 作为 Scala 程序库的设计决策,该决策使得概率编程模型更容易与 Java 虚拟机应用集成。同时,Figaro 具备了我所知的概率编程系统中最广泛的表现特征和推理算法。Figaro 现在是一个开源 GitHub 项目,最新版本号为3.3。

概率编程可能是一种难以掌握的技术,因为它需要多种技能,其中主要的是编写概率模型和编写程序的能力。对于许多程序员来说,编写程序很自然,但是概率建模有些神秘。本书的目的是揭开概率建模的神秘面纱,告诉您如何在创建概率模型时高效编程,帮助您有效地使用概率编程系统。本书假定读者在机器学习或者概率推理上没有任何背景。函数式编程和 Scala 的经验有所帮助,但是要使用本书并不一定要成为 Scala 的奇才,Scala 专业知识也可能因为阅读本书而增长。

阅读本书之后,您应该可以在没有机器学习博士学位的情况下,为许多应用程序设计概率模型,从数据中获得有意义的信息。如果您是某个领域的专家,本书能够帮助您表达脑海中或者纸面上的模型,使它们可以运算,实现对不同概率的计算和分析。如果您是一位数据科学家,本书可以帮助您开发比其他工具更丰富、更详细和更精确的模型。如果您是软件工程师或者架构师,正寻求在系统中加入不确定情形下的推理能力,本书不仅能够帮助您构建处理不确定性的模型,还能将这些模型集成到应用程序中。不管因为何种原因选择本书,我都希望您能够喜欢它,并从中得益。

致谢

本书的创作经过了许多年:从关于概率编程的第一个思路,到 IBAL 和 Figaro 系统的创建,再到构思、编写并与 Manning 出版社一起完善。在这段时间里,许多人贡献了自己的力量,使本书得以面世。

本书的出版很大程度上归功于我在 Charles River Analytics 的团队的努力:Joe Gorman、Scott Harrison、Michael Howard、Lee Kellogg、Alison O’Connor、Mike Reposa、Brian Ruttenberg 和 Glenn Takata。还要感谢 Scott Neal Reilly 从一开始就支持 Figaro。

在人工智能和机器学习方面,给我最大教益的是我的导师和合作者 Daphne Koller。Stuart Russell 为我提供了学习人工智能的第一个机会,在整个职业生涯中鼓励我,并成为最新的合作者和本书的序言撰写者。Mike Stonebraker 在其 Postgres 项目中为我提供了第一个研究机会,在他的小组中工作时,我学到了许多关于系统构建的知识。Alon Halevy 曾邀请我和他在 AT&T 实验室中一起度过一个夏季,我在那里第一次和 David McAllester 讨论关于概率编程的问题,成果就是和 Daphne 合作编写的 Lisp 概率论文。当这些思路刚刚萌芽时,我总是和我的合作者和同事 Lise Getoor 一起探讨。

我深深感谢 Alex Ihler,他慷慨地贡献自己的专业知识,认真阅读本书以审核技术上的准确性。过去几年中,在所有与推理相关的事情上,Alex 总是极好的意见反馈者。

在不同的发展阶段,还有其他许多人提供了意见,包括 Ravishankar Rajagopalan、Shabeesh Balan、Chris Heneghan、Clemens Baader、Cristofer Weber、Earl Bingham、Giuseppe de Marco、Jaume Valls、Javier Guerra Giraldez、Kostas Passadis、Luca Campobasso、Lucas Gallindo、Mark Elston、Mark Miller、Nitin Gode、Odisseyas Pentakolos、Peter Rabinovitch、 Phillip Bradford、Stephen Wakely、Taposh Dutta Roy 和 Unnikrishnan Kumar。

感谢 Manning Publications 的许多出色员工对本书出版的帮助。特别要感谢编辑 Dan Maharry 使这本书远远超过了我自己完成的质量,还要感谢 Frank Pohlmann 鼓励我编写本书,并且帮助我准备写作过程。

感谢空军研究实验室(AFRL)和国防部高级研究计划署(DARPA)对本书所描述的先进机器学习概率编程(PPAML)项目中某些工作的投资。特别要感谢几位 DARPA 项目经理,Bob Kohout、Tony Falcone、Kathleen Fisher 和 Suresh Jagannathan,他们对概率编程深信不疑并致力于实现它。

最后,如果没有家人的爱和支持,本书也不可能出版。感谢我的妻子 Debby Gelber 和孩子们(Dina、Nomi 和 Ruti),你们都是了不起的人。永远感谢我的母亲 Claire Pfeffer 用自己的爱养育了我。谨以本书献给你们。

关于本书

不管商业、科学、军事上还是日常生活中,许多决策都涉及不确定情况下的判断。当不同的因素将您引向不同方向,如何知道最应该注意的是哪个方面?概率模型可以表达关于您所处情况的所有相关信息。概率推理使用这些模型确定对决策影响最大的变量的概率。您可以使用概率推理预测最可能发生的情况:您的产品能否在目标价格上取得成功;患者对特定疗法的反应是否良好;您的候选人如果采用某种立场,能否赢得选举?您还可以使用概率推理推导出所发生情况的可能原因:如果产品失败,是不是因为价格太高?

概率推理也是机器学习的主要方法之一。您在概率模型中编码关于所在领域的初始信念,如用户对市场产品的一般反应。然后,提供训练数据(可能与特定产品的用户反应有关),更新信念以获得新模型。现在,可以使用新模型预测未来的结果,如规划中的产品是否成功,或者推导出观测结果的可能原因,如新产品失败的原因。

过去,概率推理使用专用语言表示概率模型。近年来,我们意识到可以使用常规的编程语言,这造就了概率编程。概率编程有三大好处。首先,在构建模型时,可以从编程语言的所有特征中获益,如丰富的数据结构和控制流。其次,概率模型很容易与其他应用程序集成。第三,可以从用于论证模型的通用推理算法中获益。

本书的目标是提供在日常活动中使用概率编程的知识。特别是:

如何构建概率模型并以概率程序表达。

概率推理的工作原理以及如何以各种推理算法实现。

如何使用 Figaro 概率编程系统构建实用的概率程序。

Figaro 以 Scala 程序库的形式实现。和 Scala 一样,Figaro 结合了函数式和面向对象编程风格。这对于不了解函数编程的人来说很有用。本书不使用高级函数式编程概念,所以您应该能在对此了解有限的情况下理解。同样,对 Scala 有所了解是有益的。尽管本书中常常会解释 Scala 的结构,但不是 Scala 的简介。同样,本书通常不使用 Scala 较为难懂的功能,所以略有涉猎就应该足够了。

路线图

本书的第1部分简介概率编程和 Figaro。第1章首先解释概率编程的定义及其实用性,然后简单介绍 Figaro。第2章是 Figaro 的使用教程,帮助您很快地了解概率程序的编写。第3章提供了一个完整的概率编程应用——一个垃圾邮件过滤器,包括论证给定电子邮件是常规邮件还是垃圾邮件的组件,以及从训练数据学习概率模型的组件。第3章的目标是在详细介绍建模技术之前,提供各种技术相互融合的全貌。

第2部分介绍概率程序的构建。第4章包含有关概率模型和概率程序的基本材料,这对理解它们,真正了解创建概率程序时需要做什么很重要。第5章提供了两种作为概率编程核心的建模框架——贝叶斯网络和马尔科夫网络。第6~8章描述了一组用于构建更高级程序的实用编程技术。第6章讨论使用 Scala 和 Figaro 集合组织涉及许多同类变量的程序的方法。第7章讨论面向对象编程,这种方法对于概率编程和常规程序同样有益。第8章介绍建模动态系统。动态系统是状态随时间推移而变化的系统,是这一章深入介绍的概率推理极其常见和重要的应用。

第3部分向您传授关于概率推理算法的知识。理解推理对于有效使用概率编程很重要,这样您就可以使用适合于任务的算法,对合适的方式配置,以支持有效推理的方式表达模型。第3部分在传授算法理论和使用这些算法的实践技巧之间达成了平衡。第9章是基础,介绍了捕捉概率推理中使用的主要思路的3条原则。第10章和第11章描述了两个主要的推理算法家族。第10章描述因子分解算法,包括对因子及其工作原理的介绍,以及变量消除和置信传播算法。第11章介绍抽样算法,特别关注重要性抽样和马尔科夫链蒙特卡洛算法。第10章和第11章专注于计算感兴趣的变量概率的基本查询,而第12章介绍如何使用因子分解和抽样算法计算其他查询,如多变量联合概率、变量最大可能值和观测证据的概率。最后,第13章讨论两个高级而重要的推理任务:监视随时变化的动态系统,从数据中学习概率模型的数值参数。

每章都有一组练习,涵盖了从简单计算、编程任务到开放思维练习的范围。

本书还包括两个附录。附录 A 是 Figaro 的安装指南。附录 B 是其他概率编程系统的概况。

关于代码和练习

本书的代码以等宽字体显示,以便和正文分开。许多代码清单中含有代码注释,强调了重要的概念。在某些情况下,清单之后有链接到解释的编号项目。

本书包含许多代码示例,其中大部分可以从本书网站www.manning.com/books/practical-probabilistic-programming的在线代码库中找到。该网站还包含部分练习答案。

关于作者

Avi Pfeffer 是概率编程的先驱,从一开始就活跃于这个领域。Avi 是 Figaro 的首席设计者和开发者。在 Charles River Analytics,Avi 参与了 Figaro 在多个问题上的应用,包括恶意软件分析、汽车健康监控、气象模型建立和工程系统评估。

在闲暇时,Avi 是一位歌手、作曲家和音乐制作人。他和妻子及三个孩子在马萨诸塞州坎布里奇生活。

作者在线

购买本书就可以免费访问 Manning Publications 运营的一个私有网络论坛,在那里可以评论本书,提出技术问题,讨论书中的练习,从作者和社区那里得到帮助。在www.manning.com/books/practical-probabilistic-programming可以访问和订阅该论坛。这个页面提供了关于注册后如何访问论坛、论坛提供的帮助类型以及行为准则的信息。

Manning 对读者的承诺是,提供读者之间和读者与作者之间有意义对话的途径。我们不能承诺作者的参与度,他们对论坛的贡献完全是自愿(无偿)的。我们建议读者向作者提出挑战性的问题,以免他们失去兴趣!

只要本书仍在销售中,作者在线论坛和过去讨论的存档都可以在 Manning 网站上访问。

关于封面

本书封面上的插图题为“威尼斯人”。这幅插图取自一本法国旅游图书——J. G. St. Saveur 于1796年出版的《旅游百科全书》。当时,旅游消遣还是相当新颖的现象,这样的旅游指南很受欢迎,它向旅游者和空谈旅游家介绍了法国和海外其他地区的风土人情。

《旅游百科全书》中丰富的插图生动地讲述了200年前世界各个城市和地区的独特个性。当时,在两个距离仅为几十英里的地区,人们的穿着就足以独特地反映所属地区。这本旅游指南展示了当时与其他历史时代(除了快节奏的现在)的孤立感和距离感。

当时的着装规范已经变化,各个地区的多样化也逐渐消失。现在,往往难以分辨不同大陆的居民。从乐观的角度看,我们用文化和视觉上的多样性换来了更多彩的个人生活——或者更丰富、有趣的知识和技术生活。

Manning 通过复活这本旅游指南中的插图,用两个世纪前丰富多彩的地域性差别赞美计算机行业的创造性和乐趣。

第1部分 概率编程和 Figaro 简介

什么是概率编程?它有什么用处?如何使用它?这些问题是第1部分的主题。第1章介绍概率编程的基本思路。首先介绍概率推理系统的概念,说明概率编程如何将传统的概率推理系统概念和编程语言技术相结合。

在本书中,您将使用 Figaro 概率编程系统。第1章简要介绍 Figaro,第2章提供所有 Figaro 主要概念的简单教程,帮助您快速开始编写概率程序。第3章介绍一个完整的概率编程应用程序,为您提供实际应用程序组合的全貌。虽然这一章接近全书的开头,因此您从一开始就一窥全局,但是在阅读本书的更多章节,已经学习到更深入的概念时,仍值得不时复习。

第1章 概率编程简介
第2章 Figaro 快速教程(上)
第2章 Figaro 快速教程(下)
第3章 创建一个概率编程应用程序(上)
第3章 创建一个概率编程应用程序(下)
第2部分 编写概率程序
第4章 概率模型和概率程序(上)
第4章 概率模型和概率程序(下)
第5章 用贝叶斯和马尔科夫网络建立依赖性模型(上)
第5章 用贝叶斯和马尔科夫网络建立依赖性模型(下)
第6章 使用 Scala 和 Figaro 集合构建模型(上)
第6章 使用 Scala 和 Figaro 集合构建模型(下)
第7章 面向对象概率建模(上)
第7章 面向对象概率建模(下)
第8章 动态系统建模(上)
第8章 动态系统建模(下)
第9章 概率推理三原则(上)
第9章 概率推理三原则(下)
第10章 因子分解推理算法(上)
第10章 因子分解推理算法(下)
第11章 抽样算法(上)
第11章 抽样算法(下)
第12章 处理其他推理任务
第13章 动态推理和参数学习
附录 A 获取和安装 Scala 和 Figaro
附录 B 概率编程系统简况

阅读全文: http://gitbook.cn/gitchat/geekbook/5b8ce0d015deb02924ce4a13

你可能感兴趣的:(概率编程实战)