Skip to content

Instantly share code, notes, and snippets.

@kristovatlas
Created October 23, 2020 20:10
Show Gist options
  • Save kristovatlas/e9945d8e9360f4dac26cc07be44b12fd to your computer and use it in GitHub Desktop.
Save kristovatlas/e9945d8e9360f4dac26cc07be44b12fd to your computer and use it in GitHub Desktop.
evidence.py
"""
https://twitter.com/elliot_olds/status/1319364546880942080
To keep calculations simple, let's fix population size to 100
"""
POPULATION = 100
FRED_PROB_FIRST = 1/(0.6 * POPULATION)
NOT_FRED_PROB_FIRST = 1-FRED_PROB_FIRST
def prob_no_blood_type(population, num_crime_scene):
"""
Suppose there are p people in the population and n people at the scene of
the crime. If we have no idea how many people are at the scene of the crime
(n is between 1 and p, inclusive), then the probability that Fred was one of
the people at the scene of the crime is n/p.
"""
return num_crime_scene * 1.0 / population
def prob_blood_type(population, num_crime_scene):
"""
If we know that there were at least two people at the scene of the crime
with blood types O (60%) and AB (1%) respectively, and that Fred has blood
type O, then the probability is changed. Since order does not matter, let's
fix the first person at the scene as blood type O, the second as blood type
AB, and the remainder (if any) as being any remaining member of the
population.
The probability that Fred is the O type (first) is 1/(0.6p)
The probability that Fred isn't the O type (first) is 1-(1/(0.6p))
The probability that Fred is the AB type (second) is 0
The probability that is third or later is based on the probability that
Fred was in none of the previous places multiplied by probability that
he was at a specific place. He cannot appear in multiple places, of
course.
We will calculate the total probability that one of the suspects is Fred.
"""
fred_prob_first = 1/(0.6 * population)
not_fred_prob_first = 1-fred_prob_first
fred_total_prob = fred_prob_first
# The probability that all previous suspects were not Fred. We will add to
# this list as we continue to calculate from N=3 to N=num_crime_scene
not_fred_lookup_table = [not_fred_prob_first, not_fred_prob_first]
# nth_person_at_scene is 0-based; starting at 2 since Fred can't be the
# second person given his blood type of O
for nth_person_at_scene in range(2, num_crime_scene):
not_fred_prev = not_fred_lookup_table[nth_person_at_scene - 1]
new_prob_fred = 1.0 / (population - nth_person_at_scene)
new_prob_not_fred = 1 - new_prob_fred
not_fred_lookup_table.append(not_fred_prev * new_prob_not_fred)
current_prob = not_fred_prev * new_prob_fred
fred_total_prob += current_prob
return fred_total_prob
def main():
"""
Let's compare likelihoods for Fred given fixed P = 100 and various N's
We can skip N=1 since there's no comparison for the blood type scenario
"""
print("p,n,prob_no_blood,prob_blood")
#num_crime_scene is 1-based
for num_crime_scene in range(2, POPULATION + 1):
prob_no_blood = prob_no_blood_type(POPULATION, num_crime_scene)
prob_blood = prob_blood_type(POPULATION, num_crime_scene)
if prob_blood > 1:
prob_blood = 1 #correct rounding error
print("{p},{n},{prob_no_blood},{prob_blood}".format(
p=POPULATION, n=num_crime_scene, prob_no_blood=prob_no_blood,
prob_blood=prob_blood))
if __name__ == '__main__':
main()
@kristovatlas
Copy link
Author

