使用python分析抛硬币统计数据

时间:2014-02-13 17:44:09

标签: python python-2.7 statistics

我一直在edX学习python编程,这是一门非常好的课程,到目前为止我完全可以推荐。刚刚观看了Statistics的TED演讲,我认为很棒,这是一种简单的方法,可以练习我在现实场景中学到的蟒蛇技巧。这个家伙给出了一个例子,说明了不断翻转硬币和寻找两个重复序列的可能性,他解释说,你会认为发生的概率与他声称的事实相同。简单地说他声称Heads Tails Heads的序列比Heads Tails Tails更容易发生,因为在第一个序列结束时你已经是三分之一再次重复序列,在第二个序列结束时你必须抛出再一次开始这个序列。这很有道理,所以我开始尝试使用这里显示的小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次抛掷和每10次HTT序列,因为它看起来像无论哪种方式我得到平均均衡的结果。所以我的问题是我在实施问题时出了什么问题?

5 个答案:

答案 0 :(得分: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次投掷的预期值。

答案 1 :(得分: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)

答案 2 :(得分: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

上询问

答案 3 :(得分: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

答案 4 :(得分:0)

当您从长序列中选择3个连续样本时,您的代码确认两个字符串出现的概率相等。

实际上对于任何给定的链,三个样本匹配它的概率总是1/2 ^ [链的长度] - 唯一的变量是长度,而不是内容。

你描述的TED演讲听起来就像对Penney游戏的描述:http://en.wikipedia.org/wiki/Penney%27s_game 但是这里的一个关键区别是Penney的游戏描述了任何一个序列发生的可能性(所以一个给定的玩家可以获胜) - 而不是你的代码找到的总发生次数。也可能TED扬声器向后获得第二个序列(HHT,而不是HTT。)

以下代码测试(并确认)Penney游戏中的统计异常。注意它在发现时“中断”或退出内循环。

输出: 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`

`