我实现了Wald-Wolfowitz runs test但是在测试期间我遇到了奇怪的行为,我采取的步骤如下:
我从同一个发行版中取出两个样本:
import numpy as np
list_dist_A = np.random.chisquare(2, 1000)
list_dist_B = np.random.chisquare(2, 1000)
我连接两个列表并对它们进行排序,同时记住哪个数字来自哪个样本。以下函数执行此操作并返回标签列表[“A”,“B”,“A”,“A”,...“B”]
def _get_runs_list(list1, list2):
# Add labels
l1 = list(map(lambda x: (x, "A"), list1))
l2 = list(map(lambda x: (x, "B"), list2))
# Concatenate
lst = l1 + l2
# Sort
sorted_list = sorted(lst, key=lambda x: x[0])
# Return only the labels:
return [l[1] for l in sorted_list]
现在我想计算运行次数(连续的相同标签序列)。 e.g:
为此,我使用以下代码:
def _calculate_nruns(labels):
nruns = 0
last_seen = None
for label in labels:
if label != last_seen:
nruns += 1
last_seen = label
return nruns
由于所有元素都是随机绘制的,我认为我应该大致以序列a,b,a,b,a,b...
结束。所以这意味着运行次数大约是2000。
然而,可以看出in this snippet on "repl.it"情况并非如此,它总是大约在1000左右。
任何人都可以解释为什么会这样吗?
答案 0 :(得分:4)
~1000是预期的结果。 Following the Wikipedia article在此统计测试中,您有Np = Nn = 1000
和N = Np + Nn = 2000
。这意味着运行次数的预期值为mu = 2 * Np * Nn / N + 1
,即1001。
答案 1 :(得分:2)
哦,这让我想起了Gambler's fallacy。
我不是统计学家,但要获得2000次运行,您需要A
跟随B
和B
跟随A
的可能性为100%。这表明PRNG对先前的抽奖有某种记忆。那不太好......
OTOH,假设您绘制了一个标记为A
的值,那么有50%的几率绘制另一个A
,并有50%的机会绘制B
。因此,绘制长度一次运行的机会实际上只有50%,获得长度为2的运行的机会是25%,长度为3,它是12.5%,长度为4,它是6.25,依此类推。
最后一部分可以轻松验证:
import numpy as np
list_dist_A = np.random.chisquare(2, 1000)
list_dist_B = np.random.chisquare(2, 1000)
listA = [(value, 'A') for value in list_dist_A]
listB = [(value, 'B') for value in list_dist_B]
combined = sorted(listA+listB, key=lambda x: x[0])
combined = [x[1] for x in combined]
from itertools import groupby
from collections import Counter
runlengths = [len(list(it)) for _, it in groupby(combined)] # lengths of the individual runs
print(Counter(runlengths)) # similar to a histogram
# Counter({1: 497, 2: 234, 3: 131, 4: 65, 5: 29, 6: 20, 7: 11, 8: 2, 10: 1, 14: 1})
所以这实际上非常接近预期(如上所述:1: 500, 2: 250, 3: 125, 4:62, ...
)。如果您的假设是正确的,那么它将更接近1:2000, 2: 0, ...