【问题标题】:Using python to analyse coin tossing statistics使用python分析抛硬币统计
【发布时间】:2014-02-13 17:44:08
【问题描述】:

我一直在 edX 上学习 python 编程,这是一门非常好的课程,到目前为止我可以完全推荐。刚刚在Statistics 上观看了 TED 演讲,我觉得很棒,这是一种锻炼我在现实世界场景中学到的 Python 技能的简单方法。这家伙举了一个关于不断抛硬币并寻找两个重复序列的概率的例子,他解释说,你会认为发生的概率与他声称的实际上没有发生的概率相同。简单地说,他声称序列 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 次投掷发生,而 HTT 序列应该每 10 次发生,就像看起来一样无论哪种方式,我都能得到平均平衡的结果。所以我的问题是我在执行问题时哪里出错了?

【问题讨论】:

  • 我认为这家伙的说法是虚假的,除非他说你更有可能通过少量的投掷获得 HTH。为了从 HTH 中获得比 HTT 更多的里程,出于他所说的原因,您还必须获得比 HTTH 更多的 HTHT 出现次数。但是,如果你应用他的相同逻辑,HTTH 已经在序列的开头结束了,而你必须使用 HTHT 重新开始。
  • @MarkkuK。实际上,当您拥有 HTHT 时,您已经拥有下一个 HTHT 的前两个字母。对于 HTTH,您只有第一个字母。
  • @MattParker,这是真的,我把那家伙说的话应用得太狭隘了。但是,HTHT 与 HTTH 的统计数据也大致相同,至少使用此处的方法。
  • @MarkkuK。同意 - 我认为你关于翻转总数的观点可能是它的核心。当 N = 5 时(正如 EducateMe 在下面指出的那样),HTH 具有明显的优势,可能也在 10 和 15 时,但它可能已经减少了一百万......

标签: python python-2.7 statistics


【解决方案1】:

您的专家是对的,您所说的代码是正确的,但他实际上说了其他话。他说,当你开始抛硬币时,你应该期望看到 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 次投掷的预期值。

【讨论】:

  • 就是这样。我刚刚在视频中再次观看了该部分,现在可以看到我哪里出错了。这是我对实际问题的解释。我应该做的是平均计数直到序列出现,而不是平均抛硬币的总数。谢谢。
【解决方案2】:

至于您的代码,这在功能上是等效的:

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 我会在 stats.stackexchange.com 上试一试。我没有意识到这种东西有单独的交换。以为我会在这里尝试,因为它与我的 python 相关。
  • @Hoppo 确实,stackoverflow 是询问您是否有与您的 代码 相关的问题的最佳场所(我觉得很好)。请不要在统计数据上发布您的代码,只需询问序列是否应该出现相同的次数
【解决方案3】:
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)

【讨论】:

  • 这给出了相同的结果?
  • 我认为它应该......在 100 万个上的两次测试运行返回了大约 124917 HTH、124855 HTT。 HTH 应该更频繁发生的原因是因为 HTHTH = 2 的可能性,而没有这样的五次翻转组合会产生两个 HTT 结果。
【解决方案4】:

当您从长序列中选择 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`

`

【讨论】:

    【解决方案5】:

    我认为你的专家错了,或者你误解了他的意思。我认为您的检测 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      • 2014-05-25
      • 2011-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多