Created
January 23, 2012 22:41
-
-
Save puterleat/1665911 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import division | |
import itertools | |
from scipy import stats | |
import numpy as np | |
from collections import Counter | |
# Define some functions to use later | |
def form_lineup(delta, foils, felons): | |
foils = [i for i in stats.norm.rvs(loc=0, scale=1, size=foils)] | |
if felons > 0: | |
felons = [i for i in stats.norm.rvs(loc=delta, scale=1, size=felons)] | |
else: | |
felons = [] | |
return foils, felons | |
def worst_is_a_felon(lineup): | |
foils, felons = lineup | |
if len(felons)==0: | |
return False | |
return bool(max(felons) > max(foils)) | |
def punters_worst_first(lineup): | |
all = list(itertools.chain(*lineup)) | |
all.sort() | |
all.reverse() | |
return all | |
def worst_meets_criterion(lineup, criterion): | |
all = punters_worst_first(lineup) | |
return bool(all[0] > criterion) | |
def exceeds_margin(lineup, margin): | |
all = punters_worst_first(lineup) | |
return bool(all[0] - all[1] > margin) | |
def beats_average_by(lineup, margin): | |
all = punters_worst_first(lineup) | |
worst = all[0] | |
rest = all[1:] | |
av_rest = np.average(rest) | |
return bool(worst - av_rest > margin) | |
def categorise_lineup(lineup, criterion, win_function, margin): | |
a = worst_meets_criterion(lineup, criterion) and win_function(lineup, margin) | |
b = worst_is_a_felon(lineup) | |
if a and b: | |
return 'hit' | |
if a: | |
return 'false_alarm' | |
# DEFINE SOME PARAMETERS | |
criterion = 1.5 | |
delta = 3 | |
nfelons = 1 | |
nfoils = 5 | |
reps = 1000 | |
prob_felon = .5 | |
prob_no_felon = 1 - prob_felon | |
win_function = exceeds_margin # this might seem odd, but you choose the function to apply by assigning it to this variable | |
# GENERATE SOME LINEUPS | |
lineups_with_felons = [form_lineup(delta=delta, foils=nfoils, felons=nfelons) for i in range(0, int(reps * prob_felon))] | |
lineups_without = [form_lineup(delta=delta, foils=nfoils+nfelons, felons=0) for i in range(0, int(reps * prob_no_felon))] | |
lineups = list(itertools.chain(lineups_with_felons, lineups_without)) | |
# SIMULATE AT DIFFERENT VALUES OF MARGIN | |
for margin in [x * 0.3 for x in range(0, 10)]: | |
c = Counter([categorise_lineup(i, criterion, win_function, margin) for i in lineups]) | |
n = len(lineups) | |
phit = c['hit']/n | |
pfa = c['false_alarm']/n | |
dprime=stats.norm.ppf(phit) - stats.norm.ppf(pfa) # norm.ppf is NORMSINV in excel | |
print "margin: %g \t phit: %g \t pfa: %g \t dprime: %g" % (margin, phit, pfa, dprime) | |
# outputs: | |
# margin: 0 phit: 0.463 pfa: 0.181 dprime: 0.818682 | |
# margin: 0.3 phit: 0.455 pfa: 0.157 dprime: 0.893826 | |
# margin: 0.6 phit: 0.438 pfa: 0.123 dprime: 1.00408 | |
# margin: 0.9 phit: 0.412 pfa: 0.078 dprime: 1.19625 | |
# margin: 1.2 phit: 0.369 pfa: 0.045 dprime: 1.36089 | |
# margin: 1.5 phit: 0.322 pfa: 0.023 dprime: 1.53328 | |
# margin: 1.8 phit: 0.27 pfa: 0.015 dprime: 1.55728 | |
# margin: 2.1 phit: 0.215 pfa: 0.007 dprime: 1.66807 | |
# margin: 2.4 phit: 0.17 pfa: 0.003 dprime: 1.79362 | |
# margin: 2.7 phit: 0.126 pfa: 0.002 dprime: 1.73266 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment