Dorian’s Math

PRACTICE / PROBABILITY STATISTICS

用 Python 看條件機率

比較運算、述詞、蒙提霍爾問題,以及依證據更新,採 CS61A 的風格。

單選

Python 會顯示什麼?比較一個串列

Python 會顯示什麼?

>>> child1 = [1, 2, 1]
>>> child1 == 1
你的答案

選擇一個答案。

提示
1

Python 的 == 會拿左邊的整個值和右邊的整個值比較。

2

一個串列可能等於一個數字嗎?

參考解答

False。Python 把整個串列 [1, 2, 1] 和數字 1 比較,兩者不相等。它不會逐元素比較;在 R 裡,child1 == 1 則會得到 TRUE FALSE TRUE。要得到 [True, False, True],請寫 [c == 1 for c in child1]。

來源: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

填空

Python 會顯示什麼?用 and 計數

Python 會顯示什麼?

>>> pairs = [(1, 1), (1, 2), (2, 1), (1, 1)]
>>> sum([c1 == 1 and c2 == 1 for c1, c2 in pairs])
你的答案

可以輸入整數、小數或分數,例如 1/2。 這題需要精確值。

提示
1

生成式的結果是 [True, False, False, True]。

2

sum 把每個 True 當作 1。

參考解答

2。只有第一組和最後一組的兩個值都是 1,所以串列是 [True, False, False, True],加總為 2。這就是 AA=兩個都是女孩時的 nABn_{AB}。

來源: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Python

估計條件機率

完成 conditional_frequency(outcomes, a, b)。a 和 b 是述詞,也就是接收一個結果、傳回 True 或 False 的函式。請傳回 nAB/nBn_{AB}/n_B:兩者都成立的結果數,除以 b 成立的結果數。如果 b 從未成立,傳回 None。

你的答案

Python 函式練習。Tab 會移動焦點;選取程式行後,可用按鈕調整縮排。

公開測試

1. Elder child is a girl

>>> families = [(1, 1), (1, 2), (2, 1), (2, 2)]
>>> both_girls = lambda f: f == (1, 1)
>>> conditional_frequency(families, both_girls, lambda f: f[0] == 1)
0.5

2. At least one girl

>>> families = [(1, 1), (1, 2), (2, 1), (2, 2)]
>>> both_girls = lambda f: f == (1, 1)
>>> round(conditional_frequency(families, both_girls, lambda f: 1 in f), 3)
0.333

3. B never happens

>>> families = [(1, 1), (1, 2), (2, 1), (2, 2)]
>>> both_girls = lambda f: f == (1, 1)
>>> conditional_frequency(families, both_girls, lambda f: False) is None
True

4. Other outcomes

>>> rolls = [1, 2, 3, 4, 5, 6]
>>> conditional_frequency(rolls, lambda r: r == 6, lambda r: r % 2 == 0)
0.3333333333333333
提示
1

用 sum(1 for o in outcomes if b(o)) 數出 nBn_B。

2

用同樣的方式數出 nABn_{AB},條件改成 a(o) and b(o)。

3

除法之前先檢查 nB=0n_B = 0 的情況。

參考解答
def conditional_frequency(outcomes, a, b):
    n_b = sum(1 for o in outcomes if b(o))
    n_ab = sum(1 for o in outcomes if a(o) and b(o))
    return None if n_b == 0 else n_ab / n_b

這個函式對小孩或骰子一無所知,只會呼叫傳進來的述詞;正因如此,一個定義就能回答筆記中的每個問題。

來源: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Python

蒙提會開哪一扇門?

針對 1、2、3 號門,完成 monty_opens(chosen, car)。蒙提從不打開玩家選的門,也不打開有汽車的門。當有兩扇門可以開(玩家正好選中汽車)時,傳回編號較小的那一扇,讓結果可以預測。

你的答案

Python 函式練習。Tab 會移動焦點;選取程式行後,可用按鈕調整縮排。

公開測試

1. Only one door allowed

>>> monty_opens(1, 2)
3
>>> monty_opens(2, 1)
3
>>> monty_opens(3, 1)
2

2. Player picked the car

>>> monty_opens(1, 1)
2
>>> monty_opens(2, 2)
1
>>> monty_opens(3, 3)
1
提示
1

逐一檢查 (1, 2, 3) 中的每扇門,只留下既不是 chosen 也不是 car 的門。

2

對允許的門取 min,就是編號較小的那一扇。

參考解答
def monty_opens(chosen, car):
    return min(door for door in (1, 2, 3) if door != chosen and door != car)

當 chosen != car 時,只有一扇門可以開;兩者相等時有兩扇,min 選編號較小的。實際遊戲中蒙提此時會隨機挑選,筆記中的模擬會把這個隨機性加回去。

來源: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

填空

換門獲勝的機率

你選 1 號門,蒙提打開一扇後面是山羊的門,而你永遠選擇換門。你贏得汽車的機率是多少?請以分數作答。

你的答案

可以輸入整數、小數或分數,例如 1/2。 這題需要精確值。

提示
1

換門正好在你第一次選錯時會贏。

2

第一次選錯的機率是 2/32/3。

參考解答

2/32/3。如果第一次就選中汽車(機率 1/31/3),換門就會輸。如果第一次選到山羊(機率 2/32/3),蒙提只能打開另一扇山羊門,所以你換過去的那扇門後面一定是汽車。筆記中的模擬得到 0.66900.6690。

來源: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

Python

依證據更新機率

完成 bayes_update(prior, p_evidence_if_a, p_evidence_if_not_a)。已知 P(A)P(A)、P(E∣A)P(E\mid A) 與 P(E∣Ac)P(E\mid A^c),請用貝氏定理搭配全機率公式傳回 P(A∣E)P(A\mid E)。測試傳入的是 Fraction,所以答案是精確值。假設 P(E)>0P(E)>0。

你的答案

Python 函式練習。Tab 會移動焦點;選取程式行後,可用按鈕調整縮排。

公開測試

1. Monday: at least one girl

>>> bayes_update(Fraction(1, 4), 1, Fraction(2, 3))
Fraction(1, 3)

2. Tuesday: the elder is a girl

>>> bayes_update(Fraction(1, 3), 1, Fraction(1, 2))
Fraction(1, 2)

3. Evidence that rules out not-A

>>> bayes_update(Fraction(1, 100), 1, 0)
Fraction(1, 1)

4. Evidence that says nothing

>>> bayes_update(Fraction(1, 5), Fraction(1, 2), Fraction(1, 2))
Fraction(1, 5)
提示
1

分子是 P(E∣A) P(A)P(E\mid A)\,P(A)。

2

分母是在分子之外再加上 P(E∣Ac) (1−P(A))P(E\mid A^c)\,(1-P(A))。

參考解答
def bayes_update(prior, p_evidence_if_a, p_evidence_if_not_a):
    numerator = p_evidence_if_a * prior
    return numerator / (numerator + p_evidence_if_not_a * (1 - prior))

結果仍然是 AA 的機率,所以可以直接當成下一次的先驗再傳進去,這就是依序更新。在 AA 與非 AA 之下同樣可能出現的證據,不會改變先驗。

來源: Adapted from Blitzstein & Hwang, Introduction to Probability, Chapter 2 and §2.10 (R), rewritten in Python · Original exercise; the book's R examples are paraphrased, not copied

閱讀 Markdown 版本 ↗一起閱讀: 用 Python 看條件機率:兩個小孩、蒙提霍爾問題,以及依證據更新