翻转硬币:序列的概率与个体的概率

机器算法验证 r 可能性 分布 模拟 赔率
2022-04-01 22:15:54

这是我想到的一个问题:

  • 假设我正在看某人掷硬币。每次翻转都完全独立于前一次翻转。
  • 我看着这个人连续翻转3个头。
  • 我打断这个人并提出以下提议:如果下一次翻转结果是“头”,我会给你买一片披萨;如果下一次翻转导致“尾巴”,你会给我买一片披萨。

我的问题:谁的获胜几率更大?


我使用 R 编程语言编写了以下模拟。在这个模拟中,一个“硬币”被翻转了很多次(“1”=HEAD,“0”=TAILS)。然后我们计算 HEAD-HEAD-HEAD-HEAD 出现次数与 HEAD-HEAD-HEAD-TAILS 相比的百分比:

#load library
library(stringr)

#define number of flips
n <- 10^7

#flip the coin many times
set.seed(1)
flips = sample(c(0,1), replace=TRUE, size=n)

#count the percent of times HEAD-HEAD-HEAD-HEAD appears 
str_count(paste(flips, collapse=""), '1111') / n

0.0333663

#count the percent tof times HEAD-HEAD-HEAD-TAIL appears
str_count(paste(flips, collapse=""), '1110') / n

0.0624983

从上面的分析来看,似乎这个人的运气用完了:在 3 个 HEADS 之后,下一次翻转是 HEAD 的几率为 3.33%,而下一次翻转不是 HEAD 的几率为 6.25%(即 TAILS )。

因此,我们是否可以得出结论:即使每次翻转的概率与前一次翻转无关,但观察一系列 HEADS 然后下一次翻转将是 TAILS 在统计上变得更有利?因此,您观察到的 HEADS 序列越长,“破坏”序列的概率就越大?

3个回答

默认情况下,str_count不计算指定模式的重叠出现次数。子串1111可以与其自身基本重叠,而子串1110不能与其自身重叠。因此,您对第一个子字符串的计算存在很大偏差——您大大低估了该模式在您的模拟中实际出现的次数。试试这个替代方法:

#Flip the coin many times
set.seed(1)
n     <- 10^8
FLIPS <- sample(c(0,1), size = n, replace = TRUE)

#Count the proportion of occurrences of 1-1-1-1
PATTERN.1111 <- FLIPS[1:(n-3)]*FLIPS[2:(n-2)]*FLIPS[3:(n-1)]*FLIPS[4:n]
sum(PATTERN.1111)/n
[1] 0.06246614

#Count the proportion of occurrences of 1-1-1-0
PATTERN.1110 <- FLIPS[1:(n-3)]*FLIPS[2:(n-2)]*FLIPS[3:(n-1)]*(1-FLIPS[4:n])
sum(PATTERN.1110)/n
[1] 0.0624983

通过这种替代模拟(计算模式的重叠出现),您可以获得大致相同的两个结果的比例。​如果掷硬币实际上是独立且“公平的”,那么每个玩家赢得赌注的概率相同。在数学上,四个结果的任何运行的真实概率是,因此它是上述模拟有效估计的;模拟中剩余的小差异是由于随机误差造成的。1/24=0.0625

编辑

您获得 HHHH 和 HHHT 百分比不同的原因是您正在计算非常长的字符串中的 1111 和 1110 的实例。你没有把它们分成 4 个块。在一个很长的字符串中,你更有可能连续有 3 个而不是连续有 4 个。由于您没有检查 4 的分组以确保翻转都在一个测试中,因此您最终会得到更多的 1110,然后是 1111。

编码问题的正确方法是将硬币翻转分组为 4 组。以下应该很容易理解,但有点慢。

#load library
library(stringr)

#define number of flips
n <- 100000

# Pre-assign a length of n to a data.frame
df <- data.frame(flip = character(n))

for(i in 1:n){
  df$flip[i] <- paste(sample(c(0,1),replace = TRUE,size = 4),collapse = "")
}

100*sum(df$flip == "1111")/n
# 6.259

100*sum(df$flip == "1110")/n
# 6.193

基于数学的原始答案(缺少代码):

这是对统计数据的常见误解。学习的好例子。

你的问题是:抛硬币 3 次后,如果我赌第 4 次抛硬币的结果,第 4 次抛硬币的概率是多少。

第 4 次翻转现在独立于前 3 次翻转。没有任何机制可以抓住硬币并改变第四次翻转的概率。第 4 次翻转将有 50% 的机会是正面,以及 50% 的机会是反面。

现在,您要回答的问题是:一枚硬币连续 4 次正面朝上的概率是多少。这是一个完全不同的问题。新问题是问你连续4次正面朝上的概率是多少,这是一个独立的问题,因为不仅第4次翻转必须是正面,还取决于前3次也是正面朝上。那么你在 4 次抛硬币中有 16 种可能的组合,并且只有 1 种可能的方式来产生 4 个正面(1/16 = 6.25%)。

啊,我的朋友,你犯了一个非常简单的错误。在您的模拟中,您正在计算一个人可以连续翻转 4 个头的次数的比例。 但这不是你下注的。

您在看到三个正面后下注,并且只对下一次翻转的结果下注。因为每次翻转都是独立的,并且硬币假设是公平的,所以正面的概率与反面的概率相同,因此几率是偶数!

如果您在四次翻转开始时下注,情况会有所不同。在这种情况下,我们可以只计算二项式密度。我们会看到连续 4 次正面朝上(以仅进行 4 次翻转为条件)非常小,因此再次假设硬币是公平的,您的赔率会更高。但是已经看到了 3 次翻转然后下注类似于只是投注硬币翻转。