天天看點

《樹莓派開發實戰(第2版)》——1.3 Figaro簡介:一種機率程式設計語言

本節書摘來異步社群《機率程式設計實戰》一書中的第1章,第1.3節,作者:【美】avi pfeffer(艾維·費弗),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

在本書中,您将使用一種稱為figaro的機率程式設計系統。(我用莫紮特的歌劇《費加羅的婚禮》中的角色為其命名。我喜愛莫紮特,并在該劇于波士頓的一次演出中飾演巴爾托洛醫生。)本書的主要目标是教授機率程式設計的原則,在本書中學到的技術應該可以在其他機率程式設計系統上沿用。附錄b簡單描述了現有的一些系統。但是,本書還有第二個目标——幫助您獲得建立使用機率程式的親身體驗,并提供可以立即使用的工具。是以,許多例子都用figaro代碼實作。

figaro是從2009年開始開發的一個開源軟體,在github上維護。它以scala庫的形式實作。圖1-9說明figaro如何使用scala實作機率程式設計系統。該圖詳細說明了圖1-7,後者描述了機率程式設計系統的主要組成部分。讓我們從機率模型開始,在figaro中,該模型由任意數量的資料結構(稱作“元素”)組成。每個元素代表在您的情境中可取任意數量值的一個變量。這些資料結構用scala實作,您可以用這些資料結構編寫scala程式建立模型。可以通過關于元素值的資訊提供證據,也可以指定希望在查詢中了解的元素。至于推理算法,您可以選擇一個figaro内建推理算法并應用到模型上,根據證據回答您的查詢。推理算法以scala實作,其調用就是一個scala函數調用。推理結果是查詢元素不同值的機率。

《樹莓派開發實戰(第2版)》——1.3 Figaro簡介:一種機率程式設計語言

figaro内嵌于scala提供了一些重大優勢。其中一些來自内嵌于通用宿主語言相對于獨立機率語言的優勢。其他優勢則是因為scala的良好特性。下面是在通用宿主語言中内嵌機率程式設計語言的好處。

證據可以用宿主語言的程式得出。例如,您可以編寫一個程式讀取一個資料檔案,以某種方式處理其中的值,并将其作為證據提供給figaro模型。在獨立語言中,這一任務要難得多。

類似地,您可以在一個程式中使用figaro提供的答案。例如,如果您有一個供足球隊經理使用的程式,該程式可以取得進球機率,向經理提出建議。

可以在機率程式中嵌入通用代碼。例如,假設您有一個模拟頭球在空中飛行軌迹的實體模型,可以在figaro元素中加入這個模型。

可以使用通用程式設計技術建構figaro模型。例如,您可能有一個映射,包含對應于球隊中所有球員的figaro元素,并根據情況中涉及的球員選擇對應的元素。

下面是選擇scala作為内嵌機率程式設計系統的宿主語言的一些理由。

scala是一個函數式程式設計語言,是以figaro也能得到函數式程式設計的好處。正如我在第2部分中所說明的,函數式程式設計對機率程式設計有幫助,許多模型可以自然地以函數式風格編寫。

scala是面向對象的,其優點之一是既是函數式語言,又具有面向對象的特征。figaro也是面向對象的。正如第2部分中将要說明的,面向對象是表達機率程式設計中多種設計模式的有用手段。

最後,figaro還有嵌入scala之外的一些優勢,包括:

figaro能夠表示極其廣泛的機率模型。figaro元素的值可以為任何類型,包括布爾型、整數、雙精度數、數組、樹、圖等。這些元素之間的關系可以由任何函數定義。

figaro提供了使用其條件和限制規定證據的豐富架構。

figaro有多種多樣的推理算法。

figaro能夠表示和推理随時間變化的動态模型。

figaro能夠在其模型中包含明确決策,并支援最優決策的推斷。

由于多種原因,figaro是學習機率程式設計的出色語言。

figaro以scala庫的形式實作,可以用于java和scala程式,很容易與應用程式內建。

