我创建了一个小型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
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
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
这是我的代码:
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))
答案 0 :(得分:8)
你在这里混合了一些东西。
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发行版的评论吸收其他发行版的属性,我认为这有点混乱。如果您从另一个发行版中统一随机选择值 - 这就是此代码正在执行的操作 - 那么您将再次使用原始发行版。在这种情况下,如果您从任何其他分布中均匀地随机选择变量,则随着样本量的增长,您将恢复原始分布。
我完全同意统一取数字(即ala random.random()
)将返回本福德分布,如果原始数字符合本福德定律,那么问题归结为决定是否从每个集合中的每个数字开始的数字概率的平均值:
1
1 2
1 2 3
1 2 3 4
...
有Benford发行版。这里需要注意的是,在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
这是每个i
的B_i(N)。我创建它们时,我会添加大N的图。这些图是每[i * 10 ** j for j in range(lowPower, highPower) for i in range(1,10)] + [10 ** (highPower)]
个,使用三次样条插值,因此我不必执行尽可能多的数据点。插值虽然差别很小。
虽然在日志范围内查看它会更有意义;
请注意,您不必平均这些线以获得整个分布的平均值,这些是问题中第二个PRNG的B_i(N)的预期值。