user12419639
user12419639

Reputation:

Calculating probabilities in Python

I'm trying to write a script that computes the probability of choosing random elements from a given list. Here is what I have so far:

import random

a = [11, 12, 13, 14]
b = [21, 22, 23, 24, 25]
c = [31, 32, 33, 34, 35, 36]

total = a+b+c


print ("Choosing 3 random items from any list")
sampled_list = random.sample(total, 3)
print(sampled_list)

With this script I can choose three random elements without replacement. Now I want to compute the probability that the random list generated will include, for example, two elements from list b, or an element from each list. How should I go about this? Is my choice of numbers in a list not the most efficient way to do it?

Upvotes: 1

Views: 16092

Answers (3)

user4740565
user4740565

Reputation:

It might not be the most elegant solution, but at least it gives a simple solution that can be easily read and expanded.

import random

a = [11, 12, 13, 14]
b = [21, 22, 23, 24, 25]
c = [31, 32, 33, 34, 35, 36]

total = a+b+c

# Decide how many samples you want.
samples = 100

# Define an empty vector.
combs = []

# Get the possible outcomes of number of elements per list.
for i in range(0,4):
    for j in range(0,4):
        for k in range(0,4):
            if(i + j + k == 3):
                combs = combs + [[i,j,k]]
            
# Count of how many elements per group
accum = [0 for x in combs]

# Perform the experiment a number of times given the sample.
for i in range(samples):

    # Auxiliary variables.
    totalEnt = [0,0,0]
    sampled_list = random.sample(total, 3)

    # Store the number of elements that belong to each list.
    totalEnt[0] = [x in a for x in sampled_list].count(True)
    totalEnt[1] = [x in b for x in sampled_list].count(True)
    totalEnt[2] = [x in c for x in sampled_list].count(True)

    # According to the result add to the proper counter. 
    idx = combs.index(totalEnt)
    accum[idx] += 1

# Print the probabilities.
print("[elements in a, elements in b, elements in c]: Probability")
for i, elem in enumerate(accum):
    print(str(combs[i]) + ": " + str(elem/samples))

Upvotes: 0

1313e
1313e

Reputation: 1232

This is just probability theory. You only have to calculate the number of valid possibilities and divide it by the total number of possibilities.

So, we need an equation for calculating the number of possible combinations, or nCr:

from math import factorial

def nCr(n, r):
    return(factorial(n)//(factorial(r)*factorial(n-r)))

Now that we have that, we can calculate easily what the probability is of choosing the numbers in a specific way. Let's say we have a list of 3 values, each saying how many values were taken from a particular list. So, for example, if we want to have 2 from list 1 and 1 from list 2, we can calculate the probability that this happens when we randomly choose 3 out of a set of all lists, with:

from functools import reduce
import operator

# Define product function
def prod(iterable):
    return(reduce(operator.mul, iterable, 1))


# Define lists
numbers = [
    [11, 12, 13, 14],
    [21, 22, 23, 24, 25],
    [31, 32, 33, 34, 35, 36]
    ]

# Define how many are taken from each
n_taken = [2, 1, 0]


# Calculate number of values in each list
n_values = list(map(len, numbers))

# Calculate total number of values
n_total = sum(n_values)

# Calculate number of ways numbers can be taken this way
N1 = prod(map(nCr, n_values, n_taken))

# Calculate total number of possibilities
N2 = nCr(n_total, sum(n_taken))

# Divide the two
print(N1/N2)

Output: 0.06593406593406594 or about 6.6%.

You can modify the numbers and n_taken lists to add more lists or more numbers to the lists.

Upvotes: 0

xrisk
xrisk

Reputation: 3898

Here is how you would do Monte Carlo sampling for your first task (containing exactly two elements from B).

The broad idea is to check whether a particular sample satisfies whatever condition you have and increment a variable (counter) here. The approximate probability is then counter / N.

import random

a = [11, 12, 13, 14]
b = [21, 22, 23, 24, 25]
c = [31, 32, 33, 34, 35, 36]

total = a+b+c

N = 1000
counter = 0

for _ in range(N):
    sampled_list = random.sample(total, 3)
    els_in_b = 0
    for el in sampled_list:
        if el in b:
            els_in_b += 1
    if els_in_b == 2:
        counter += 1

print(counter / N)
 

Upvotes: 0

Related Questions