def gaussian_case(sig): sample_size = 200 count_error = math.sqrt(sample_size) m1 = 1 m2 = 2 s1 = generate_sample(sample_size, m1, sig) s2 = generate_sample(sample_size, m2, sig) h_testing = Hedges_d(s1, s2) h_testing.hedges_d_unbiased() #answer is in self.d approx_95CI_lower, approx_95CI_upper = h_testing.approx_CI() bs_95CI_lower, bs_95CI_upper = h_testing.bootstrap_CI(5000) print(mean_SD(s1), mean_SD(s2)) print("h_testing.d, analytic, correction = ", h_testing.d, (m2 - m1) / sig, h_testing.correction) print("lower: approx, bootstrap", approx_95CI_lower, bs_95CI_lower) print("upper: approx, bootstrap", approx_95CI_upper, bs_95CI_upper) #bootstrap is similar at high d but gives wider intervals at low d assert close_enough(approx_95CI_lower, bs_95CI_lower, count_error) assert close_enough(approx_95CI_upper, bs_95CI_upper, count_error) assert close_enough(h_testing.d, (m2 - m1) / sig, count_error)
def bootstrap_CI(self, repeats, bCA=False): # repeats is the number of times that it is repeated. # bCA: bias-corrected and accelerated - recommended to improve pctile coverage # bCA not implemented yet random.seed(1984) hedges_d_bs = [] #unbiased, values from bootstrap n1m = len(self.s1) - 1 #we only use these below - simplifies n2m = len(self.s2) - 1 correction = 1.0 - 3.0 / (4 * (n1m + n2m) - 1) for n in range(repeats): # bootstrap # RL 31/03/19 removed call to local bootstrap function (redundant) #br1 = bootstrap(self.s1) br1 = random.choices(self.s1, k=len(self.s1)) #br2 = bootstrap(self.s2) br2 = random.choices(self.s2, k=len(self.s2)) #means and SDs of bootstrap sampled distributions mbr1, sbr1 = mean_SD(br1) mbr2, sbr2 = mean_SD(br2) #need to call a function for Hedges_d that returns a value, not storing it #current alternative, just include here, it is so simple. s_pooled = math.sqrt((n2m * sbr2**2 + n1m * sbr1**2) / (n1m + n2m)) #Hedges' g # RL: quick fix (probably not very meaningful) for a case of a sample with two measurments only if s_pooled == 0.0: biased_d = 0.0 else: biased_d = (mbr2 - mbr1) / s_pooled # correction has no influence on the bootstrap distribution # so apply it later to save multiplications hedges_d_bs.append(biased_d) hedges_d_bs.sort() # put the values into rank order self.lower95CI = hedges_d_bs[int(0.025 * repeats)] * correction self.upper95CI = hedges_d_bs[int(0.975 * repeats)] * correction return (self.lower95CI, self.upper95CI)
def hedges_d_unbiased(self): #d_unbiased = d_biased [ 1 - 3/ (4 * ( n1 + n2 - 2)-1)] #from Nakagawa and Cuthill (2007) Biol. Rev. #count each time to make formulas easier to read n1 = len(self.s1) n2 = len(self.s2) #means and standard deviations m1, s1 = mean_SD(self.s1) m2, s2 = mean_SD(self.s2) #pooled variance s_pooled = math.sqrt( ((n2 - 1) * s2**2 + (n1 - 1) * s1**2) / (n1 + n2 - 2)) #Hedges' g biased_d = (m2 - m1) / s_pooled self.correction = 1.0 - 3.0 / (4 * (n1 + n2 - 2) - 1) #store answer self.d = biased_d * self.correction
def bootstrap_CI(self, repeats, bCA=False): # repeats is the number of times that it is repeated. # bCA: bias-corrected and accelerated - recommended to improve pctile coverage # bCA not implemented yet hedges_d_bs = [] #unbiased, values from bootstrap n1m = len(self.s1) - 1 #we only use these below - simplifies n2m = len(self.s2) - 1 correction = 1.0 - 3.0 / (4 * (n1m + n2m) - 1) for n in range(repeats): br1 = bootstrap(self.s1) br2 = bootstrap(self.s2) #means and SDs of bootstrap sampled distributions mbr1, sbr1 = mean_SD(br1) mbr2, sbr2 = mean_SD(br2) #need to call a function for Hedges_d that returns a value, not storing it #current alternative, just include here, it is so simple. s_pooled = math.sqrt((n2m * sbr2**2 + n1m * sbr1**2) / (n1m + n2m)) #Hedges' g biased_d = (mbr2 - mbr1) / s_pooled # correction has no influence on the bootstrap distribution # so apply it later to save multiplications hedges_d_bs.append(biased_d) hedges_d_bs.sort() # put the values into rank order self.lower95CI = hedges_d_bs[int(0.025 * repeats)] * correction self.upper95CI = hedges_d_bs[int(0.975 * repeats)] * correction return (self.lower95CI, self.upper95CI)