Przeglądaj źródła

Updating logit reg

Martin Horvat 1 rok temu
rodzic
commit
425e1b0900

Plik diff jest za duży
+ 0 - 449
python/bayesian/bayesian_box-cox.ipynb


Plik diff jest za duży
+ 0 - 514
python/bayesian/bayesian_bygroup.ipynb


Plik diff jest za duży
+ 0 - 477
python/bayesian/bayesian_experimental.ipynb


Plik diff jest za duży
+ 0 - 494
python/bayesian/bayesian_full.ipynb


Plik diff jest za duży
+ 0 - 477
python/bayesian/bayesian_full_stratified-boots.ipynb


Plik diff jest za duży
+ 0 - 270
python/bayesian/bayesian_truncated-gauss.ipynb


Plik diff jest za duży
+ 102 - 89
python/logistic/logit_reg_boots.ipynb


+ 13 - 11
python/logistic/logit_reg_fit.ipynb

@@ -50,7 +50,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 2,
    "id": "3373f87f",
    "metadata": {
     "tags": []
@@ -85,7 +85,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 4,
    "id": "4a292c31",
    "metadata": {},
    "outputs": [],
@@ -162,12 +162,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 7,
    "id": "2359d3c1",
    "metadata": {},
    "outputs": [],
    "source": [
-    "# defining two-sided probabilities\n",
+    "# defining two-sided confidence intervals\n",
     "alpha = 0.05   # significance level\n",
     "probs = [alpha/2, 1 - alpha/2]"
    ]
@@ -227,7 +227,7 @@
          "type": "float"
         }
        ],
