我创建了一个小型Python程序,它将计算各种"随机"数字的概率,看看它们是否遵循本福德定律.
我的算法可能不是最有效的,但它仍然可以完成这项工作.
我的问题是,为什么numGen1不遵循规则,其中numGen2和numGen3遵循规则?
这与计算机生成数字的方式有关吗?
样本输出(n = 5000):
NumGen1:
Occurance of starting with 1 is 0.112
Occurance of starting with 2 is 0.104
Occurance of starting with 3 is 0.117
Occurance of starting with 4 is 0.117
Run Code Online (Sandbox Code Playgroud)
NumGen2:
Occurance of starting with 1 is 0.327
Occurance of starting with 2 is 0.208
Occurance of starting with 3 is 0.141
Occurance of starting with 4 is 0.078
Run Code Online (Sandbox Code Playgroud)
NumGen3:
Occurance of starting with 1 is 0.301
Occurance of starting with 2 is 0.176
Occurance of starting with 3 is 0.125
Occurance of starting with 4 is 0.097
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
import random
def numGen1(n):
'''random.randint choses an integer from [1,n]'''
L = []
start1 = 0
start2 = 0
start3 = 0
start4 = 0
for i in range(n):
L.append(str(random.randint(1,10000000)))
for numbers in L:
x = eval(numbers[0])
if x == 1:
start1 += 1
if x == 2:
start2 += 1
if x == 3:
start3 += 1
if x == 4:
start4 += 1
print ("Occurance of starting with 1 is %.3f \n"
"Occurance of starting with 2 is %.3f \n"
"Occurance of starting with 3 is %.3f \n"
"Occurance of starting with 4 is %.3f ") % (start1/float(n),start2/float(n),start3/float(n),start4/float(n))
def numGen2(n):
'''random.random() takes a number x, such that 0 <= x < 1 '''
L = []
start1 = 0
start2 = 0
start3 = 0
start4 = 0
for i in range(n):
L.append(str(random.random()*i))
for numbers in L:
x = eval(numbers[0])
if x == 1:
start1 += 1
if x == 2:
start2 += 1
if x == 3:
start3 += 1
if x == 4:
start4 += 1
print ("Occurance of starting with 1 is %.3f \n"
"Occurance of starting with 2 is %.3f \n"
"Occurance of starting with 3 is %.3f \n"
"Occurance of starting with 4 is %.3f ") % (start1/float(n),start2/float(n),start3/float(n),start4/float(n))
def numGen3(n):
'''Fibonnaci sequence generator'''
a = 0
b = 1
c = 0
L=[]
start1 = 0
start2 = 0
start3 = 0
start4 = 0
for i in range(n):
c = a + b
a = b
b = c
L.append(str(c))
for numbers in L:
x = eval(numbers[0])
if x == 1:
start1 += 1
if x == 2:
start2 += 1
if x == 3:
start3 += 1
if x == 4:
start4 += 1
print ("Occurance of starting with 1 is %.3f \n"
"Occurance of starting with 2 is %.3f \n"
"Occurance of starting with 3 is %.3f \n"
"Occurance of starting with 4 is %.3f ") % (start1/float(n),start2/float(n),start3/float(n),start4/float(n))
Run Code Online (Sandbox Code Playgroud)
你在这里搞混合了.
Bendford定律适用于数据来源,你可以说它是他们坚持的东西.你基本上定义了三个随机数生成器; 它们有自己的规则来管理它们如何创建数字.
存在许多类型的随机数生成,其中两个主要是均匀的,并且是高斯的,其中它们生成在最小值和最大值之间均匀间隔的数量,并且通常分布为具有标准偏差的平均值(分别).
只有你的第三个随机数发生器可以说满足本福德定律,第二个类似,但它不符合法则(它与log(d + 1) - log(d)不匹配).这些只是随机数生成器的特征,这是一个数学问题.
你的第三个人遵守法律,因为斐波那契数字遵守规则.如果你使用阶乘法和大多数数字的权力做同样的事情,你会得到相同的结果,因为它们碰巧遵守本福德定律.
第二个PRNG依赖于N,例如,如果N是某个值,如80000,那么您将错过8XXXX和9XXXX条目,并使结果偏斜.大概最好的选择是只有N作为10的幂,我会测试这个.这对N =\infty表现如何,虽然我也不确定,我会尝试推断.
下面是N的不同值的分布图,注意尖点,以及它们如何出现在不同的颜色上(抱歉传说,我没想到我什么时候绘制它,并且绘制时需要花费很多时间.)
如果你只看10的力量,那么你就失去了尖点;
我运行N的每个值足够多次,以便它们都具有相同数量的样本 - 即1000的行运行1000次,1000000的行运行一次.这应该已经消除了大部分的随机性.我会说这不符合本福德定律.你可以选择一些神奇的数字来让它发挥作用,但这并不符合本福德定律的精神,这通常被认为是所有数据极限的行为.
随着N的进一步增加,它会转向正确的分布,我会想出它的分析公式,然后尝试绘制它.
至于unutbu关于Benford分布的评论吸收了其他发行版的属性,我认为这有点混乱.如果您从另一个发行版中统一随机选择值 - 这就是此代码正在执行的操作 - 那么您将再次使用原始发行版.在这种情况下,如果您从任何其他分布中均匀地随机选择变量,则随着样本量的增长,您将恢复原始分布.
我完全同意random.random()
,如果原始数字符合本福德定律,那么统一取数字(即ala )将返回Benford分布,因此问题归结为决定数字概率的平均值是否从每个数字的每个数字开始套装:
1
1 2
1 2 3
1 2 3 4
...
Run Code Online (Sandbox Code Playgroud)
有一个本福德分布.这里需要注意的是,在10的每个倍数处,所有数字的分布相等,对于10的非倍数,它是不均匀的,从而对序列中的较早数字产生更多偏差.然而,我不知道是否遵循本福特定律对数字给予额外偏差的数量.
来自维基百科的这个情节:
声称它确实如此,但除此之外不提供任何其他内容.
每个数字包含在任何样本中的概率是:
其中N是最大值(或在原始问题中,n
在函数调用中),并且i
是数字.
然后需要将其转换为给出数字的概率,X
因为它是第一个数字.我不知道如何以一种简单的方式做到这一点,将需要更多的挖掘.我现在称它为B(i),如果某些东西真正地分配给它,它有B(1)= 30.1%(等)
我可以绘制它; 这是N = 100:
在每个10的幂,有一个类似波纹的特征,它扩展到下一个10的幂,你可以很容易地与从X开始的数字增加的概率相关(即对于N = 119,B(i)将是高于N = 99,因为我们在循环中有20次额外的迭代,其中从1开始的数字增加,即所有额外的数字)
每个涟漪都较长,因为它遍布整个域10 ^ m - > 10 ^ {m + 1}.这是N = 1000
这里是每个人的B_i(N)i
.当我创建它时,我将添加更大N的图.这些图是每个[i * 10 ** j for j in range(lowPower, highPower) for i in range(1,10)] + [10 ** (highPower)]
,使用三次样条插值,因此我不必执行尽可能多的数据点.插值虽然差别很小.
但是,在对数刻度上查看它会更有意义;
请注意,您不必平均这些线来获得整个分布的平均值,这些是问题中第二个PRNG的B_i(N)的预期值.