2014-02-13 112 views
4

我一直在學習python編程edX這是一個非常好的課程,我至今可以完全推薦。剛剛看過一個關於Statistics的TED演講,我認爲這很棒,這是一種鍛鍊我在真實世界場景中獲得的Python技能的簡單方法。這個人舉了一個例子,說明不斷翻轉一枚硬幣的可能性,並尋找兩個反覆出現的序列,他解釋說,你會認爲他有相同的發生概率,他聲稱事實上沒有。簡單地說,他聲稱序列頭尾巴頭最有可能發生比頭尾尾巴在第一個序列的末尾,你已經有三分之一的重複序列再次在第二個序列的結尾你必須拋棄另一頭再次開始序列。這非常有意義,所以我着手試圖用我在這裏顯示的小型python程序來證明它。使用python分析擲硬幣統計

import random 

HTH = 0 
HTT = 0 
myList = [] 
i = 0 
numberOfTosses = 1000000 

while i < numberOfTosses: 
    myList.append(random.randint(0,1)) 
    i += 1 

for i in range (len(myList)): 

    if i+2 >= len(myList): 
     break 

    if myList[i] == 1 and myList[i+1] == 0 and myList[i+2] == 1: 
     HTH +=1 

    if myList[i] == 1 and myList[i+1] == 0 and myList[i+2] == 0: 
     HTT +=1 

print 'HTT :' ,numberOfTosses, HTT, numberOfTosses/HTT 
print 'HTH :' ,numberOfTosses, HTH, numberOfTosses/HTH 

因此,我已多次運行程序,改變最大迭代值高,但似乎無法證明自己的說法,平均的HTH順序應該發生埃維8次投擲和HTT序列每10個,因爲看起來我平均得到平衡的結果。所以我的問題是我在執行這個問題的時候出了什麼問題?

+2

我認爲那傢伙的主張是虛假的,除非他說你更有可能得到HTH少數的折磨。爲了從HTH中獲得更多的勝利,因爲他說,你必須得到比HTTH更多的HTHT。但是如果你應用他的同樣的邏輯,HTTH已經在序列的最後開始了,而你必須從HTHT開始重新開始。 –

+0

@MarkkuK。實際上,當你有HTHT的時候,你已經有了下一個HTHT的前兩個字母。對於HTTH,你只有第一個字母。 –

+0

@MattParker,的確如此,我正在應用這個人說的太狹隘。不過,HTHT vs HTTH的統計數據也大致相同,至少在這裏使用該方法。 –

回答

4

你的專家是正確的,你的,你說他說的代碼是正確的,但他實際上說了別的。他說,當你開始擲硬幣時,你應該預計HTT會首次出現在平均8次翻轉中,HTH首次平均翻轉10次。

如果您修訂程序來測試這一說法,這可能是這樣的:

import random 

HTH = 0 
HTT = 0 
numberOfTrials = 10000 

for t in xrange(numberOfTrials): 
    myList = [ random.randint(0,1), random.randint(0,1), random.randint(0,1) ] 
    flips = 3 
    HTHflips = HTTflips = 0 

    while HTHflips == 0 or HTTflips == 0: 
     if HTHflips == 0 and myList[flips-3:flips] == [1,0,1]: 
      HTHflips = flips 
     if HTTflips == 0 and myList[flips-3:flips] == [1,0,0]: 
      HTTflips = flips 
     myList.append(random.randint(0,1)) 
     flips += 1 

    HTH += HTHflips 
    HTT += HTTflips 


print 'HTT :', numberOfTrials, HTT, float(HTT)/numberOfTrials 
print 'HTH :', numberOfTrials, HTH, float(HTH)/numberOfTrials 

運行將確認的8次10投擲的預期值。

+0

就是這樣。我只是在視頻中再次觀看了該部分,現在可以看到我出錯的地方。這是我對實際問題的解釋。我應該做的是平均數直到序列出現,而不是平均投擲硬幣總數。謝謝。 – Hoppo

0
import random 

HTH = 0 
HTT = 0 
myList = [] 
numberOfTosses = 1000000 

myList.append(random.randint(0,1)) 
myList.append(random.randint(0,1)) 

for x in range (3, numberOfTosses + 3): 
    myList.append(random.randint(0,1)) 
    if myList[x-3:x] == [1,0,1]: 
     HTH += 1 
    elif myList[x-3:x] == [1,0,0]: 
     HTT += 1 

print (HTH, " ", HTT) 
+0

這給出了相同的結果嗎? – M4rtini

+1

我認爲它應該......兩次100萬的測試運行返回124917 HTH,124855 HTT。 HTH應該更頻繁地發生的原因是HTHTH = 2的可能性,而沒有這樣的五次翻轉的組合會產生兩個HTT結果。 – EducateMe

