瀏覽代碼

Update 'python/bayesian/Bayesian_Zahra.py'

Zahra Alirezaei 11 月之前
父節點
當前提交
5d0ff13302
共有 1 個文件被更改,包括 56 次插入69 次删除
  1. 56 69
      python/bayesian/Bayesian_Zahra.py

+ 56 - 69
python/bayesian/Bayesian_Zahra.py

@@ -280,78 +280,65 @@ plt.show()
 
 
 # 1- Delta-method 
-import numdifftools as nd  
-
-# wrap scalar objective for numdifftools
-def build_objective(X, y):
-    def f(phi):
-        return neg_post_phi_mono_WITH_CONST_REG(np.asarray(phi, float), X, y)
-    return f
-
-# compute Σ_φ (covariance in phi-space) at MAP using numdifftools.Hessian
-phi_hat = res.x.copy()                    # MAP in raw-phi space 
-f_obj = build_objective(X, y)             # scalar negative log-posterior
-H = nd.Hessian(f_obj, method='central')(phi_hat)
-Sigma_phi = invert_with_eigenfloor(H, floor=1e-6)
-
-
-# 95% Wald band via Delta method
-z = norm.ppf(0.975)  # 1.96 for 95%  ppf stands for percent point function — it’s the inverse CDF
-
+# ===== Delta band + compact summaries (minimal) =====
+import numpy as np
+import matplotlib.pyplot as plt
+import numdifftools as nd
+from scipy.stats import norm
 
-def g_px_at_x(x):
-    """Return g(φ) = P(AE | x, φ), so we can get ∇g(φ̂) via numdifftools.Gradient."""
-    #Build a scalar function g(φ) = P(AE | x, φ) for a fixed x.
-    #We return this function so numdifftools.Gradient can compute ∇g(φ̂).
-    def g(phi):
-        p, a, b, s, k, th = unpack_phi_mono(np.asarray(phi, float))
-        L = (np.log(p) - np.log(1 - p)) + dE_full(x, a, b, s, k, th)
-        return logistic(L)
-    return g
+# 1) Covariance in raw-phi space at MAP
+phi_hat   = res.x.copy()
+f_obj     = lambda phi: neg_post_phi_mono_WITH_CONST_REG(np.asarray(phi, float), X, y)
+H         = nd.Hessian(f_obj, method='central')(phi_hat)
+Sigma_phi = np.linalg.pinv(0.5*(H + H.T))  # robust inverse
 
-# x-grid
-x_lo = max(1e-6, float(X.min()) * 0.8)
-x_hi = min(10.0, float(X.max()) * 1.2)
-xg = np.linspace(x_lo, x_hi, 500)
+# 2) Delta band on P(AE|x) via numdifftools.Gradient
+x_lo = max(1e-6, float(X.min())*0.8)
+x_hi = min(10.0, float(X.max())*1.2)
+xg   = np.linspace(x_lo, x_hi, 500)
 
-p_hat = np.empty_like(xg)  # point estimate at MAP
-p_lo  = np.empty_like(xg)  # lower 95%
-p_hi  = np.empty_like(xg)  # upper 95%
+p_hat = np.empty_like(xg)
+p_lo  = np.empty_like(xg)
+p_hi  = np.empty_like(xg)
 
 for i, x in enumerate(xg):
-    gx = g_px_at_x(x)
-    # point estimate at MAP
-    ph = gx(phi_hat)
-    # gradient wrt φ at φ̂ via numdifftools.Gradient
-    grad = nd.Gradient(gx, method='central')(phi_hat)  # shape (d,)
-    # Delta-method variance on probability scale: var ≈ ∇g^T Σ_φ ∇g
-    var = float(grad @ Sigma_phi @ grad)
-    se  = np.sqrt(max(var, 0.0))
-
+    gx   = g_px(x)
+    ph   = gx(phi_hat)
+    grad = nd.Gradient(gx, method='central')(phi_hat)
+    var  = float(grad @ Sigma_phi @ grad)
+    se   = np.sqrt(max(var, 0.0))
     p_hat[i] = ph
