|
|
@@ -75,16 +75,21 @@ def logit_poly_fit(lm, x, y, degree = 1):
|
|
|
x: array of n floats
|
|
|
y: array of n int in {0,1}
|
|
|
b: array of r = degree+1 floats, model parameters
|
|
|
-
|
|
|
+ thresh: float, default 0.5, threshold value for classification
|
|
|
+
|
|
|
Return:
|
|
|
- {"n": n, "k":k, "dof":n-k, "LLF": log_likelihood, "AIC": AIC, "BIC": BIC}
|
|
|
+ {"n": n, "k":k, "dof":n-k,
|
|
|
+ "LLF": log_likelihood,
|
|
|
+ "AIC": AIC,
|
|
|
+ "BIC": BIC,
|
|
|
+ "A": classification accuracy (threshold values = 0.5 prob)}
|
|
|
|
|
|
Ref:
|
|
|
https://en.wikipedia.org/wiki/Logistic_regression
|
|
|
https://en.wikipedia.org/wiki/Akaike_information_criterion
|
|
|
https://www.medicine.mcgill.ca/epidemiology/joseph/courses/epib-621/logfit.pdf
|
|
|
"""
|
|
|
-def logit_poly_goodness_of_fit(x, y, b):
|
|
|
+def logit_poly_goodness_of_fit(x, y, b, thresh=0.5):
|
|
|
|
|
|
# model probabilities
|
|
|
p = logit_poly_model(x, b)
|
|
|
@@ -104,8 +109,12 @@ def logit_poly_goodness_of_fit(x, y, b):
|
|
|
chi2 = np.sum(r**2)
|
|
|
p_val = scipy.stats.chi2.sf(chi2, dof)
|
|
|
|
|
|
+ # using model as classifier
|
|
|
+ matches = y == np.heaviside(p - thresh, 1)
|
|
|
+
|
|
|
return {"LLF": llf, "AIC": AIC, "BIC": BIC,
|
|
|
- "chi2": chi2, "p-value(chi2)": p_val,
|
|
|
+ "A" : np.count_nonzero (matches)/n,
|
|
|
+ "chi2": chi2, "p-value(chi2)": p_val, # not very useful
|
|
|
"n": n, "k": k, "dof": dof}
|
|
|
|
|
|
"""
|
|
|
@@ -249,7 +258,10 @@ def logit_poly_model_quantiles_delta(x, probs, mean_b, cov):
|
|
|
|
|
|
"""
|
|
|
Generate m parameters via non-parametric bootstrapping with a minimal constraint
|
|
|
- that both groups should be present in the sampled data.
|
|
|
+ that both groups should be present in the sampled data:
|
|
|
+
|
|
|
+ boostrapped sample = (xb, yb) by sampling with replacement pairs (x_i, y_i)
|
|
|
+ with condition that yb can not be just 0 or just 1
|
|
|
|
|
|
Input:
|
|
|
lm: linear_model.LogisticRegression
|
|
|
@@ -289,7 +301,12 @@ def get_nonparam_boots_pars(lm, x, y, m, degree = 1, seed = 1977):
|
|
|
|
|
|
|
|
|
"""
|
|
|
- Generate m parameters via non-parametric stratified bootstrapping.
|
|
|
+ Generate m parameters via non-parametric stratified bootstrapping:
|
|
|
+
|
|
|
+ boostrapped sample = (xb, yb)
|
|
|
+
|
|
|
+ xb = (sampled with replacement from x0, sampled with replacement from x1)
|
|
|
+ yb = (0...0, 1...1)
|
|
|
|
|
|
Input:
|
|
|
lm: linear_model.LogisticRegression
|
|
|
@@ -327,7 +344,11 @@ def get_nonparam_stratified_boots_pars(lm, x, y, m, degree = 1, seed = 1977):
|
|
|
return np.array(lst)
|
|
|
|
|
|
"""
|
|
|
- Generate m parameters via parametric bootstrapping.
|
|
|
+ Generate m parameters via parametric bootstrapping:
|
|
|
+
|
|
|
+ boostrapped sample = (x, yb) yb ~ B(model(x, fitted pars))
|
|
|
+
|
|
|
+ where B is Bernoulli distribution
|
|
|
|
|
|
Input:
|
|
|
lm: linear_model.LogisticRegression
|
|
|
@@ -343,6 +364,7 @@ def get_nonparam_stratified_boots_pars(lm, x, y, m, degree = 1, seed = 1977):
|
|
|
Ref:
|
|
|
|
|
|
* https://www.scirp.org/journal/paperinformation?paperid=70962
|
|
|
+ * https://en.wikipedia.org/wiki/Bernoulli_distribution
|
|
|
"""
|
|
|
def get_parametric_boots_pars(lm, x, y, m, degree = 1, seed = 1977):
|
|
|
|