天天看点

《树莓派开发实战(第2版)》——1.1 什么是概率编程

本节书摘来异步社区《概率编程实战》一书中的第1章,第1.1节,作者:【美】avi pfeffer(艾维·费弗),更多章节内容可以访问云栖社区“异步社区”公众号查看。

概率编程是一种系统创建方法,它所创建的系统能够帮助我们在面对不确定性时做出决策。许多日常决策涉及在确定无法直接观测的相关因素时的判断能力。历史上,帮助在不确定性下做出决策的方法之一是使用概率推理系统。概率推理将我们对某种情况的认识和概率法则结合起来,确定无法观测的决策关键因素。直到最近,概率推理系统的范围仍然有限,难以应用到许多现实情况中。概率编程是一种新方法,它使概率推理系统更容易构建,适用范围更广。

要理解概率编程,首先要观察不确定性条件下的决策过程和涉及的主观判断。然后,您将了解概率推理是如何帮助您做出决策的。您将注意到概率推理系统所能进行的3种推理,也就能理解概率编程,以及通过编程语言的能力用概率编程构建概率推理系统的方法。

在现实世界中,我们所关心的问题很少有非此即彼的答案。例如,如果您打算启动一个新产品,想要知道它的销路如何。您可能认为它将取得成功,因为您相信它设计精良,市场调查也表明有需求,但是无法确定。您的竞争者可能推出更好的产品,或者您的产品可能有市场不能容许的致命缺陷,经济也可能突然衰退。如果要求百分之百的确定,就无法做出是否投放该产品的决策(见图1-1)。

《树莓派开发实战(第2版)》——1.1 什么是概率编程

概率语言有助于做出此类决策。在投放某个产品时,可以使用类似产品的先期经验估算产品的成功概率。然后,用这一概率帮助决定是否继续推进并投放该产品。您可能不仅关心产品能否成功,还关心它能带来多少收入,或者失败将导致多大的损失。您可以使用不同结果的概率做出更明智的决策。

概率论思想可以帮助您做出艰难的决策和判断,但是,您该怎么做呢?一般原则在下面列出。

事实:主观判断基于知识+逻辑。

您对感兴趣的问题有某些知识。例如,您对产品有深入的了解,可能进行了一些市场调查以找出客户的需求。您还可能有关于竞争对手的情报和经济预测。同时,逻辑帮助您运用知识获得问题的答案。

您需要一种规格化知识的方法,还需要运用知识得出问题答案的逻辑。概率编程提供了规格化知识和回答问题的逻辑。在我描述概率编程系统概念之前,我将描述概率推理系统的一般概念,这种系统提供了规格化知识和提供逻辑的基本手段。

概率推理是使用您的领域模型做出不确定条件下决策的一种方法。举个足球界的例子。假定统计显示9%的角球造成进球。您的任务是预测某次角球的结果。攻方的中锋身高6英尺4英寸(约1.93米),以头球能力著称。守方正选门将刚刚受伤,被第一次出场的替补门将换下。除此之外,咆哮的大风使长传难以控制。那么,如何计算进球的概率?

图1-2展示了使用概率推理系统找出答案的途径。您在一个角球模型中编码关于角球和所有相关因素的知识。然后,提供特定角球的证据,也就是中锋个子很高、守门员缺乏经验以及强风。您告诉该系统,希望知道这次角球是否进球。推理算法返回答案——有20%的概率进球。

《树莓派开发实战(第2版)》——1.1 什么是概率编程

关键定义

一般知识——不考虑特定情况细节时,对领域相关情况的概括了解。

概率模型——用定量的概率术语编码的领域一般知识。

证据——关于特定情况的具体信息。

查询——您希望知道的情况属性。

推理——概率模型根据证据回答查询的过程。

在概率推理中,您创建一个模型,以定量的概率术语捕捉领域的所有相关一般知识。在我们的例子中,这个模型可能是对角球情况和影响结果的所有球员相关特征及条件的描述。然后,对于某个特定情况,您将该模型应用于所拥有的具体信息,得出结论。这些具体信息称为证据。在本例中,证据是中锋身材高大,守门员缺乏经验,风力很大。所得出的结论可以帮助您决策——例如,您是否应该在下一场比赛中更换不同的守门员。结论本身以概率的方式描述,比如守门员的不同技能水平的概率。

模型、您所提供的信息和查询答案之间的关系由数学上的概率法则定义。根据证据,运用模型回答查询的过程称作概率推理或者简单地称作推理。幸运的是,计算机算法已经有了很大的发展,能够为您完成这些数学题,自动进行所有必要的计算。这些算法被称作推理算法。

图1-3总结了您所学到的知识。

《树莓派开发实战(第2版)》——1.1 什么是概率编程

简言之,我们刚刚讨论的是概率推理系统的组成,以及与之互动的方式。但是,如何利用这样的系统?它如何帮助您决策?下一小节描述了概率推理系统所能执行的3类推理。

概率推理系统很灵活。它们可以根据任何方面的证据,回答关于情况其他特征的查询。在实践中,概率推理系统执行3类推理。

