PHP mt_rand是真的随机还是可能有偏见?

时间:2016-08-29 18:48:53

标签: javascript php random adsense ab-testing

我在我的网站上做过两次基本的A-B-C测试,比如

if(mt_rand(0,2) == 0){
//THROW IN RE HERE 
}elseif(mt_rand(0,2) == 1){
//THROW IN LR HERE
}else{
//THROW IN LB HERE
}

我期待这三个条件经常发生(占所有网页浏览量的33.3%)。但是,展示次数(由Google Adsense衡量)显示了非常不同的分布。有趣的是,两个测试(下面的两个图表)显示了相似的模式:LB出现最多,然后是RE,然后是LR。

样本数量是数千,因此随机发生这种情况的可能性实际上为零。

我误解了mr_rand()吗?有人知道它是否经过了适当的测试?这些奇怪的模式怎么会出现呢?

enter image description here

2 个答案:

答案 0 :(得分:4)

你正在运行mt_rand测试两次..你有选项0,1和2.如果测试是0,你抛出RE。如果没有,(即它是1或2),你再次运行相同的测试,(再次使用选项0,1和2)。在那里你测试1,如果是,你扔LR。如果不是(它是0或2)你扔LB.如果你需要,我可以进一步解释..

    $number = mt_rand(0,2);
    switch ($number){
     case 0:
       //do re
       break;
     case 1:
       //do lr
       break;
     case 2:
       //do lb
       break;
    }

或者这也可以完成这项工作

if(mt_rand(0,2) == 0){
//THROW IN RE HERE 
}elseif(mt_rand(0,1) == 1){ //we've stripped RE out, no longer deciding from 3 options
//THROW IN LR HERE
}else{
//THROW IN LB HERE
}

答案 1 :(得分:3)

我不确定您是如何通过Google Adsense收集数据的。您是否通过传入一些自定义var来依赖Google Analytics?如果是这样,肯定会有其他导致偏见的因素与PHP无关。

为了测试统一的随机分布,我们可以在PHP中运行这样的测试。

$test = [0,0,0];
for($i = 0; $i < 100000; $i++) {
    $rand = mt_rand(0,2);
    $test[$rand]++;
}
var_dump($test);

哪个应该给你这样的结果......

array(3) {
  [0]=>
  int(33288)
  [1]=>
  int(33394)
  [2]=>
  int(33318)
}

这表示您正在寻找超过100K迭代的33%均匀分布。

值得注意的是mt_rand()的实现是PRNG(伪随机数生成器)而不是CSPRNG(密码安全伪随机数生成器)。这意味着,它不适合加密目的,但适用于其他PRNG需求。它基于Mersenne Twister,因为它比libc rand()更快。虽然我不认为您在数据中发现的任何问题可能是PHP实施mt_rand()的直接结果。