How to resolve the algorithm Probabilistic choice step by step in the Python programming language
How to resolve the algorithm Probabilistic choice step by step in the Python programming language
Table of Contents
Problem Statement
Given a mapping between items and their required probability of occurrence, generate a million items randomly subject to the given probabilities and compare the target probability of occurrence versus the generated values. The total of all the probabilities should equal one. (Because floating point arithmetic is involved, this is subject to rounding errors).
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Probabilistic choice step by step in the Python programming language
The code you provided is a Python program that implements two functions for choosing items from a list with specified probabilities.
The first function, probchoice
, splits the interval 0.0-1.0 in proportion to the specified probabilities and then finds where each random number generated by random.random()
lies. The function returns the item at the corresponding index in the list.
The second function, probchoice2
, puts the items in bins in proportion to the specified probabilities and then uses random.choice()
to select items. The function returns the item selected by random.choice()
.
The tester
function tests the two functions by generating a specified number of random choices and counting the number of times each item is chosen. The function then prints the target probabilities, the attained probabilities, and the number of trials.
The program is executed if it is run as the main program (if __name__ == '__main__'
) and tests the two functions with a list of items and probabilities. The program generates 1,000,000 random choices for each function.
Source code in the python programming language
import random, bisect
def probchoice(items, probs):
'''\
Splits the interval 0.0-1.0 in proportion to probs
then finds where each random.random() choice lies
'''
prob_accumulator = 0
accumulator = []
for p in probs:
prob_accumulator += p
accumulator.append(prob_accumulator)
while True:
r = random.random()
yield items[bisect.bisect(accumulator, r)]
def probchoice2(items, probs, bincount=10000):
'''\
Puts items in bins in proportion to probs
then uses random.choice() to select items.
Larger bincount for more memory use but
higher accuracy (on avarage).
'''
bins = []
for item,prob in zip(items, probs):
bins += [item]*int(bincount*prob)
while True:
yield random.choice(bins)
def tester(func=probchoice, items='good bad ugly'.split(),
probs=[0.5, 0.3, 0.2],
trials = 100000
):
def problist2string(probs):
'''\
Turns a list of probabilities into a string
Also rounds FP values
'''
return ",".join('%8.6f' % (p,) for p in probs)
from collections import defaultdict
counter = defaultdict(int)
it = func(items, probs)
for dummy in xrange(trials):
counter[it.next()] += 1
print "\n##\n## %s\n##" % func.func_name.upper()
print "Trials: ", trials
print "Items: ", ' '.join(items)
print "Target probability: ", problist2string(probs)
print "Attained probability:", problist2string(
counter[x]/float(trials) for x in items)
if __name__ == '__main__':
items = 'aleph beth gimel daleth he waw zayin heth'.split()
probs = [1/(float(n)+5) for n in range(len(items))]
probs[-1] = 1-sum(probs[:-1])
tester(probchoice, items, probs, 1000000)
tester(probchoice2, items, probs, 1000000)
You may also check:How to resolve the algorithm Literals/Integer step by step in the 68000 Assembly programming language
You may also check:How to resolve the algorithm Emirp primes step by step in the zkl programming language
You may also check:How to resolve the algorithm Rosetta Code/Find bare lang tags step by step in the Icon and Unicon programming language
You may also check:How to resolve the algorithm Deal cards for FreeCell step by step in the Fortran programming language
You may also check:How to resolve the algorithm Sequence of non-squares step by step in the SparForte programming language