天天看點

《樹莓派開發實戰(第2版)》——2.3 使用基本構件:原子元素

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

現在正是積累figaro元素知識的時機。我将首先介紹模型的基本構件——原子元素。原子這一名稱意味着,它們不依賴于任何其他元素,完全是獨立的。在此我不提供完整的原子元素清單,隻介紹最常見的例子。

原子元素根據值的類型分為離散元素和連續元素。離散原子元素取boolean和integer等類型的值,而連續原子元素通常使用double類型的值。從技術上說,離散意味着值之間有很清晰的分隔。例如,整數1和2有很清晰的分隔,其中沒有任何整數。而連續意味着值處于一個沒有分隔的連續域中,如實數。在任何兩個實數之間都有更多的實數。離散和連續元素之間的差異造成了機率定義的差異,第4章中将做介紹。

有些人認為離散就意味着有限。這是錯誤的。例如,整數有無窮多個,但是它們是清晰分隔的,是以是離散值。

關鍵定義

原子元素——不依賴于任何其他元素的獨立元素。

複合元素——由其他元素構成的元素。

離散元素——值類型清晰分隔的元素。

連續元素——值類型沒有分隔的元素。

讓我們來看一些離散原子元素的例子:flip、select和binomial。

flip

您已經看到了離散原子元素flip。flip包含在com.cra.figaro.language包中,該包中有許多最常用的元素。我建議始終在程式開始處導入該包的所有内容。一般來說,flip取一個參數p,表示元素值為真的機率。p應該是0和1(包含)之間的數值。該元素值為假的機率是1-p。例如:

val greeting = select(0.6 -> "hello, world!", 0.3 -> "howdy, universe!", 0.1

println(variableelimination.probability(greeting, "howdy, universe!"))

// prints 0.30000000000000004<code>`</code>

注意,在select中,機率累加起來不一定等于1。如果它們加起來不等于1,機率将被規格化——加起來等于1,同時保持機率之間的比例。在下面的例子中,每個機率都等于前一個例子中的兩倍,是以加總起來等于2。規格化之後恢複成前一個例子中的機率,是以得到相同的結果。

binomial是一個有用的離散元素。想象一下一周有7天,每天都有一個“晴天”元素flip(0.2)。現在您想要一個元素,其值為一周中放晴的天數。這可以用元素binomial(7, 0.2)實作。這個元素的值是總共嘗試7次,每次嘗試為true的機率為0.2的情況下,嘗試結果為true的次數。可以這樣使用它:

import com.cra.figaro.library.atomic.continuous.normal

val temperature = normal(40, 100)<code>`</code>

均值為40,方差為100,意味着标準差為10。現在,假定您想要用這一進制素進行推理。figaro的變量消除算法隻适用于可能取值個數有限的元素。特别是,它不能用于連續元素。是以,需要一個不同的算法。您将使用稱作重要性抽樣的算法,這是一種很适合于連續元素的近似算法。算法的運作方法如下:

import com.cra.figaro.library.atomic.continuous.uniform

val temperature = uniform(10, 70)

importance.probability(temperature, greaterthan50 _)

// prints something like 0.3334<code>`</code>

uniform元素取兩個參數:最小值和最大值。從最小值到最大值的所有值機率密度相同。在前一個例子中,最小值為10,最大值為70,是以範圍的大小為60。您的查詢預測是該值是否在50~70——區間大小為20。是以,預測的機率為20/60或者1/3,可以看到,重要性抽樣得到的結果與此接近。

最後說明一下:這個元素的官方名稱是連續均勻分布(continuous uniform)。在<code>com.cra.figaro.library.atomic.discrete</code>包中還可以找到離散均勻分布。正如您的預期,離散均勻分布明确列出一組值,其中的每個值出現可能性相同。

好了,現在您已經了解了構件,下面我們來看看如何組合它們,建立更大的模型。

繼續閱讀