<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 八、隨機性 > 原文:[Randomness](https://github.com/data-8/textbook/tree/gh-pages/chapters/08) > 譯者:[飛龍](https://github.com/wizardforcel) > 協議:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) > 自豪地采用[谷歌翻譯](https://translate.google.cn/) 在前面的章節中,我們開發了深入描述數據所需的技能。 數據科學家也必須能夠理解隨機性。 例如,他們必須能夠隨機將個體分配到實驗組和對照組,然后試圖說明,觀察到的兩組結果之間的差異是否僅僅是由于隨機分配,或真正由于實驗所致。 在這一章中,我們開始分析隨機性。 首先,我們將使用 Python 進行隨機選擇。 在`numpy`中有一個叫做`random`的子模塊,它包含許多涉及隨機選擇的函數。 其中一個函數稱為`choice`。 它從一個數組中隨機選取一個項目,選擇任何項目都是等可能的。 函數調用是`np.random.choice(array_name)`,其中`array_name`是要從中進行選擇的數組的名稱。 因此,下面的代碼以 50% 的幾率求值為`treatment`,50% 的機率為`control`。 ```py two_groups = make_array('treatment', 'control') np.random.choice(two_groups) 'treatment' ``` 上面的代碼和我們迄今運行的所有其他代碼之間的巨大差異在于,上面的代碼并不總是返回相同的值。 它可以返回`treatment`或`control`,我們不會提前知道會選擇哪一個。 我們可以通過提供第二個參數來重復這個過程,它是重復這個過程的次數。 ```py np.random.choice(two_groups, 10) array(['treatment', 'control', 'treatment', 'control', 'control', 'treatment', 'treatment', 'control', 'control', 'control'], dtype='<U9') ``` 隨機事件的根本問題是它們是否發生。 例如: + 個體是否被分配到實驗組? + 賭徒是否會贏錢? + 一個民意調查是否做出了準確的預測? 一旦事件發生,你可以對所有這些問題回答“是”或“否”。 在編程中,通常通過將語句標記為`True`或`False`來執行此操作。 例如,如果個體被分配到實驗組,那么“個體被分配到實驗組”的陳述將是真的。 如果不是,那將是假的。 ## 布爾值和比較 在 Python 中,布爾值(以邏輯學家 George Boole 命名)表示真值,并只有兩個可能的值:`True`和`False`。 無論問題是否涉及隨機性,布爾值通常都由比較運算符產生。 Python 包含了各種比較值的運算符。 例如,`3`大于`1 + 1`。 ```py 3 > 1 + 1 True ``` `True`表示比較是有效的;Python 已經證實了`3`和`1 + 1`的關系的這個簡單事實。 下面列出了一整套通用的比較運算符。 | 比較 | 運算符 | True 示例 | False 示例 | | --- | --- | --- | --- | | 小于 | `<` | `2 < 3` | `2 < 2` | | 大于 | `>` | `3 > 2` | `3 > 3` | | 小于等于 | `<=` | `2 <= 2` | `3 <= 2` | | 大于等于 | `>=` | `3 >= 3` | `2 >= 3` | | 等于 | `==` | `3 == 3` | `3 == 2` | | 不等于 | `!=` | `3 != 2` | `2 != 2` | 注意比較中的兩個等號`==`用于確定相等性。 這是必要的,因為 Python 已經使用`=`來表示名稱的賦值,我們之前看到過。 它不能將相同的符號用于不同的目的。 因此,如果你想檢查`5`是否等于`10/2`,那么你必須小心:`5 = 10/`2返回一個錯誤信息,因為 Python 假設你正試圖將表達式`10/2`的值賦給一個名稱,它是數字`5`。相反,你必須使用`5 == 10/2`,其計算結果為`True`。 ```py 5 = 10/2 File "<ipython-input-4-5c7d3e808777>", line 1 5 = 10/2 ^ SyntaxError: can't assign to literal 5 == 10/2 True ``` 一個表達式可以包含多個比較,并且它們都必須滿足,為了整個表達式為真。 例如,我們可以用下面的表達式表示`1 + 1`在`1`和`3`之間。 ```py 1 < 1 + 1 < 3 True ``` 兩個數字的平均值總是在較小的數字和較大的數字之間。 我們用下面的數字`x`和`y`來表示這種關系。 你可以嘗試不同的`x`和`y`值來確認這種關系。 ```py x = 12 y = 5 min(x, y) <= (x+y)/2 <= max(x, y) True ``` ### 字符串比較 字符串也可以比較,他們的順序是字典序。 較短的字符串小于以較短的字符串開頭的較長的字符串。 ```py 'Dog' > 'Catastrophe' > 'Cat' ``` 我們回到隨機選擇。 回想一下由兩個元素組成的數組`two_groups`,`treatment`和`control`。 為了看一個隨機分配的個體是否去了實驗組,你可以使用比較: ```py np.random.choice(two_groups) == 'treatment' False ``` 和以前一樣,隨機選擇并不總是一樣的,所以比較的結果也不總是一樣的。 這取決于是選擇`treatment`還是`control`。 對于任何涉及隨機選擇的單元格,多次運行單元格來獲得結果的變化是一個好主意。 ## 比較數組和值 回想一下,我們可以對數組中的很多數字執行算術運算。 例如,`make_array(0, 5, 2)*2`等同于`make_array(0, 10, 4)`。 以類似的方式,如果我們比較一個數組和一個值,則數組的每個元素都與該值進行比較,并將比較結果求值為布爾值數組。 ```py tosses = make_array('Tails', 'Heads', 'Tails', 'Heads', 'Heads') tosses == 'Heads' array([False, True, False, True, True], dtype=bool) ``` `numpy`方法`count_nonzero`計算數組的非零(即`True`)元素的數量。 ```py np.count_nonzero(tosses == 'Heads') 3 ``` ## 條件語句 在許多情況下,行動和結果取決于所滿足的一組特定條件。例如,隨機對照試驗的個體如果被分配給實驗組,則接受實驗。賭徒如果贏了賭注就賺錢。 在本節中,我們將學習如何使用代碼來描述這種情況。條件語句是一個多行語句,它允許 Python 根據表達式的真值選擇不同的選項。雖然條件語句可以出現在任何地方,但它們通常出現在函數體內,以便根據參數值執行可變的行為。 條件語句總是以`if`開頭,這是一行,后面跟著一個縮進的主體。只有當`if`后面的表達式(稱為`if`表達式)求值為真時,才會執行主體。如果`if`表達式的計算結果為`False`,則跳過`if`的主體。 讓我們開始定義一個返回數字符號的函數。 ```py def sign(x): if x > 0: return 'Positive' sign(3) 'Positive' ``` 如果輸入是正數,則此函數返回正確的符號。 但是,如果輸入不是正數,那么`if`表達式的計算結果為`false`,所以`return`語句被跳過,函數調用沒有值(為`None`)。 ```py sign(-3) ``` 所以,讓我們改進我們的函數來返回負數,如果輸入是負數。 我們可以通過添加一個`elif`子句來實現,其中`elif`是 Python 的`else, if`的縮寫。 ```py def sign(x): if x > 0: return 'Positive' elif x < 0: return 'Negative' ``` 現在當輸入為`-3`時,`sign`返回正確答案。 ```py sign(-3) 'Negative' ``` 那么如果輸入是`0`呢?為了處理這個情況,我們可以添加`elif`子句: ```py def sign(x): if x > 0: return 'Positive' elif x < 0: return 'Negative' elif x == 0: return 'Neither positive nor negative' sign(0) 'Neither positive nor negative' ``` 與之等價,我們可以用`else`子句替換最后的`elif`子句,只有前面的所有比較都是`false`,才會執行它的正文。 也就是說,輸入值等于`0`的時候。 ```py def sign(x): if x > 0: return 'Positive' elif x < 0: return 'Negative' else: return 'Neither positive nor negative' sign(0) 'Neither positive nor negative' ``` ### 一般形式 條件語句也可以有多個具有多個主體的子句,只有其中一個主體可以被執行。 多子句的條件語句的一般格式如下所示。 ```py if <if expression>: <if body> elif <elif expression 0>: <elif body 0> elif <elif expression 1>: <elif body 1> ... else: <else body> ``` 總是只有一個`if`子句,但是可以有任意數量的`elif`子句。 Python 將依次求解頭部的`if`和`elif`表達式,直到找到一個真值,然后執行相應的主體。 `else`子句是可選的。 當提供`else`頭部時,只有在前面的子句的頭部表達式都不為真時才執行`else`頭部。 `else`子句必須總是在最后(或根本沒有)。 ### 示例:"另一個" 現在我們將使用條件語句來定義一個看似相當虛假和對立的函數,但是在本章后面的章節中會變得方便。 它需要一個數組,包含兩個元素(例如,`red`和`blue`),以及另一個用于比較的元素。 如果該元素為`red`,則該函數返回`blue`。 如果元素是(例如)`blue`,則函數返回`red`。 這就是為什么我們要將函數稱為`other_one`。 ```py def other_one(x, a_b): """Compare x with the two elements of a_b; if it is equal to one of them, return the other one; if it is not equal to either of them, return an error message. """ if x == a_b.item(0): return a_b.item(1) elif x == a_b.item(1): return a_b.item(0) else: return 'The input is not valid.' colors = make_array('red', 'blue') other_one('red', colors) 'blue' other_one('blue', colors) 'red' other_one('potato', colors) 'The input is not valid.' ``` ## 迭代 編程中經常出現這樣的情況,特別是在處理隨機性時,我們希望多次重復一個過程。 例如,要檢查`np.random.choice`是否實際上是隨機選取的,我們可能需要多次運行下面的單元格,以查看`Heads`是否以大約 50% 的幾率出現。 ```py np.random.choice(make_array('Heads', 'Tails')) 'Heads' ``` 我們可能希望重新運行代碼,帶有稍微不同的輸入或其他稍微不同的行為。 我們可以多次復制粘貼代碼,但是這很枯燥,容易出現拼寫錯誤,如果我們想要這樣做一千次或一百萬次,忘記它吧。 更自動化的解決方案是使用`for`語句遍歷序列的內容。 這被稱為迭代。 `for`語句以單詞`for`開頭,后面跟著一個名字,我們要把這個序列中的每個項目賦給它,后面跟著單詞`in`,最后以一個表達式結束,它求值為一個序列。 對于序列中的每個項目,`for`語句的縮進主體執行一次。 ```py for i in np.arange(3): print(i) 0 1 2 ``` 想象一下,沒有`for`語句的情況下,完全實現`for`語句功能的代碼,這樣很有幫助。 (這被稱為循環展開。)`for`語句簡單地復制了內部的代碼,但是在每次迭代之前,它從給定的序列中將我們選擇的名稱賦為一個新的值。 例如,以下是上面循環的展開版本: ```py i = np.arange(3).item(0) print(i) i = np.arange(3).item(1) print(i) i = np.arange(3).item(2) print(i) 0 1 2 ``` > 譯者注:實際的實現方式不是這樣,但是效果一樣。這里不做深究。 請注意,我的名字是任意的,就像我們用`=`賦值的名字一樣。 在這里我們用一個更為現實的方式使用`for`語句:我們從數組中打印`5`個隨機選項。 ```py coin = make_array('Heads', 'Tails') for i in np.arange(5): print(np.random.choice(make_array('Heads', 'Tails'))) Heads Heads Tails Heads Heads ``` 在這種情況下,我們只執行了幾次完全相同的(隨機)操作,所以我們`for`語句中的代碼實際上并不涉及到`i`。 ### 擴展數組 雖然上面的`for`語句確實模擬了五次硬幣投擲的結果,但結果只是簡單地打印出來,并不是我們可以用來計算的形式。 因此,`for`語句的典型用法是創建一個結果數組,每次都擴展它。 `numpy`中的`append`方法可以幫助我們實現它。 調用`np.append(array_name,value)`將求出一個新的數組,它是由`value`擴展的`array_name`。在使用`append`時請記住,數組的所有條目必須具有相同的類型。 ```py pets = make_array('Cat', 'Dog') np.append(pets, 'Another Pet') array(['Cat', 'Dog', 'Another Pet'], dtype='<U11') ``` 這會使`pets`數組保持不變。 ```py pets array(['Cat', 'Dog'], dtype='<U3') ``` 但是在擴展數組的時候,通常使用`for`循環來修改它很方便。 這通過將擴展后的數組賦給原始數組的相同名稱來實現。 ```py pets = np.append(pets, 'Another Pet') pets array(['Cat', 'Dog', 'Another Pet'], dtype='<U11') ``` ### 示例:計算正面的數量 現在我們可以模擬一個硬幣的五次投擲,并把結果放入一個數組中。 我們將從創建一個空數組開始,然后附加每次投擲的結果。 ```py coin = make_array('Heads', 'Tails') tosses = make_array() for i in np.arange(5): tosses = np.append(tosses, np.random.choice(coin)) tosses array(['Tails', 'Heads', 'Tails', 'Heads', 'Tails'], dtype='<U32') ``` 讓我們將`for`語句展開,重寫單元格。 ```py coin = make_array('Heads', 'Tails') tosses = make_array() i = np.arange(5).item(0) tosses = np.append(tosses, np.random.choice(coin)) i = np.arange(5).item(1) tosses = np.append(tosses, np.random.choice(coin)) i = np.arange(5).item(2) tosses = np.append(tosses, np.random.choice(coin)) i = np.arange(5).item(3) tosses = np.append(tosses, np.random.choice(coin)) i = np.arange(5).item(4) tosses = np.append(tosses, np.random.choice(coin)) tosses array(['Heads', 'Heads', 'Tails', 'Tails', 'Heads'], dtype='<U32') ``` 通過將結果捕獲到數組中,我們自己有能力使用數組方法進行計算。 例如,我們可以使用`np.count_nonzero`來計算五次投擲中的正面數量。 ```py np.count_nonzero(tosses == 'Heads') 2 ``` 迭代是一個強大的技術。 例如,通過為 1000 次投擲運行完全相同的代碼,而不是`5`次,我們可以計算`1000`次投擲的正面數量。 ```py tosses = make_array() for i in np.arange(1000): tosses = np.append(tosses, np.random.choice(coin)) np.count_nonzero(tosses == 'Heads') 481 ``` ## 示例:100 次投擲中的正面數量 預測 100 次硬幣投擲中有 50 個正面是很自然的,或多或少。 但多少是“或多或少”呢? 獲得正好 50 個正面的幾率是多少? 像數據科學這樣的問題,不僅因為它們涉及隨機性的有趣方面,而且因為它們可以用于分析試驗,其中實驗和控制組的分配由硬幣的投擲決定。 在這個例子中,我們將模擬以下實驗的 10,000 次重復: + 擲硬幣 100 次,記錄正面數量。 我們的結果的直方圖會讓我們了解有多少個正面。 作為一個預熱,請注意,`np.random.choice`接受可選的第二個參數來指定選擇的數量。 默認情況下,選擇使用替換來進行。 這里是一個硬幣 10 次投擲的模擬: ```py np.random.choice(coin, 10) array(['Tails', 'Heads', 'Heads', 'Tails', 'Tails', 'Heads', 'Tails', 'Tails', 'Heads', 'Tails'], dtype='<U5') ``` 現在我們來研究 100 次投擲。 我們將首先創建一個名為`heads`的空數組。 然后,在每個一萬次重復中,我們會拋硬幣 100 次,計算正面的數量,并將其附加到`heads`上。 ```py N = 10000 heads = make_array() for i in np.arange(N): tosses = np.random.choice(coin, 100) heads = np.append(heads, np.count_nonzero(tosses == 'Heads')) heads array([ 46., 64., 59., ..., 56., 54., 56.]) ``` 讓我們將結果收集到表格中,并繪制直方圖: ```py results = Table().with_columns( 'Repetition', np.arange(1, N+1), 'Number of Heads', heads ) results ``` | Repetition | Number of Heads | | --- | --- | | 1 | 46 | | 2 | 64 | | 3 | 59 | | 4 | 57 | | 5 | 54 | | 6 | 47 | | 7 | 45 | | 8 | 50 | | 9 | 44 | | 10 | 57 | (省略了 9990 行) 這里是數據的直方圖,桶的寬度為 1,中心為每個正面數量的值。 ```py results.select('Number of Heads').hist(bins=np.arange(30.5, 69.6, 1)) ``` ![](https://box.kancloud.cn/97c567efd66a20c3b59ac8b48fb911e9_434x298.png) 毫不奇怪,直方圖看起來大約關于 50 個正面左右對稱。 50 處的條形的高度大約是每單位 8%。 由于每個條形的寬度都是 1 個單位,這就是說,8% 的重復正好產生了 50 個正面。 這不是一個很大的百分比,但是與其他數量的正面相比,這是最大的。 直方圖還顯示,在幾乎所有的重復中,100 次投擲的正面數量在 35 到 65 之間。事實上,大部分的重復產生 45 到 55 個正面數量。 理論上,正面數量可能在 0 到 100 之間,但模擬顯示可能值的范圍要小得多。 這是一個更普遍現象的例子,關于擲硬幣中的變化,我們將在后面看到。 ## Monty Hall 問題 多年來這個問題已經使許多人感到困惑,包括數學家在內。 讓我們看看我們是否可以解決。 這個設定來源于一個名為“讓我們做個交易”(Let's Make a Deal)的電視游戲節目。Monty Hall 在二十世紀六十年代主持了這個節目,從此產生了一些副產品。 這個節目令人興奮的一部分是,雖然參賽者有機會贏得大獎,但他們可能最終會選擇不那么理想的“zonks”。 這就是現在所謂的 Monty Hall 問題的基礎。 這個設定是一個游戲節目,參賽者面對三個閉著的門。 在其中一扇門的后面是一輛奇特的汽車,另外兩扇門后面有一只山羊。 參賽者不知道汽車的位置,必須按照以下規則進行嘗試。 + 參賽者進行初步選擇,但不打開那個門。 + 其他兩個門中至少有一個門的后面必須有一只山羊。Monty 打開這些門之一來展示山羊,[維基百科](https://en.wikipedia.org/wiki/Monty_Hall_problem)中顯示了他所有的榮耀。 ![](https://box.kancloud.cn/c85a32654bcedb6101ed61369376f3d8_220x122.png) + 還剩下兩個門,其中一個是參賽者的原始選擇。 其中一扇門后面有車,另一扇有一只山羊。 參賽者現在可以選擇打開兩扇門中的哪一扇。 參賽者需要作出決定。 如果她想要這輛車,她應該選擇打開哪扇門? 她應該堅持最初的選擇,還是轉向另一個門? 這是 Monty Hall 問題。 ### 解法 在涉及幾率的任何問題中,重要的隨機性的假設。 假設有三分之一的幾率,參賽者的最初選擇是后面有車的門,這是合理的。 在這個假設下,解決這個問題的方法非常簡單,盡管簡單的解決方案并不能說服每個人。 無論如何就是這樣。 + 汽車在原來選擇的門后面的幾率是 1/3。 + 汽車在原來選擇的門后面或者剩余的門后面。 它不能在其他地方。 + 因此,汽車在剩余的門后的幾率是 2/3。 + 因此,選手應該更改選擇。 + 就是這樣,故事結束了。 不相信? 那么讓我們模擬游戲,看看結果如何。 ### 模擬 我們開始建立兩個實用的數組,`doors`和`goats`,這會讓我們區分三個門和兩只山羊。 ```py doors = make_array('Car', 'Goat 1', 'Goat 2') goats = make_array('Goat 1', 'Goat 2') ``` 現在我們定義一個函數`monty_hall`來模擬游戲,并按照這個順序返回含有三個字符串的數組: + 參賽選手的原始選擇的什么 + Monty 排除了什么 + 剩下的門是什么 如果選手的原始選擇是帶山羊的門,蒙蒂必須扔掉另一只山羊,剩下的就是這輛車。 如果最初的選擇是帶車的門,蒙蒂必須扔掉兩只山羊中的一只,剩下的就是另一只羊。 因此很顯然,在前一節中定義的函數將是有用的。 它需要一個字符串和一個兩個元素的數組; 如果字符串等于其中一個元素,則返回另一個元素。 ```py def other_one(x, a_b): if x == a_b.item(0): return a_b.item(1) elif x == a_b.item(1): return a_b.item(0) else: return 'Input Not Valid' ``` 如果選手的原始選擇是山羊,游戲的結果是這二者之一: ```py original = 'Goat 1' make_array(original, other_one(original, goats), 'Car') array(['Goat 1', 'Goat 2', 'Car'], dtype='<U6') original = 'Goat 2' make_array(original, other_one(original, goats), 'Car') array(['Goat 2', 'Goat 1', 'Car'], dtype='<U6') ``` 現在我們可以把所有這些代碼放到`monty_hall`函數中,來模擬一次游戲的結果。 該函數不帶任何參數。 參賽者的原始選擇將是三門之中隨機選擇的門。 為了檢查原始選擇是否是山羊,我們首先寫一個名為`is_goat`的小函數: ```py def is_goat(door_name): """ Check whether the name of a door (a string) is a Goat. Examples: ========= >>> is_goat('Goat 1') True >>> is_goat('Goat 2') True >>> is_goat('Car') False """ if door_name == "Goat 1": return True elif door_name == "Goat 2": return True else: return False def monty_hall(): """ Play the Monty Hall game once and return an array of three strings: original choice, what Monty throws out, what remains """ original = np.random.choice(doors) if is_goat(original): return make_array(original, other_one(original, goats), 'Car') else: throw_out = np.random.choice(goats) return make_array(original, throw_out, other_one(throw_out, goats)) ``` 讓我們玩幾次這個游戲。這里是一個結果。你應該運行幾次單元格來觀察結果如何變化。 ```py monty_hall() array(['Car', 'Goat 2', 'Goat 1'], dtype='<U6') ``` 為了衡量不同結果發生的頻率,我們必須玩多次游戲并收集結果。 為此,我們將使用`for`循環。 我們將首先定義三個空數組,每個數組對應原始選擇,Monty 排除了什么,剩下的是什么。然后我們將玩這個游戲 N 次并收集結果。我們已經將 N 設為 10,000,但是你可以改變它。 ```py # Number of times we'll play the game N = 10000 original = make_array() # original choice throw_out = make_array() # what Monty throws out remains = make_array() # what remains for i in np.arange(N): result = monty_hall() # the result of one game # Collect the results in the appropriate arrays original = np.append(original, result.item(0)) throw_out = np.append(throw_out, result.item(1)) remains = np.append(remains, result.item(2)) # The for-loop is done! Now put all the arrays together in a table. results = Table().with_columns( 'Original Door Choice', original, 'Monty Throws Out', throw_out, 'Remaining Door', remains ) results ``` | Original Door Choice | Monty Throws Out | Remaining Door | | --- | --- | --- | | Car | Goat 1 | Goat 2 | | Goat 1 | Goat 2 | Car | | Goat 2 | Goat 1 | Car | | Car | Goat 2 | Goat 1 | | Car | Goat 2 | Goat 1 | | Goat 1 | Goat 2 | Car | | Goat 1 | Goat 2 | Car | | Goat 1 | Goat 2 | Car | | Goat 2 | Goat 1 | Car | | Goat 1 | Goat 2 | Car | (省略了 9990 行) 為了看看選手是否應該堅持原來的選擇或更改,讓我們看看她的兩個選項后面的車的頻率。 ```py results.group('Original Door Choice') ``` | Original Door Choice | count | | --- | --- | | Car | 3312 | | Goat 1 | 3382 | | Goat 2 | 3306 | ```py results.group('Remaining Door') ``` | Remaining Door | count | | --- | --- | | Car | 6688 | | Goat 1 | 1640 | | Goat 2 | 1672 | 我們的解決方案說明了,這輛車有三分之二的幾率在剩下的門后面,這是相當不錯的近似值。 如果參賽者更改了她的選擇,她有兩倍的可能性會得到車。 為了使結果可視化,我們可以將上面的兩個表格連接在一起并繪制疊加的條形圖。 ```py results_o = results.group('Original Door Choice') results_r = results.group('Remaining Door') joined = results_o.join('Original Door Choice', results_r, 'Remaining Door') combined = joined.relabeled(0, 'Item').relabeled(1, 'Original Door').relabeled(2, 'Remaining Door') combined ``` | Item | Original Door | Remaining Door | | --- | --- | --- | | Car | 3312 | 6688 | | Goat 1 | 3382 | 1640 | | Goat 2 | 3306 | 1672 | ```py combined.barh(0) ``` ![](https://box.kancloud.cn/28315f74105456692cedc24737a0046e_566x231.png) 注意三條藍色條形幾乎相等 - 原始選擇有同等可能是三個可用條目中的任何一條。 但是,汽車對應的金色條形是藍色條形的兩倍。 模擬證實了,如果參賽者改變選擇,她有兩倍的可能性獲勝。 ## 發現概率 幾個世紀以來,對于什么是概率存在哲學爭論。有些人認為概率是相對頻率;其他人認為他們是長期的相對頻率較長;還有一些人認為概率是個人不確定性程度的主觀測量。 在這個課程中,大多數概率將是相對頻率,盡管許多人會有主觀的解釋。無論如何,在不同的解釋中,概率計算和組合的方式是一致的。 按照慣例,概率是介于 0 和 1 之間的數字,或者 0% 和 100% 之間。不可能的事件概率為 0。確定的事件概率為 1。 數學是準確發現概率的主要工具,盡管計算機也可用于此目的。模擬可以提供出色的近似,具有很高的概率。在本節中,我們將以非正式方式制定一些簡單的規則來管理概率的計算。在隨后的章節中,我們將回到模擬來近似復雜事件的概率。 我們將使用標準符號 ![](https://img.kancloud.cn/7e/0b/7e0b155539fe531f8fd6e709a1beba62_68x18.gif) 來表示“事件”發生的概率,我們將交替使用“幾率”和“概率”兩個字。 ## 事件不會發生的時候 如果事件發生的概率是 40%,不發生的幾率就是 60%。這個自然的計算可以這樣秒速: ![](https://img.kancloud.cn/b2/da/b2da24862117f26d324dc1e04d25c3d9_456x18.gif) ## 所有結果等可能的時候 如果你投擲一個普通的骰子,一個自然的假設是,所有六個面都是等可能的。 那么一個面出現的概率可以很容易地計算出來。 例如,骰子顯示偶數的幾率是: ![](https://img.kancloud.cn/2b/cb/2bcb356645a61c458c0d4889af20c14c_379x44.gif) 與之相似: ![](https://img.kancloud.cn/bb/b2/bbb2141eb66d78e06d83a20a12bbfaf3_436x44.gif) 通常: ![](https://img.kancloud.cn/50/4f/504fb2787243037e79b2962aa69e8c1a_535x44.gif) 前提是所有的結果都是等可能的。 并非所有的隨機現象都像骰子一樣簡單。 下面的兩個主要的概率規則甚至允許數學家在復雜的情況下找到概率。 ## 兩個事件必須同時發生時 假設你有一個盒子,包含三張紙條:一張紅色,一張藍色和一張綠色。 假設你隨機抽兩張紙條而不放回;也就是你把三張紙條打亂,抽一張,打亂其余兩張,再從這兩張中抽出一張。 你先得到綠色紙條,然后是紅色紙條的幾率是多少? 有六種可能的顏色對:RB,BR,RG,GR,BG,GB(我們已經縮寫了每種顏色的名字,就是它的第一個字母)。 所有這些都是抽樣方案是等可能的,只有其中一個(GR)使事件發生。所以: ![](https://img.kancloud.cn/ad/9b/ad9bcbcc2f9553dbc78fdb3f8fe0cbcd_516x44.gif) 但是還有另外一種方法來得到答案,可以用兩個階段來思考這個事件。 必須首先抽取綠色紙條。幾率是 1/3,也就是說在所有實驗的大約 1/3 的重復中,先抽取了綠色紙條,但事件還沒完成。在這 1/3 的重復中,必須再次抽取紅色紙條。這個發生在大約 1/2 的重復中,所以: ![](https://img.kancloud.cn/29/61/2961e51e0c03dc03611a0dfa71c04480_318x37.gif) 這個計算通常按照事件順序,像這樣: ![](https://img.kancloud.cn/70/3c/703cb2c451153c5beb4f96ac929c3007_325x37.gif) 因數 1/2 叫做“假設第一次出現了綠色紙條,第二次出現紅色紙條的條件幾率”。 通常,我們擁有乘法規則: ![](https://img.kancloud.cn/29/63/296310b84e301710029eacc401941225_922x18.gif) 兩個事件同時發生的概率,等于第一個事件發生的概率,乘上第一個事件發生的情況下第二個事件發生的概率。 因此,這里有兩個條件 - 一個事件必須發生,另一個也是 - 幾率是分數的分數,這比兩個因數的任何一個都要小。 滿足的條件越多,滿足的可能性就越小。 ## 事件以兩種不同的方式發生 相反,假設我們希望兩張紙條中的一張是綠色的,另一張是紅色的。 此事件不指定顏色必須出現的順序。所以他們可以以任何順序出現。 解決這樣的問題的一個好方法就是對事件進行劃分,以便它正好能夠以幾種不同的方式之一發生。 “一綠一紅”的自然劃分是:GR,RG。 根據上面的計算,GR 和 RG 每個的幾率都是 1/6。所以你可以通過把它們相加來計算一綠一紅的概率。 ![](https://img.kancloud.cn/d7/8c/d78c1a51ad508838047e9c773f84f656_499x37.gif) 通常,我們擁有加法規則: ![](https://img.kancloud.cn/5a/2a/5a2ab6cbcd11da5b474f4843850098d3_648x18.gif) 事件發生的概率,等于以第一種方式發生的概率,加上以第二種方式發生的概率。 只要事件正好以兩種方式之一發生。 因此,當事件以兩種不同的方式之一發生時,發生的幾率是一些幾率的總和,因此比任何一種方式的幾率都大。 乘法規則可以自然擴展到兩個以上的事件,我們將在下面看到。 所以這個加法規則也有自然的擴展,事件可以以幾種不同的方式之一發生。 我們將所有這些規則組合成示例,并用示例來結束該部分。 ### 至少有一個成功 數據科學家經常使用來自總體的隨機樣本。 有時候問題就來了,就是總體中的一個特定個體選進樣本的可能性。為了找出幾率,這個個體被稱為“成功”,問題是要找到樣本包含成功的幾率。 要看看如何計算這樣的幾率,我們從一個更簡單的設定開始:投擲硬幣兩次。 如果你投擲硬幣兩次,有四個等可能的結果:HH,HT,TH 和 TT。 我們把正面縮寫為 H ,反面縮寫為 T。至少有一個正面的幾率是 3/4。 得出這個答案的另一種方法是,弄清楚如果你不能得到至少一個正面,會發生什么事情:這兩次投擲都必須是反面。所以: ![](https://img.kancloud.cn/1d/66/1d6698250f6013a11a06ce3d1660e02f_564x38.gif) 要注意根據乘法規則: ![](https://img.kancloud.cn/a9/ba/a9ba87268935d8c4e2dc35913b4602f9_311x49.gif) 這兩個觀察使我們能夠在任何給定數量的投擲中找到至少一個正面的幾率。 例如: ![](https://img.kancloud.cn/46/df/46df233388fd72c0039cd4b56d04722c_566x49.gif) 而現在我們有能力找到在骰子的投擲中,六點至少出現一次的幾率: ![](https://img.kancloud.cn/90/92/90925e1a70e8e859aa822e93239bbaa3_539x38.gif) ![](https://img.kancloud.cn/38/d9/38d9386782c1f2ef45581d00d0679e77_590x68.gif) 下表展示了,這些概率隨著投擲數量從 1 增加到 50 而增加。 ```py rolls = np.arange(1, 51, 1) results = Table().with_columns( 'Rolls', rolls, 'Chance of at least one 6', 1 - (5/6)**rolls ) results ``` | Rolls | Chance of at least one 6 | | --- | --- | | 1 | 0.166667 | | 2 | 0.305556 | | 3 | 0.421296 | | 4 | 0.517747 | | 5 | 0.598122 | | 6 | 0.665102 | | 7 | 0.720918 | | 8 | 0.767432 | | 9 | 0.806193 | | 10 | 0.838494 | (省略了 40 行) 隨著投擲數量的增加,六點至少出現一次的幾率迅速增加。 ```py results.scatter('Rolls') ``` ![](https://box.kancloud.cn/880a4c98a8b83fb6ce5bd115545e46af_518x461.png) 在 50 次投擲中,你幾乎肯定能得到至少一個六。 ```py results.where('Rolls', are.equal_to(50)) ``` | Rolls | Chance of at least one 6 | | --- | --- | | 50 | 0.99989 | 像這樣的計算可以用來找到,隨機樣本中選擇特定個體的幾率。 準確的計算將取決于抽樣方案。 但是我們上面的觀察的通常可以被推廣:增加隨機樣本的大小增加了選擇個體的幾率。 ## 抽樣 現在我們來仔細看看抽樣,例子基于`top_movies.csv`數據集。 ```py top1 = Table.read_table('top_movies.csv') top2 = top1.with_column('Row Index', np.arange(top1.num_rows)) top = top2.move_to_start('Row Index') top.set_format(make_array(3, 4), NumberFormatter) ``` | Row Index | Title | Studio | Gross | Gross (Adjusted) | Year | | --- | --- | --- | --- | --- | --- | | 0 | Star Wars: The Force Awakens | Buena Vista (Disney) | 906,723,418 | 906,723,400 | 2015 | | 1 | Avatar | Fox | 760,507,625 | 846,120,800 | 2009 | | 2 | Titanic | Paramount | 658,672,302 | 1,178,627,900 | 1997 | | 3 | Jurassic World | Universal | 652,270,625 | 687,728,000 | 2015 | | 4 | Marvel's The Avengers | Buena Vista (Disney) | 623,357,910 | 668,866,600 | 2012 | | 5 | The Dark Knight | Warner Bros. | 534,858,444 | 647,761,600 | 2008 | | 6 | Star Wars: Episode I - The Phantom Menace | Fox | 474,544,677 | 785,715,000 | 1999 | | 7 | Star Wars | Fox | 460,998,007 | 1,549,640,500 | 1977 | | 8 | Avengers: Age of Ultron | Buena Vista (Disney) | 459,005,868 | 465,684,200 | 2015 | | 9 | The Dark Knight Rises | Warner Bros. | 448,139,099 | 500,961,700 | 2012 | (省略了 190 行) ### 對表格的行進行抽樣 數據表的每一行代表一個個體;最重要的是,每個個體都是一部電影。 因此可以通過表格的行的抽樣來實現對個體的抽樣。 一行的內容是在同一個個體上測量的不同變量的值。 因此,行的內容的抽樣形成了每個變量值的樣本。 ## 確定性樣本 當你只是簡單地指定,你要選擇的集合中的哪些元素時,就不會涉及任何幾率,可以創建確定性樣本。 你已經做了很多次了,例如使用`take`: ```py top.take(make_array(3, 18, 100)) ``` | Row Index | Title | Studio | Gross | Gross (Adjusted) | Year | | --- | --- | --- | --- | --- | --- | | 3 | Jurassic World | Universal | 652,270,625 | 687,728,000 | 2015 | | 18 | Spider-Man | Sony | 403,706,375 | 604,517,300 | 2002 | | 100 | Gone with the Wind | MGM | 198,676,459 | 1,757,788,200 | 1939 | 你也使用了`where`: ```py top.where('Title', are.containing('Harry Potter')) ``` | Row Index | Title | Studio | Gross | Gross (Adjusted) | Year | | --- | --- | --- | --- | --- | --- | | 22 | Harry Potter and the Deathly Hallows Part 2 | Warner Bros. | 381,011,219 | 417,512,200 | 2011 | | 43 | Harry Potter and the Sorcerer's Stone | Warner Bros. | 317,575,550 | 486,442,900 | 2001 | | 54 | Harry Potter and the Half-Blood Prince | Warner Bros. | 301,959,197 | 352,098,800 | 2009 | | 59 | Harry Potter and the Order of the Phoenix | Warner Bros. | 292,004,738 | 369,250,200 | 2007 | | 62 | Harry Potter and the Goblet of Fire | Warner Bros. | 290,013,036 | 393,024,800 | 2005 | | 69 | Harry Potter and the Chamber of Secrets | Warner Bros. | 261,988,482 | 390,768,100 | 2002 | | 76 | Harry Potter and the Prisoner of Azkaban | Warner Bros. | 249,541,069 | 349,598,600 | 2004 | 雖然這些是電影的樣本,它們并不涉及幾率。 ### 概率抽樣 很多數據科學都根據隨機樣本中的數據得到結論。 根據隨機樣本的正確解釋分析,需要數據科學家準確地檢查隨機樣本。 總體是從中抽取樣本的所有元素的集合。 概率樣本是一種樣本,在抽取樣本之前,可以計算出的元素的任何子集將進入樣本的幾率。 在概率樣本中,所有的元素不需要有相同的選中幾率。 ### 隨機抽樣方案 例如,假設根據以下方案,從三個個體 A,B 和 C 組成的總體中選擇兩個個體: + 個體 A 選中概率為 1。 + 個體 B 或 C 根據擲硬幣來選擇:如果硬幣為正面,選擇 B,否則,選擇 C。 這是一個大小為 2 的概率樣本。下面是所有非空子集的選中幾率: ```py A: 1 B: 1/2 C: 1/2 AB: 1/2 AC: 1/2 BC: 0 ABC: 0 ``` 個體 A 比 B 或 C 有更高的選中幾率;的確,個體 A 肯定會被選中。由于這些差異是已知的和量化的,所以在處理樣本時可以考慮這些差異。 ### 系統樣本 想象一下,總體的所有元素都列出在序列中。 抽樣的一種方法是,先從列表中選擇一個隨機的位置,然后是它后面的等間隔的位置。樣本由這些位置上的元素組成。這樣的樣本被稱為系統樣本。 在這里,我們將選擇頂部一些行的系統樣本。我們最開始隨機選取前 10 行中的一行,然后我們將選取它后面的每個第 10 行。 ```py """Choose a random start among rows 0 through 9; then take every 10th row.""" start = np.random.choice(np.arange(10)) top.take(np.arange(start, top.num_rows, 10)) ``` | Row Index | Title | Studio | Gross | Gross (Adjusted) | Year | | --- | --- | --- | --- | --- | --- | | 6 | Star Wars: Episode I - The Phantom Menace | Fox | 474,544,677 | 785,715,000 | 1999 | | 16 | Iron Man 3 | Buena Vista (Disney) | 409,013,994 | 424,632,700 | 2013 | | 26 | Spider-Man 2 | Sony | 373,585,825 | 523,381,100 | 2004 | | 36 | Minions | Universal | 336,045,770 | 354,213,900 | 2015 | | 46 | Iron Man 2 | Paramount | 312,433,331 | 341,908,200 | 2010 | | 56 | The Twilight Saga: New Moon | Sum. | 296,623,634 | 338,517,700 | 2009 | | 66 | Meet the Fockers | Universal | 279,261,160 | 384,305,300 | 2004 | | 76 | Harry Potter and the Prisoner of Azkaban | Warner Bros. | 249,541,069 | 349,598,600 | 2004 | | 86 | The Exorcist | Warner Bros. | 232,906,145 | 962,212,800 | 1973 | | 96 | Back to the Future | Universal | 210,609,762 | 513,740,700 | 1985 | (省略了 10 行) 運行單元個幾次,看看輸出如何變化。 這個系統樣本是一個概率樣本。 在這個方案中,所有的行都有機會被選中。 例如,當且僅當第 3 行被選中時,第 23 行才被選中,并且其幾率是 1/10。 但并不是所有的子集都有相同的選中幾率。 由于選中的行是等間隔的,大多數行的子集都沒有機會被選中。 唯一可能的子集是由所有間隔為 10 的行構成的子集。任何這些子集都以 1/10 的幾率被選中。 其他子集,如包含表格前 11 行的子集,選中幾率都是 0。 ### 放回或不放回的隨機抽樣 在這個課程中,我們將主要處理兩個最直接的抽樣方法。 首先是帶放回的隨機抽樣,它(如我們前面所見)是`np.random.choice`從數組中抽樣時的默認行為。 另一個稱為“簡單隨機樣本”,是隨機抽取的樣本,不帶放回。在下一個個體被抽中之前,抽中的個體不會放回總體。例如,當你發牌時,就會發生這種抽樣。 在下一章中,我們將使用模擬來研究帶放回和不放回的大樣本隨機抽取。 繪制隨機樣本需要謹慎和精確。這不是隨便的,即使這是“隨機”一詞的口語意義。如果你站在街頭,選取前十名經過的人作為樣本,你可能會認為你在隨機抽樣,因為你沒有選擇誰走過。但它不是一個隨機樣本 - 這是一個方便的例子。你沒有提前知道每個人進入樣本的概率,也許甚至你沒有具體指定誰在總體中。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看