$ python3 evidence.py
p,n,prob_no_blood,prob_blood
100,2,0.02,0.016666666666666666
100,3,0.03,0.02670068027210884
100,4,0.04,0.03673469387755102
100,5,0.05,0.046768707482993194
100,6,0.06,0.05680272108843537
100,7,0.07,0.06683673469387755
100,8,0.08,0.07687074829931972
100,9,0.09,0.0869047619047619
100,10,0.1,0.09693877551020408
100,11,0.11,0.10697278911564626
100,12,0.12,0.11700680272108843
100,13,0.13,0.1270408163265306
100,14,0.14,0.13707482993197279
100,15,0.15,0.14710884353741496
100,16,0.16,0.15714285714285714
100,17,0.17,0.16717687074829932
100,18,0.18,0.1772108843537415
100,19,0.19,0.18724489795918367
100,20,0.2,0.19727891156462585
100,21,0.21,0.20731292517006802
100,22,0.22,0.2173469387755102
100,23,0.23,0.22738095238095238
100,24,0.24,0.23741496598639455
100,25,0.25,0.24744897959183673
100,26,0.26,0.2574829931972789
100,27,0.27,0.2675170068027211
100,28,0.28,0.2775510204081633
100,29,0.29,0.2875850340136055
100,30,0.3,0.2976190476190477
100,31,0.31,0.30765306122448993
100,32,0.32,0.31768707482993214
100,33,0.33,0.32772108843537434
100,34,0.34,0.33775510204081655
100,35,0.35,0.34778911564625875
100,36,0.36,0.35782312925170096
100,37,0.37,0.36785714285714316
100,38,0.38,0.37789115646258536
100,39,0.39,0.38792517006802757
100,40,0.4,0.3979591836734698
100,41,0.41,0.407993197278912
100,42,0.42,0.4180272108843542
100,43,0.43,0.4280612244897964
100,44,0.44,0.4380952380952386
100,45,0.45,0.4481292517006808
100,46,0.46,0.458163265306123
100,47,0.47,0.4681972789115652
100,48,0.48,0.4782312925170074
100,49,0.49,0.4882653061224496
100,50,0.5,0.4982993197278918
100,51,0.51,0.508333333333334
100,52,0.52,0.5183673469387762
100,53,0.53,0.5284013605442184
100,54,0.54,0.5384353741496606
100,55,0.55,0.5484693877551028
100,56,0.56,0.558503401360545
100,57,0.57,0.5685374149659872
100,58,0.58,0.5785714285714294
100,59,0.59,0.5886054421768716
100,60,0.6,0.5986394557823138
100,61,0.61,0.608673469387756
100,62,0.62,0.6187074829931982
100,63,0.63,0.6287414965986404
100,64,0.64,0.6387755102040826
100,65,0.65,0.6488095238095248
100,66,0.66,0.658843537414967
100,67,0.67,0.6688775510204092
100,68,0.68,0.6789115646258514
100,69,0.69,0.6889455782312937
100,70,0.7,0.6989795918367359
100,71,0.71,0.7090136054421781
100,72,0.72,0.7190476190476203
100,73,0.73,0.7290816326530625
100,74,0.74,0.7391156462585047
100,75,0.75,0.7491496598639469
100,76,0.76,0.7591836734693891
100,77,0.77,0.7692176870748313
100,78,0.78,0.7792517006802735
100,79,0.79,0.7892857142857157
100,80,0.8,0.7993197278911579
100,81,0.81,0.8093537414966001
100,82,0.82,0.8193877551020423
100,83,0.83,0.8294217687074845
100,84,0.84,0.8394557823129267
100,85,0.85,0.8494897959183689
100,86,0.86,0.8595238095238111
100,87,0.87,0.8695578231292533
100,88,0.88,0.8795918367346955
100,89,0.89,0.8896258503401377
100,90,0.9,0.89965986394558
100,91,0.91,0.9096938775510222
100,92,0.92,0.9197278911564644
100,93,0.93,0.9297619047619066
100,94,0.94,0.9397959183673488
100,95,0.95,0.949829931972791
100,96,0.96,0.9598639455782332
100,97,0.97,0.9698979591836754
100,98,0.98,0.9799319727891176
100,99,0.99,0.9899659863945598
100,100,1.0,1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment