Python: грешката при закръгляване изкривява равномерното разпределение

Трябва да взема проби от 10 равномерно разпределени произволни числа между 0 и 1. Затова реших, че следният код в python ще направи това:

positions = []
for dummy_i in range(1000000):
    positions.append(round(random.random(),1))

Въпреки това, когато поставите резултата в хистограма, резултатът изглежда както следва:

Честота на числата, закръглени до 1 знак след десетичната запетая

Така че закръгляването изглежда разрушава равномерното разпределение, генерирано от random.random(). Чудя се какво причинява това и как да предотвратя това да се случи. Благодаря за вашата помощ!


person harlekin    schedule 17.12.2015    source източник
comment
Лесен начин да получите броя (и да видите, че групирането на хистограми е това, което изкривява нещата) е да използвате collections.Counter: опитайте collections.Counter(round(random.random(), 1) for _ in range(10**6)) и ще видите, че броят е приблизително еднакъв за 0.1 до 0.9.   -  person Mark Dickinson    schedule 17.12.2015


Отговори (4)


Изглежда, че имате проблем по-късно в кода... (напр. при събиране на статистиката). Вижте този по-малък фрагмент:

import random, collections
data = collections.defaultdict(int)
for x in range(1000000):
    data[round(random.random(),1)] += 1
print(data)

Ще видите, че 0 и 1 разбира се имат около половината от извадките на другите стойности, които са почти еднакви.

Например получих:

defaultdict(<class 'int'>,
            {0.4: 100083,
             0.9: 99857,
             0.3: 99892,
             0.8: 99586,
             0.5: 100108,
             1.0: 49874,     # Correctly about half the others
             0.7: 100236,
             0.2: 99847,
             0.1: 100251,
             0.6: 100058,
             0.0: 50208})    # Correctly about half the others
person 6502    schedule 17.12.2015

Вашият начин за създаване на хистограмата е грешен. Трябва да получите приблизително:

50k за 0 и 1

100k за всички останали номера

Но третият ви бин е от 0,2 включително до 0,3 включително, което води до 200k, докато четвъртият ви бин е от 0,3 ексклузивно до 0,4 ексклузивно, което води до нула.

Опитайте се да създадете хистограма, където ръбовете са 0,05, 0,15 и т.н., тогава няма да имате такива грешки в точността.

person Daniel    schedule 17.12.2015

Опитайте тази

positions = []
for dummy_i in range(10):
    positions.append(random.randint (0, 10) / 10)
person Victor Voronov    schedule 17.12.2015

Мисля, че може да е по-чисто и по-ефективно да използвате Numpy тук:

import numpy as np
positions = np.random.random(10000)
positions = np.round(positions, decimals=3)
person piman314    schedule 17.12.2015
comment
Хм. Това всъщност не е отговор на въпроса на OP: това е коментар, маскиран като отговор. - person Mark Dickinson; 18.12.2015