Random.choices not returning uniform distribution

Viewed 198

I am trying to simulate a uniform distribution of discrete values using random.choices. Each time that a new set is generated, a key representing the unique counts is incremented.

Why is the uniform outcome ([2,2]) less likely to occur than [1,3]?

def sim_counts(size, values=[1,-1], popsize=2):
    
    count_dict = {}
    for i in range(popsize):
        X = random.choices(values,k=size)
        _, counts = np.unique(X, return_counts=True)
        
        if len(counts) == 1:
            counts = [0,counts[0]]
        key = str(np.sort(counts))

        if key not in count_dict:
            count_dict[key] = 0
            count_dict[key] +=1
        else:
            count_dict[key] +=1
            
    return count_dict
   
sim_counts(4, values=[1,-1], popsize=10000)

>>> {'[2 2]': 3747, '[0 4]': 1319, '[1 3]': 4934}
2 Answers

This is actually more of a mathematical question than programming.

Here are all the permutations that produce [3 1] counts:

[1, 1, 1, -1]
[1, 1, -1, 1]
[1, -1, 1, 1]
[-1, 1, 1, 1]
[-1, -1, -1, 1]
[-1, -1, 1, -1]
[-1, 1, -1, -1]
[1, -1, -1, -1]

Here are all the [2 2] permutations:

[1, 1, -1, -1]
[1, -1, 1, -1]
[-1, 1, 1, -1]
[1, -1, -1, 1]
[-1, 1, -1, 1]
[-1, -1, 1, 1]

So the ratio is 8:6, which is the approximate ratio of your results.

As part of the tidy of the code, you are setting key = str(numpy.sort(counts)) and this is hiding that there are two ways to get a key of [1 3] using that strategy.

If you run the test again without the sort, I think you will find that the result [2 2] is more common as you expected but that the results of [1 3] and [3 1] while individually less combine to a greater amount.

For example:

{'[3 1]': 2521, '[1 3]': 2550, '[2 2]': 3721, '[0, 4]': 1208}

Please also see @barmar's answer for a more nuanced look at the individual permutations that result in the keys in question.

Related