由于以程式庫而非獨立語言的形式實作,figaro提供了宿主程式設計語言的全部功能,可以用來構模組化型。scala是進階的現代化語言,具有許多有用的程式組織功能,使用figaro時可以自動獲得這些好處。

從所提供算法的範圍來看,figaro 堪稱全能。

本書強調使用的技術和實用的示例。隻要有可能,我都會解釋模組化的一般原則,并描述在figaro中的實作方法。不管您最終使用哪一種機率程式設計系統,這對您都将大有裨益。并不是所有系統都能輕松地實作本書中的所有技術。例如,現有的面向對象機率程式設計系統很少。但是有了好的基礎,您就可以找出用所選語言表達需求的方法。

使用scala

因為figaro是一個scala庫,需要scala的知識才能使用figaro。本書是關于機率程式設計的,是以在本書中不教授scala的知識。scala的出色學習資源很多,比如twitter的scala school。但是為了防止您對scala不自信,我在本書中對代碼中使用的scala功能加以說明。即使您還不了解scala,也能夠跟上本書的進度。

從機率程式設計和figaro中獲益并不要求您是一位scala奇才,在本書中也避免使用一些較為進階和晦澀的特性。但是,增強scala技能有助于成為更好的figaro程式員。您甚至會發現,閱讀本書也可以提高scala的技能。

figaro與java的對比:建構簡單的機率程式設計系統

為了說明機率程式設計和figaro的好處,我将展示以兩種方式編寫的簡單機率應用。首先,我說明用java(您可能對它很熟悉)編寫這種應用的方法。然後,我将展示用figaro編寫的scala應用。盡管scala相對java有一定的優勢,但是這不是我要指出的主要差别。關鍵的思路是,figaro提供了表示機率模型和用這些模型進行推理的能力,如果沒有機率程式設計,這些能力就不存在。

我們的小應用将作為figaro的“hello,world”示例。想象一下,有個人早上起床,檢視天氣是否晴朗,并根據天氣發出問候。每天發出連續兩天的問候。而且,第二天的天氣取決于第一天:如果第一天是晴天,第二天就更可能是晴天。這些陳述可以由表1-1中的數字量化。

《樹莓派開發實戰(第2版)》——1.3 Figaro簡介:一種機率程式設計語言

下面幾章将明确解釋這些數字的含義。現在,我們直覺地認為今天是晴天的機率為0.2,也就是說,今天有20%的可能放晴。同樣,如果明天是晴天,明天的問候語為“hello, world!”的機率為0.6,也就是說問候語為“hello, world!”有60%的可能性,“howdy, universe!”的可能性為40%。

我們為自己設定了用這個模型執行3種推理任務的目标。在1.1.3小節中您已經知道,用機率模型能夠進行3類推理:預測未來,推斷導緻觀測結果的過去事件,從過去事件中學習以更好地預測未來。您将用我們的簡單模型完成這三種任務。具體任務如下。

1.預測今天的問候語。

2.如果觀測發現今天的問候語是“hello, world!”,推斷今天是不是晴天。

3.從今天對問候語是“hello, world!”這一觀測值的學習,預測明天的問候語。

下面是用java完成這些任務的方法。

程式清單1-1 用java實作的hello world 程式

import com.cra.figaro.language.{flip, select}

import com.cra.figaro.library.compound.if

import com.cra.figaro.algorithm.factored.variableelimination ◁——● //導入figaro結構

object helloworld {

val sunnytoday = flip(0.2)

val greetingtoday = if(sunnytoday,

val sunnytomorrow = if(sunnytoday, flip(0.8), flip(0.05))

val greetingtomorrow = if(sunnytomorrow,

def predict() { ◁——● //用推理算法預測今天的問候語

}

}<code>`</code>

我将等到下一章才詳細解釋這段代碼。現在,我希望指出,它解決了java代碼的兩個問題。首先,模型定義準确描述了對應于表1-1的模型結構。您定義了4個變量:sunnytoday、greetingtoday、sunnytomorrow和greetingtomorrow,它們都對應于表1-1。例如,greetingtoday的定義如下: