Advertisement
Guest User

Untitled

a guest
Mar 25th, 2021
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.92 KB | None | 0 0
  1. import random
  2. from collections import Counter
  3. import itertools
  4.  
  5. random.seed(0xdeadbeef)
  6. # output for this seed:
  7. # testing good draw
  8. # PASSED chi-squared test; got 2.612083333333333 <  18.47 for 3 DOF
  9. # testing bad draw
  10. # FAILED chi-squared test; got 1005.0618333333333 >= 18.47 for 3 DOF
  11.  
  12. probs = [
  13.     (1, 0.1),
  14.     (2, 0.2),
  15.     (3, 0.3),
  16.     (4, 0.4),
  17. ]
  18.  
  19. chi_squared_table = [
  20.     # p-values
  21.     [ 0,  0.95,  0.90,   0.80,   0.70,   0.50,    0.30,   0.20,   0.10,   0.05,   0.01,  0.001],
  22.     # values
  23.     [ 1, 0.004,  0.02,   0.06,   0.15,   0.46,    1.07,   1.64,   2.71,   3.84,   6.63,  10.83],
  24.     [ 2,  0.10,  0.21,   0.45,   0.71,   1.39,    2.41,   3.22,   4.61,   5.99,   9.21,  13.82],
  25.     [ 3,  0.35,  0.58,   1.01,   1.42,   2.37,    3.66,   4.64,   6.25,   7.81,  11.34,  16.27],
  26.     [ 4,  0.71,  1.06,   1.65,   2.20,   3.36,    4.88,   5.99,   7.78,   9.49,  13.28,  18.47],
  27.     [ 5,  1.14,  1.61,   2.34,   3.00,   4.35,    6.06,   7.29,   9.24,  11.07,  15.09,  20.52],
  28.     [ 6,  1.63,  2.20,   3.07,   3.83,   5.35,    7.23,   8.56,  10.64,  12.59,  16.81,  22.46],
  29.     [ 7,  2.17,  2.83,   3.82,   4.67,   6.35,    8.38,   9.80,  12.02,  14.07,  18.48,  24.32],
  30.     [ 8,  2.73,  3.49,   4.59,   5.53,   7.34,    9.52,  11.03,  13.36,  15.51,  20.09,  26.12],
  31.     [ 9,  3.32,  4.17,   5.38,   6.39,   8.34,   10.66,  12.24,  14.68,  16.92,  21.67,  27.88],
  32.     [10,  3.94,  4.87,   6.18,   7.27,   9.34,   11.78,  13.44,  15.99,  18.31,  23.21,  29.59],
  33. ]
  34.  
  35. p = 0.001 # controls flakiness; lower value decreases change of random failures
  36.           # but increases chance bad implementation gets through
  37. p_index = chi_squared_table[0].index(p)
  38.  
  39. def test_draw(draw, num_trials=10000):
  40.     N = len(probs) # N - 1 DOF
  41.     observed = Counter()
  42.     for _ in range(num_trials):
  43.         observed[draw(probs)] += 1
  44.     expected = Counter()
  45.     for val, prob in probs:
  46.         expected[val] = num_trials * prob
  47.     # compute statistical significance
  48.     chi_squared = sum(
  49.         (observed[k] - expected[k]) ** 2 / expected[k]
  50.         for k in set(observed) | set(expected)
  51.     )
  52.     table_value = chi_squared_table[N][p_index]
  53.     if chi_squared >= table_value:
  54.         print(f'FAILED chi-squared test; got {chi_squared} >= {table_value} for {N - 1} DOF')
  55.     else:
  56.         print(f'PASSED chi-squared test; got {chi_squared} <  {table_value} for {N - 1} DOF')
  57.  
  58. def good_draw(probs):
  59.     rv = random.random()
  60.     for val, prob in probs:
  61.         rv -= prob
  62.         if rv <= 0:
  63.             return val
  64.     # p=0 this happens
  65.     return probs[0][0]
  66.  
  67. def bad_draw(probs):
  68.     # increasing number of trials makes this converge to good_draw
  69.     for _ in range(2):
  70.         val, prob = random.choice(probs)
  71.         if random.random() < prob:
  72.             return val
  73.     # give up
  74.     return random.choice(probs)[0]
  75.  
  76. print('testing good draw')
  77. test_draw(good_draw)
  78. print('testing bad draw')
  79. test_draw(bad_draw)
  80.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement