def left_side(a, b, c, d): num_steps = min(a, d) p_val = [] for i in range(num_steps): a -= 1 b += 1 c += 1 d -= 1 p_val.append(_hypergeom_distribution(a, b, c, d)) return p_val
def right_side(a, b, c, d): num_steps = min(b, c) p_val = [] for i in range(num_steps): a += 1 b -= 1 c -= 1 d += 1 p_val.append(_hypergeom_distribution(a, b, c, d)) return p_val
def test_hypergeom_Dict_Error(self): a, b, c, d = 10, 10, 10, {'d': 10} with pytest.raises(TypeError): utils._hypergeom_distribution(a, b, c, d)
def test_hypergeom_Float_Error(self): a, b, c, d = 10, 10, 10, 10.5 with pytest.raises(TypeError): utils._hypergeom_distribution(a, b, c, d)
def test_hypergeom_String_Error(self): a, b, c, d = 10, 10, 10, '10' with pytest.raises(TypeError): utils._hypergeom_distribution(a, b, c, d)
def test_hypergeom_Result(self): a, b, c, d = 1, 2, 3, 4 assert pytest.approx(0.5, 0.01) == utils._hypergeom_distribution( a, b, c, d)
def fisher_test(cont_table, alternative='two-sided'): """Found in scipy.stats as fisher_exact Used to determine the exact likelihood that we would observe a measurement in our 2x2 contingency table that is just as extreme, if not moreso, than our observed results. Parameters ---------- cont_table: list or numpy array, 2 x 2 A 2x2 contingency table alternative: str, {two-sided, greater, less}, default is two-sided Our alternative hypothesis Return ------ p: float, 0 <= p <= 1 The exact likelihood of finding a more extreme measurement than our observed data """ if alternative.casefold() not in ['two-sided', 'greater', 'less']: raise ValueError("Cannot determine method for alternative hypothesis") cont_table = _check_table(cont_table, True) if cont_table.shape != (2, 2): raise AttributeError( "Fisher's Exact Test is meant for a 2x2 contingency table") a, b, c, d = cont_table[0, 0], cont_table[0, 1], cont_table[1, 0], cont_table[1, 1] p = _hypergeom_distribution(a, b, c, d) # left side def left_side(a, b, c, d): num_steps = min(a, d) p_val = [] for i in range(num_steps): a -= 1 b += 1 c += 1 d -= 1 p_val.append(_hypergeom_distribution(a, b, c, d)) return p_val # right side def right_side(a, b, c, d): num_steps = min(b, c) p_val = [] for i in range(num_steps): a += 1 b -= 1 c -= 1 d += 1 p_val.append(_hypergeom_distribution(a, b, c, d)) return p_val if alternative.casefold() == 'greater': right_p_val = right_side(a, b, c, d) return p + np.sum(right_p_val) elif alternative.casefold() == 'less': left_p_val = left_side(a, b, c, d) return p + np.sum(left_p_val) else: left_p_val, right_p_val = left_side(a, b, c, d), right_side(a, b, c, d) all_p = right_p_val + left_p_val return p + np.sum([i for i in all_p if i <= p])