0

至於你的代碼,這在功能上等同:

import random 

HTH = 0 
HTT = 0 

numberOfTosses = 1000000 

myList = [random.randint(0,1) for x in range(numberOfTosses)] 

for i in range(len(myList)-2): 
    a,b,c= myList[i:i+3] 
    HTH += int(a==c==1 and b==0) 
    HTT += int(a==1 and b==c==0) 

print 'HTT :' ,numberOfTosses, HTT, numberOfTosses/float(HTT) 
print 'HTH :' ,numberOfTosses, HTH, numberOfTosses/float(HTH) 

至於爲什麼兩個序列出現相同的次數,我的直覺是,他們應該。你可能想問stats.stackexchange.com

+0

這就是他在談話中提出的觀點。他聲稱每個人都有相同的預感,但他們是不正確的,因此我爲什麼試圖證明它,似乎我們只是證明專家是正確的還是非常錯誤的! :0我會嘗試在stats.stackexchange.com。我沒有意識到這種事情有單獨的交換。以爲我會在這裏嘗試,因爲它是與我相關的python。 – Hoppo

+0

@Hoppo的確,如果你有一個與你的*代碼相關的問題,stackoverflow是最好的地方(對我來說這似乎很好)。請不要將您的代碼發佈到統計信息上,只要詢問序列是否應該發生相同的次數 – goncalopp

0

我認爲你的專家是錯誤的,或者你誤解了他在說什麼。我沒有看到你的代碼檢測HTH和HTT序列有什麼問題。

對於少量的卷,可以通過每個可能的結果,而不是使用隨機數。

對於3捲來說,很容易推測有8種可能的結果,其中恰恰有一種是HTH,另一種是HTT。

4卷有16個可能的結果。其中2人將以HTH開始,2人將以HTT開始;同樣2將以HTH結束,2將以HTT結束。

我修改了您的代碼以檢查所有組合並計算檢測到序列的次數。在我測試的所有情況下,這兩個數字是相等的。 http://ideone.com/YtixtV

from __future__ import division 
import random 

def every_combination(n): 
    bits = [2**i for i in range(n)] 
    for value in xrange(2**n): 
     yield [1 if value & bits[i] else 0 for i in range(n)] 

for n in range(3, 16): 
    HTH = 0 
    HTT = 0 
    numberOfTosses = 0 

    for myList in every_combination(n): 

     numberOfTosses += len(myList) 
     for i in range (len(myList) - 2): 

      if myList[i] == 1 and myList[i+1] == 0 and myList[i+2] == 1: 
       HTH +=1 

      if myList[i] == 1 and myList[i+1] == 0 and myList[i+2] == 0: 
       HTT +=1 

    print 'For number of rolls', n 
    print 'HTT :' ,numberOfTosses, HTT, numberOfTosses/HTT 
    print 'HTH :' ,numberOfTosses, HTH, numberOfTosses/HTH 
0

您的代碼確認存在的任一字符串的概率等於當從長序列選擇連續的3個樣品。

實際上,對於任何給定的鏈,三個樣本匹配的概率總是1/2^[鏈長] - 唯一的變量是長度,而不是內容。

的TED談論你所描述聽起來像Penney公司的遊戲的描述:http://en.wikipedia.org/wiki/Penney%27s_game 但這裏的一個關鍵區別是,彭尼的比賽描述任何一個序列首先發生的可能性(所以給定的玩家可以贏得) - 總總出現不 - 你的代碼找到了。 TED演講者也可能倒退第二個序列(HHT,而不是HTT)。)

以下代碼測試(並確認)彭尼遊戲中的統計異常。注意它在發現時會「中斷」或退出內部循環。

它輸出: HTH:1000000 332854 3 3.00432021247 HHT:1000000 667146 1 1.49892227488

import random 

HTH = 0 
HHT = 0 
myList = [] 
i = 0 

numberOfTests = 1000000 
maxTosses = 10000 

hthConditionMeant=0 
hhtConditionMeant=0 

while i < numberOfTests : 
    myList = [] 
    j = 0 
    while (j < maxTosses): 
     myList.append(random.randint(0,1)) 
     if myList[j-3:j] == [1,0,1]: 
       HTH += 1 
       break 
     elif myList[j-3:j] == [1,1,0]: 
       HHT += 1 
       break 
     j += 1 
    i += 1 


cyclesToSeeHTHprecise = numberOfTests/float(HTH) 
cyclesToSeeHHTprecise = numberOfTests/float(HHT) 

print 'HTH :' ,numberOfTests, HTH, numberOfTests/HTH, cyclesToSeeHTHprecise 
print 'HHT :' ,numberOfTests, HHT, numberOfTests/HHT, cyclesToSeeHHTprecise` 

`