预测未来的事件。在图1-2中您已经看到此类推理,根据当前情况预测是否进球。您的证据通常包括关于当前情况的信息,如中锋身高、守门员的经验和风力。

推断事件的根源。快进10秒。高个中锋刚刚头球射门,从守门员身下入网,取得一分。根据这一证据,您对这位新手守门员有何想法?您能否得出结论,她的技能不足?图1-4说明如何使用概率推理系统回答这个问题。该模型是您之前用于预测是否进球的同一个角球模型(这是概率推理的一个实用属性:用于预测未来结果的模型同样可以在事后推断结果的根源)。使用的证据和以前一样,并结合了角球得分这一事实。查询是守门员的技能水平,答案提供了不同技能水平的概率。

《树莓派开发实战(第2版)》——1.1 什么是概率编程

想想看,第一种推理模式描述了前向推理,根据对当前情况的了解预测未来的事件,而第二种推理模式描述了后向推理,根据当前结果推断过去的条件。在构建概率模型时,模型本身通常遵循自然的时间顺序。一名球员踢角球,风作用于球,中锋跃起头球,守门员做出扑救。但是推理可以向前和向后进行。这是概率推理的关键特征之一,我在本书中将反复重申这一点:推理的方向不一定遵循模型的方向。

从过去的事件中学习,更好地预测未来的事件。现在,再快进10分钟。同一球队又获得一次角球机会。所有情况与前面类似——高中锋、缺乏经验的守门员,但是现在风力减弱了。使用概率推理,可以利用前一次角球发生的情况,帮助您预测下一次角球的结果。图1-5说明了这一点。证据包括上一次的所有证据(注明其来自上一次)以及当前情况的新信息。在回答这次角球能否进球时,推理算法首先推断导致第一次进球的条件,例如中锋和守门员的技能水平。然后,它利用这些更新的属性做出关于新情况的决策。

《树莓派开发实战(第2版)》——1.1 什么是概率编程

这些类型的查询能够帮助您做出许多层次上的决策。

您可以根据有无额外防守队员进球的概率,决定是否用一名防守队员替换进攻队员。

可以根据对守门员技能的评估,决定下一次合同谈判时向他提出的工资数额。

可以利用了解到的守门员相关情况,帮助预测下一场比赛的结果,决定是否使用同一名守门员。

学习更好的模型

上述3种推理模式提供了特定情况、给定证据下的推理手段,利用概率推理系统,还可以从过去的情况中学习,改善您的一般知识。在第三种推理模式中,您了解到如何从特定的过去经验学习,更好地预测未来的情况。另一种从过去的经验中学习的方法是改善模型本身。特别是在拥有许多过去的经验可以吸取时(如许多次角球),您可能希望学习一个新模型,以表示角球通常发生情况的一般知识。如图1-6所示,这可以通过一个学习算法实现。与推理算法有些不同,学习算法的目标是产生新的模型而不是回答查询。学习算法从原始模型入手,根据经验更新之,产生新的模型。新模型可以用于回答未来的问题。可以推测,使用新模型产生的答案应该比原始模型更明智。

《树莓派开发实战(第2版)》——1.1 什么是概率编程

概率推理系统与精确的预测

和任何机器学习系统一样,概率推理系统得到的数据越多,预测就越精确。预测的质量取决于两个因素:原始模型精确反映现实情况的程度和您所提供的数据量。一般来说,提供的数据越多,原始模型就越不重要,这是因为新模型是原始模型和数据所包含信息之间的一个平衡。如果您的数据很少,原始模型占据统治地位,所以它的质量必须很高才能得出准确的预测。如果您拥有许多数据,数据将占据统治地位,新模型倾向于忘掉不那么重要的原始模型。例如,如果您从整个足球赛季中学习,应该能够准确地学习到影响角球的因素。如果只有一场比赛的数据,就需要首先对精确预测比赛所需的因素有出色的想法。概率推理系统将很好地利用给定的模型和可用数据,尽可能精确地做出预测。

现在,您已经了解了概率推理的概念。那么,什么是概率编程?

每个概率推理系统都使用某种表示语言表达其概率模型。表示语言有许多种,您可能已经听说了其中一些,如贝叶斯网络(也称作置信网络)和隐含马尔科夫模型。表示语言控制系统可处理的模型以及模型的情况。语言所能表示的一组模型称作语言的表达能力。对于实际应用,您肯定希望表达能力尽可能强。

简单地说,概率编程系统是以编程语言作为表示语言的概率推理系统。我所说的编程语言是指具有编程语言所有预期特征(如变量、丰富的数据类型、控制流、函数等)的语言。正如您将要看到的,概率编程语言可以表达极其广泛的概率模型,超越传统的概率推理框架。概率编程语言有极强的表达能力。

图1-7说明了概率编程系统与概率推理系统的关系。可以将该图与图1-3比较,以凸显两种系统之间的差别。主要的变化是,模型以编程语言编写的程序表达,而不使用贝叶斯网络等数学结构。由于这种变化,证据、查询和答案都应用到程序中的变量。证据可能指定程序变量的特定值,查询询问程序变量的值,答案是不同查询变量值的概率。此外,概率编程系统通常带有一套推理算法。这些算法适用于以该语言编写的程序。