-       "ref": "d9c9eca7-061a-487e-9747-84deba04ae74",
+       "ref": "f3aae3c6-f11a-4234-ad63-287af6c89f82",
        "rows": [
         [
          "('plain', 'b0')",
@@ -345,7 +345,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 10,
    "id": "6ef6f46b",
    "metadata": {},
    "outputs": [
@@ -399,7 +399,7 @@
          "type": "integer"
         }
        ],
-       "ref": "0d9fc1bb-6946-43b1-bbab-42dc66fae2da",
+       "ref": "8909e19f-16bf-4243-ba9e-06e829111097",
        "rows": [
         [
          "plain",
@@ -516,7 +516,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 11,
    "id": "54f463d0",
    "metadata": {
     "tags": []
@@ -555,15 +555,17 @@
     "    # plotting fitted model \n",
     "    xp = np.linspace(min(x), max(x), 100)\n",
     "    yp = logit_utils.logit_poly_model(xp, pars)\n",
+    "\n",
     "    ax.plot(xp, yp, label = \"logistic reg\")\n",
     "\n",
     "    for lab, c in zip([\"normal\", \"delta\"], [\"red\", \"green\"]):\n",
     "        \n",
     "        # define quantile model\n",
-    "        qm = eval(f\"logit_utils.logit_poly_model_quantiles_{lab}\")\n",
+    "        fname = f\"logit_utils.logit_poly_model_quantiles_{lab}\"\n",
     "        \n",
-    "        # get result of model quantiles\n",
-    "        res = qm(xp, probs, pars, cov_pars)\n",
+    "        # get result of model quantiles at probs\n",
+    "        # pars and cov_pars are obtained via MLE method\n",
+    "        res = eval(fname)(xp, probs, pars, cov_pars)\n",
     "\n",
     "        # make plot of quantiles\n",
     "        ax.fill_between(xp, *res, color = c, alpha = 0.5, label = f\"CI:{lab}\")\n",

+ 129 - 4
python/logistic/logit_utils.py

@@ -2,7 +2,6 @@ import numpy as np
 import scipy
 import scipy.stats
 
-
 """
     Model function 
 
@@ -178,6 +177,8 @@ def logit_poly_pars_quantiles_normal(probs, mean_b, cov):
 
         b ~ N(mean_b, cov)
     
+    This distribution is asymptotic MLE distribution of parameters.
+
     Input:
         x: array of n float
         probs: array of m floats, probabilities
@@ -212,13 +213,14 @@ def logit_poly_model_quantiles_normal(x, probs, mean_b, cov):
         F(x|b) = sum_{i=0}^degree x^i b_i
     
     at given probabilities p and values x assuming 
-    normal distribution of parameters:
+    normal distribution of parameters :
 
         b ~ N(mean_b, cov)
 
+    This distribution is asymptotic MLE distribution of parameters.
     We approximate exact model with linear expansion
 
-        p(x|b) = p(x|b_mean) + dp/db (x| b_mean) (b - b_mean)
+        p(x|b) = p(x|b_mean) + dp/db(x| b_mean) (b - b_mean)
     
     and the last term is normally distributed.
 
@@ -242,4 +244,127 @@ def logit_poly_model_quantiles_delta(x, probs, mean_b, cov):
     # computing quantiles of logit
     Q = locs + np.outer(scipy.stats.norm.ppf(probs), scales)
 
-    return np.clip(Q, a_min = 0, a_max = 1)
+    return np.clip(Q, a_min = 0, a_max = 1)
+
+
+"""
+    Generate m parameters via non-parametric bootstrapping with a minimal constraint 
+    that both groups should be present in the sampled data.
+
+     Input:
+        lm: linear_model.LogisticRegression
+        x : array of n floats
+        y : array of n int in {0,1}
+        m: integer, number of samples
+        degree: int,  degree of decision function
+        seed : int, seed for the random generator
+    
+    Return:
+        array of mx(degree + 1)
+    
+    Return:
+        array of mx(degree + 1)
+"""
+def get_nonparam_boots_pars(lm, x, y, m, degree = 1, seed = 1977):
+
+    rng = np.random.default_rng(seed)
+    
+    # fitting original data
+    pars = logit_poly_fit(lm, x, y, degree = degree)
+    
+    n = len(x)
+
+    # generate parameters
+    lst = [pars]
+    while True:
+
+        # create set indices for sampling with replacement + constraint
+        idx = rng.choice(n, n)
+        if np.sum(y[idx]) in [0, n]: continue
+
+        lst.append(logit_poly_fit(lm, x[idx], y[idx], degree=degree))
+        if len(lst) == m: break
+
+    return np.array(lst)
+
+
+"""
+    Generate m parameters via non-parametric stratified bootstrapping.
+
+    Input: 
+        lm: linear_model.LogisticRegression
+        x : array of n floats
+        y : array of n int in {0,1}
+        m: integer, number of samples
+        degree: int,  degree of decision function
+        seed : int, seed for the random generator
+    
+    Return:
+        array of mx(degree + 1)
+"""
+def get_nonparam_stratified_boots_pars(lm, x, y, m, degree = 1, seed = 1977):
+
+    rng = np.random.default_rng(seed)
+
+    # pars of original data
+    pars = logit_poly_fit(lm, x, y, degree = degree)
+    
+    # statistics about groups
+    xs = [x[y == i] for i in range(2)]
+    ns = [len(e) for e in xs]
+
+    # common vector states
+    yb = np.concatenate([np.full(ns[i], i) for i in range(2)])
+
+    # generate parameters
+    lst = [pars]
+    for _ in range(m):
+        # stratified sampling with replacement
+        xb = np.concatenate([rng.choice(xs[i], ns[i]) for i in range(2)])
+        # do fitting
+        lst.append(logit_poly_fit(lm, xb, yb, degree = degree))
+
+    return np.array(lst)
+
+"""
+    Generate m parameters via parametric bootstrapping.
+
+    Input: 
+        lm: linear_model.LogisticRegression
+        x : array of n floats
+        y : array of n int in {0,1}
+        m: integer, number of samples
+        degree: int,  degree of decision function
+        seed : int, seed for the random generator
+
+    Return:
+        array of mx(degree + 1)
+
+    Ref:
+
+      * https://www.scirp.org/journal/paperinformation?paperid=70962
+"""
+def get_parametric_boots_pars(lm, x, y, m, degree = 1, seed = 1977):
+
+    # first discuss original dataset
+    pars = logit_poly_fit(lm, x, y, degree = degree)
+    p = logit_poly_model(x, pars)
+
+    rng = np.random.default_rng(seed)
+
+    n = len(x)
+
+    # generate parameters
+    lst = [pars]
+    while True:
+
+        # Generate new binary outcomes from Bernoulli(p_i)
+        y_sim = np.random.binomial(n = 1, p = p)
+
+        if np.sum(y_sim) in [0, n]: continue
+        
+        lst.append(logit_poly_fit(lm, x, y_sim, degree = degree))
+
+        if len(lst) == m: break
+
+    return np.array(lst)

BIN
python/logistic/results/logit_fit.pdf → python/logistic/results/logit_cmp_CI.pdf


BIN
python/logistic/results/logit_nonpar_boots.pdf


BIN
python/logistic/results/logit_nonpar_boots_sel.pdf


BIN
python/logistic/results/logit_nonpar_boots_strat.pdf


BIN
python/logistic/results/logit_nonpar_boots_strat_sel.pdf


BIN
python/logistic/results/logit_nonpar_boots_zoom.pdf


BIN
python/logistic/results/logit_nonpar_strat_boots.pdf


BIN
python/logistic/results/logit_nonpar_strat_boots_sel.pdf


BIN
python/logistic/results/logit_param_boots.pdf


BIN
python/logistic/results/logit_param_boots_sel.pdf


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików