是否有一个服从本福德定律的随机数分布?

2024-10-03 23:21:21 发布

您现在位置:Python中文网/ 问答频道 /正文

Python有许多方法可以生成不同的随机数分布,请参见documentation for the ^{} module。不幸的是,如果没有适当的数学背景,尤其是考虑到所需的参数,它们是无法理解的。在

我想知道这些方法中是否有一种能够产生服从Benford's Law分布的随机数,以及哪些参数值是合适的。也就是说,对于一组整数,这些整数应该以“1”开头,大约30%的时间,2“大约18%的时间,等等。


使用Jan Dvorak's answer我把下面的代码组合在一起,它看起来工作得很好。
def benfords_range_gen(stop, n):
    """ A generator that returns n random integers
    between 1 and stop-1 and whose distribution
    meets Benford's Law i.e. is logarithmic.
    """
    multiplier = math.log(stop)
    for i in range(n):
        yield int(math.exp(multiplier * random.random()))

>>> from collections import Counter
>>> Counter(str(i)[0] for i in benfords_range_gen(10000, 1000000))
Counter({'1': 300696, '2': 176142, '3': 124577, '4': 96756, '5': 79260, '6': 67413, '7': 58052, '8': 51308, '9': 45796})

Tags: and方法forcounter时间range整数random
2条回答

本福德定律描述了一组数的前几位的分布,如果这些数是从对数标度的大范围中选取的话。如果你在十年内准备一份原木均匀分布,它也将遵守法律。10^[0,1)将生成该分布。在

这将产生所需的分布:math.floor(10**random.random())

只是玩玩而已。在

对于像我这样不太擅长数学的人来说,这是一个效率更高,但可能更为明显的实现方法。。。在

创建任何所需分布的一种简单方法是用项目的所需百分比填充列表,然后使用random.choice(<list>),因为这将返回列表中项目的统一选择。在

import random
probs = [30.1, 17.6, 12.5, 9.7, 7.9, 6.7, 5.8, 5.1, 4.6]
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
population = sum([[n] * int(p * 10) for n, p in zip(nums, probs)], [])

max_value = 100
min_value = 1
result_pop = []
target_pop_size = 1000
while len(result_pop) < target_pop_size:
    s = str(random.choice(population))
    while True:
        r = random.randint(min_value, max_value)
        if str(r).startswith(s):
            break
    result_pop.append(r)

相关问题 更多 >