如何测试 d20 的公平性?

机器算法验证 假设检验 卡方检验 拟合优度 均匀分布 骰子
2022-02-09 05:01:26

如何测试二十面骰子 (d20) 的公平性?显然,我会将值的分布与均匀分布进行比较。我依稀记得在大学里使用卡方检验。我如何应用它来查看骰子是否公平?

4个回答

这是一个带有 R 代码的示例。输出以# 开头。公平的死亡:

rolls <- sample(1:20, 200, replace = T)
table(rolls)
#rolls
# 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
# 7  8 11  9 12 14  9 14 11  7 11 10 13  8  8  5 13  9 10 11 
 chisq.test(table(rolls), p = rep(0.05, 20))

#         Chi-squared test for given probabilities
#
# data:  table(rolls) 
# X-squared = 11.6, df = 19, p-value = 0.902

有偏差的骰子 - 数字 1 到 10 每个的概率为 0.045;那些 11-20 有 0.055 - 200 次投掷的概率:

rolls <- sample(1:20, 200, replace = T, prob=cbind(rep(0.045,10), rep(0.055,10)))
table(rolls)
#rolls
# 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
# 8  9  7 12  9  7 14  5 10 12 11 13 14 16  6 10 10  7  9 11 
chisq.test(table(rolls), p = rep(0.05, 20))

#        Chi-squared test for given probabilities
#
# data:  table(rolls) 
# X-squared = 16.2, df = 19, p-value = 0.6439

我们没有足够的偏见证据(p = 0.64)。

一个有偏差的骰子,1000 次投掷:

rolls <- sample(1:20, 1000, replace = T, prob=cbind(rep(0.045,10), rep(0.055,10)))
table(rolls)
#rolls
# 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
# 42 47 34 42 47 45 48 43 42 45 52 50 57 57 60 68 49 67 42 63 
chisq.test(table(rolls), p = rep(0.05, 20))

#        Chi-squared test for given probabilities
#
# data:  table(rolls) 
# X-squared = 32.36, df = 19, p-value = 0.02846

现在 p<0.05,我们开始看到偏见的证据。您可以使用类似的模拟来估计您可以预期检测到的偏差水平以及在给定 p 水平下检测它所需的投掷次数。

哇,甚至在我完成打字之前还有2个其他答案。

你想手工做还是用excel做?

如果你想在R中这样做,你可以这样做:

第 1 步:掷骰子(比如说)100 次。

第 2 步:计算您获得每个数字的次数

第 3 步:像这样将它们放入 R 中(写下你得到的每个骰子的次数,而不是我写的数字):

x <- as.table(c(1,2,3,4,5,6,7,80,9,10,11,12,13,14,15,16,17,18,19,20))

第 4 步:只需运行以下命令:

chisq.test(x)

如果 P 值低(例如:低于 0.05)- 你的骰子不平衡。

此命令模拟平衡骰子 (P= ~.5):

chisq.test(table(sample(1:20, 100, T)))

这模拟了一个不平衡的骰子:

chisq.test(table(c(rep(20,10),sample(1:20, 100, T))))

(它大约是 P = ~.005)

现在真正的问题是应该将多少骰子滚动到什么级别的检测能力。如果有人想解决这个问题,欢迎他...

更新:这里也有一篇关于这个主题的好文章

还没有人建议贝叶斯方法吗?我知道这个问题已经回答了,但到底是什么。以下仅适用于 3 面模具,但我猜如何将其修复为面是显而易见的。n=37

首先,与@Glen_b 所说的一致,贝叶斯实际上对骰子是否完全公平并不感兴趣——事实并非如此。他关心的是它是否足够接近,无论“足够”在上下文中意味着什么,例如,对于每一方来说,在公平的 5% 以内。

如果代表滚动 1、2 和 3 的概率,那么我们用先验分布表示我们关于的先验知识,并且为了简化数学,我们可以选择狄利克雷分布请注意对于非信息性先验,我们可能会选择先验参数,例如p1p2p3p=(p1,p2,p3)p1+p2+p3=1α0=(1,1,1)

如果表示观察到的 1,2,3 计数,那么当然具有参数的多项分布,并且理论说后验也是带参数的狄利克雷分布(在这里,狄利克雷称为共轭先验。)X=(X1,X2,X3)Xp=(p1,p2,p3)α=(x1+1,x2+1,x3+1)

我们观察数据,用贝叶斯规则找到后验,然后所有的推理都是基于后验的。想要估计吗?求后验的均值。想要置信区间(不,相当可信的区间)?计算后部下方的一些区域。对于现实世界中的复杂问题,我们通常从后验进行模拟,并获得上述所有问题的模拟估计。p

无论如何,这是(使用R)的方法:

首先,获取一些数据。我们掷骰子 500 次。

set.seed(1)
y <- rmultinom(1, size = 500, prob = c(1,1,1))

(我们从一个公平的骰子开始;在实践中,这些数据会被观察到。)

接下来,我们模拟 5000 次观察p从后面看一下结果。

library(MCMCpack)
A <- MCmultinomdirichlet(y, alpha0 = c(1,1,1), mc = 5000)
plot(A)
summary(A)

最后,让我们估计我们的后验概率(在观察数据之后),骰子在每个坐标中的公平误差在 0.05 以内。

B <- as.matrix(A)
f <- function(x) all((x > 0.28)*(x < 0.38))
mean(apply(B, MARGIN = 1, FUN = f))

结果在我的机器上约为 0.9486。(这并不奇怪,真的。毕竟我们是从一个公平的骰子开始的。)

快速评论:我们在这个例子中使用非信息性先验可能是不合理的。由于甚至有一个问题,大概一开始骰子看起来是近似平衡的,所以最好选择一个在所有坐标中都集中在接近 1/3 的先验。高于此只会使我们估计的“接近公平”的后验概率更高。

如果您只想检查每个数字出现的次数,那么卡方检验将是合适的。假设你掷骰子 N 次。您会期望每个值都会出现 N/20 次。卡方检验所做的只是将您观察到的内容与您得到的内容进行比较。如果此差异太大,则表明存在问题。

其他测试

如果您对随机性的其他方面感兴趣,例如,如果您 dice 给出以下输出:

1, 2, 3, 4...., 20,1,2,..

然后虽然这个输出有每个单独值的正确数量,但它显然不是随机的。在这种情况下,看看这个问题这可能只对电子骰子有意义。

R中的卡方检验

在 R 中,这将是

##Roll 200 times
> rolls = sample(1:20, 200, replace=TRUE)
> chisq.test(table(rolls), p = rep(0.05, 20))
    Chi-squared test for given probabilities
data:  table(rolls) 
X-squared = 16.2, df = 19, p-value = 0.6439

## Too many 1's in the sample
> badrolls = cbind(rolls, rep(1, 10))   
> chisq.test(table(badrolls), p = rep(0.05, 20))

    Chi-squared test for given probabilities

data:  table(badrolls) 
X-squared = 1848.1, df = 19, p-value < 2.2e-16