《树莓派开发实战(第2版)》——1.1 什么是概率编程

尽管存在许多类概率编程系统(参见附录b),本书的重点是函数式的图灵完备系统。函数式意味着它们基于函数式编程,但是不要被它吓住——使用函数式概率编程系统并不需要知道λ函数(lambda)等概念。这一切只意味着,函数式编程提供了这些语言表示概率模型的理论基础。同时,图灵完备是一句行话,表示编程语言可以编写任何能在数字计算机上完成的计算。如果某一运算可以在数字计算机上完成,就可以由任何图灵完备语言实现。您所熟悉的大部分编程语言,如c、java和python,都是图灵完备的。因为概率编程语言构建于图灵完备编程语言基础上,它们可以构建的模型类型极其灵活。

表示语言——用于编码关于模型领域知识的语言。

表达能力——表示语言编码模型中不同类型知识的能力。

图灵完备——能够表示可在数字计算机完成的任何计算的语言。

概率编程语言——使用图灵完备编程语言表示知识的概率表示语言。

附录b论述了除本书使用的figaro之外的一些概率编程系统。这些系统大部分都使用图灵完备语言。有一些系统(包括bugs和dimple)没有使用图灵完备语言,但是它们对目标应用很实用。本书主要关注图灵完备概率编程语言的能力。

将概率模型表示为程序

但是,编程语言如何成为概率建模语言?如何将概率模型表示为程序?我将在这里提出回答这一问题的一些线索,将更深入的讨论放在稍后的章节,那时您已经对概率程序有所了解。

编程语言的核心思路之一是执行。您执行一个程序以产生输出。概率程序也类似,但是它可以有许多执行路径,每个路径产生不同的输出。在程序中随机选择执行路径,每个随机的选择有许多可能的结果,程序编码每种结果的概率。因此,概率程序可以视为随机执行以产生输出的一个程序。

图1-8说明了上述概念。在图中,概率编程系统包含了一个角球程序。这个程序描述生成角球结果的随机过程,它取得一些输入;在我们的例子中,这些输入是中锋的身高、守门员的经验和风力。根据这些输入,程序随机执行以生成输出。每次随机执行产生特定的输出。因为每个随机选择都有多种可能结果,存在许多可能的执行路径,造成不同的输出。任何给定输出(如进球)可能由多个执行路径产生。

让我们来看看,这种程序如何定义概率模型。从一系列随机选择形成的任何特定执行路径都有特定的结果。每个随机选择都有发生的概率。如果将这些概率相乘,就可以得到执行路径的概率。这样,程序定义了每个执行路径的概率。想象一下,如果将该程序运行许多次,生成任何给定执行路径的次数比例等于其概率。输出的概率就是产生该输出的程序运行次数比例。在图1-8中,1/4的运行产生进球的结果,所以进球概率为1/4。

《树莓派开发实战(第2版)》——1.1 什么是概率编程

注意:

您可能疑惑于为什么图1-8中的块标签为“随机执行”而不是其他插图中的推理算法。图1-8展示了概率程序的含义——定义一个随机执行过程,而不是使用概率编程系统的方式——使用推理算法根据证据回答查询。所以,尽管上述插图的结构类似,但是表达了不同的概念。事实上,随机执行形成了某些推理算法的基础,但是许多算法并不基于简单的随机执行。

利用概率编程决策

使用概率编程预测未来很容易理解。只要随机多次执行程序,使用当前已知的信息作为输入,并观察每个输出的出现次数。在图1-8的角球示例中,多次执行该程序,以高中锋、缺乏经验的守门员和强风作为输入。因为1/4的运行得出进球的结果,您可以认定在这些输入条件下,进球概率为25%。

但是,概率编程的魔法在于,它还可以用于1.3.1小节中描述的各类概率推理。概率编程不仅可用于预测未来,还可以推断导致特定结果的事实;您可以“展开”程序,发现结果的根源,还可以在某种情况下应用程序,从结果中学习,在未来使用学习到的信息做出更好的决策。可以使用概率编程做出所有通过概率思想得到的决策。

概率编程是如何工作的?当人们意识到,在较简单的表示语言(如贝叶斯网络)上有效的推理算法可以扩展到程序上时,概率编程就变得实用了。本书的第3部分介绍实现这一扩展的各种推理算法。幸运的是,概率编程系统自带一些内建的推理算法,这些算法可以自动地应用到您的程序中。您所需要做的是以概率程序的形式提供领域知识并指明证据,系统负责推断和学习。

在本书中,您将学习通过概率编程进行概率推理。首先,您将学习概率模型的概念以及使用它得出结论的方法。您还将学习一些从简单组件构成的模型中得出那些结论所需进行的操作。您将学习各种建模技术,以及使用概率编程实现它们的方法,还将了解概率推理算法的工作原理,以便有效地设计和使用自己的模型。在阅读完本书之后,您将能够自信地使用概率编程得出有益的结论,帮助您在面对不确定性时做出决策。

继续阅读