📜  在Python中运行随机性测试

📅  最后修改于: 2022-05-13 01:55:16.262000             🧑  作者: Mango

在Python中运行随机性测试

随机数是许多系统必不可少的一部分,包括模拟、密码学等等。因此,在没有明显逻辑和可预测性的情况下随机产生值的能力成为主要函数。由于计算机无法生成完全随机的值,因此使用称为伪随机数生成器 (PRNG)的算法来完成此任务。

PRNG 产生的值并不是真正随机的,它取决于提供给算法的初始值,即种子值。考虑到它的种子值,伪随机序列的可重现性对其在模拟中的应用至关重要,例如蒙特卡洛模拟,其中系统可能需要在同一序列上进行多次测试。

一些最流行和高度使用的 PRNG 是:

  1. Mersenne Twister:在Python、R、Excel、Matlab、Ruby 和许多更流行的软件系统中用作默认随机数生成器。
  2. 线性同余生成器:用于 C++ 和Java
  3. Wichmann-Hill 生成器:在 Excel 中使用,是Python 2.2 中的默认值
  4. 帕克-米勒发电机
  5. 中方外尔序列

为了确保 PRNG 生成的值尽可能接近随机,使用了几个统计检验,包括 Diehard 检验、TestU01 系列、卡方检验和随机性运行检验。本文重点介绍随机性的运行测试

什么是运行测试?

随机性运行检验是一种统计检验,用于检查数据中的随机性。它是一种非参数测试,使用数据运行来确定呈现的数据是随机的还是倾向于遵循某种模式。一次运行被定义为一系列增加的值或减少的值。增加或减少值的数量是运行的长度。

运行测试的第一步是计算数据序列中的运行次数。有几种方法可以定义运行,但是,在所有情况下,公式都必须产生一个二分序列的值。在我们的例子中,高于中位数的值被视为正数,低于中位数的值被视为负数。一次运行被定义为一系列连续的正值或负值。

应用运行测试

  • 应用此检验的第一步是制定零假设和备择假设。

H null :序列是随机产生的

H alt序列不是以随机方式产生的

  • 计算检验统计量 Z 为:

\qquad\,Z = \frac{R - \bar{R}}{s_R}其中, R = 观察到的运行次数R' = 预期运行次数,给出为\qquad\,\bar{R} = \frac{2 n_1 n_2}{n_1 + n_2} + 1 S R = 运行次数的标准偏差\qquad\,s_{R}^2 = \frac{2 n_1 n_2(2 n_1 n_2 - n_1 - n_2)}                {(n_1 + n_2)^2 (n_1 + n_2 - 1)}其中 n1 和 n2 =系列中正负值的数量

  • 对于给定的置信水平,将计算的 Z 统计量的值与 Zcritical 进行比较(对于 95% 的置信水平, Zcritical =1.96)。如果 |Z|>Z critical ,则拒绝零假设,即声明数字不是随机的。

例子:

Python3
# simple code to implement Runs 
# test of randomnes
  
import random
import math
import statistics
  
  
def runsTest(l, l_median):
  
    runs, n1, n2 = 0, 0, 0
      
    # Checking for start of new run
    for i in range(len(l)):
          
        # no. of runs
        if (l[i] >= l_median and l[i-1] < l_median) or \
                (l[i] < l_median and l[i-1] >= l_median):
            runs += 1  
          
        # no. of positive values
        if(l[i]) >= l_median:
            n1 += 1   
          
        # no. of negative values
        else:
            n2 += 1   
  
    runs_exp = ((2*n1*n2)/(n1+n2))+1
    stan_dev = math.sqrt((2*n1*n2*(2*n1*n2-n1-n2))/ \
                       (((n1+n2)**2)*(n1+n2-1)))
  
    z = (runs-runs_exp)/stan_dev
  
    return z
    
# Making a list of 100 random numbers 
l = []
for i in range(100):
    l.append(random.random())
      
l_median= statistics.median(l)
  
Z = abs(runsTest(l, l_median))
  
print('Z-statistic= ', Z)


输出:

Z-statistic=  1.809160364503323