-    p_lo[i]  = np.clip(ph - z * se, 0.0, 1.0)
-    p_hi[i]  = np.clip(ph + z * se, 0.0, 1.0)
-
-# plot
-fig, ax = plt.subplots(figsize=(7,4.5 ))
-
-# curve + band (sharp colors)
-ax.plot(xg, p_hat, color="#000000", lw=2.2, label='P(AE|x) at MAP')
-ax.fill_between(xg, p_lo, p_hi, facecolor="#1f77b4", alpha=0.18, label='95% Wald band (Delta)')
-ax.plot(xg, p_lo, color="#1f77b4")
-ax.plot(xg, p_hi, color="#1f77b4")
-
-# overlay data with tiny vertical jitter
-rng_plot = np.random.default_rng(999)
-jit = (rng_plot.random(len(X)) - 0.5) * 0.06
-ax.scatter(X[y==0], (y + jit)[y==0], s=22, alpha=0.55, color="#2ca02c", edgecolors='none', label='NC')
-ax.scatter(X[y==1], (y + jit)[y==1], s=26, alpha=0.75, color="#ff7f0e", edgecolors='none', label='AE')
-ax.set_ylim(-0.05, 1.05)
-ax.set_xlabel('x')
-ax.set_ylabel('P(AE | x)')
-ax.set_title('Delta–method band using numdifftools Hessian/Gradient')
-ax.grid(alpha=0.3)
-ax.legend(loc='lower right')
-plt.show()
-
-
+    p_lo[i]  = np.clip(ph - z*se, 0.0, 1.0)
+    p_hi[i]  = np.clip(ph + z*se, 0.0, 1.0)
+
+# 3) Plot
+fig, ax = plt.subplots(figsize=(7.2, 4.4), dpi=140)
+ax.plot(xg, p_hat, lw=2.0, label='P(AE|x) @ MAP')
+ax.fill_between(xg, p_lo, p_hi, alpha=0.20, label='95% Delta band')
+rngp = np.random.default_rng(999); jit = (rngp.random(len(X)) - 0.5) * 0.06
+ax.scatter(X[y==0], (y+jit)[y==0], s=22, alpha=0.55, edgecolors='none', label='NC')
+ax.scatter(X[y==1], (y+jit)[y==1], s=26, alpha=0.75, edgecolors='none', label='AE')
+ax.set_ylim(-0.05, 1.05); ax.set_xlabel('x'); ax.set_ylabel('P(AE | x)')
+ax.grid(alpha=0.3); ax.legend(loc='lower right')
+plt.tight_layout(); plt.show()
+
+
+
+w = p_hi - p_lo
+mask = (xg >= float(X.min())) & (xg <= float(X.max()))
+print("\nBand width (95% pointwise): "
+      f"overall mean {w.mean():.3f}, max {w.max():.3f}; "
+      f"in-range mean {w[mask].mean():.3f}, max {w[mask].max():.3f}")
+
+
+try:
+    G = lambda phi: np.array(unpack_phi_mono(np.asarray(phi, float)), float)  # -> [p,a,b,s,k,theta]
+    J = nd.Jacobian(G)(phi_hat)
+    Sigma_theta = J @ Sigma_phi @ J.T
+    se = np.sqrt(np.maximum(np.diag(Sigma_theta), 0.0))
+    theta_hat_vec = G(phi_hat); names = ["p","a","b","s","k","theta"]
+    print("\nParameter 95% CIs (Delta/Wald):")
+    for nm, v, svi in zip(names, theta_hat_vec, se):
+        print(f"  {nm:>6s} : {v:.6g}  [ {v - z*svi:.6g}, {v + z*svi:.6g} ]")
+except Exception as e:
+    print("(Parameter CI step skipped:", e, ")")