Skip to content

Commit 2f9f40a

Browse files
committed
[Reliability Bayesian pymc-devs#474] added bootstrap predictive distribution
Signed-off-by: Nathaniel <[email protected]>
1 parent e750fbd commit 2f9f40a

File tree

2 files changed

+539
-454
lines changed

2 files changed

+539
-454
lines changed

examples/case_studies/reliability_and_calibrated_prediction.ipynb

+490-437
Large diffs are not rendered by default.

myst_nbs/case_studies/reliability_and_calibrated_prediction.myst.md

+49-17
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import numpy as np
3434
import pandas as pd
3535
import pymc as pm
3636
37+
from joblib import Parallel, delayed
3738
from lifelines import KaplanMeierFitter, LogNormalFitter, WeibullFitter
3839
from lifelines.utils import survival_table_from_events
3940
from scipy.stats import binom, lognorm, norm, weibull_min
@@ -459,7 +460,54 @@ draws = pd.DataFrame(
459460
draws
460461
```
461462

462-
Next we'll plot the bootstrapped data and the two estimates of coverage we achieve conditional on the MLE fit.
463+
We can use these bootstrapped statistics to further calculate quantities of the predictive distribution.
464+
465+
```{code-cell} ipython3
466+
def ecdf(sample):
467+
468+
# convert sample to a numpy array, if it isn't already
469+
sample = np.atleast_1d(sample)
470+
471+
# find the unique values and their corresponding counts
472+
quantiles, counts = np.unique(sample, return_counts=True)
473+
474+
# take the cumulative sum of the counts and divide by the sample size to
475+
# get the cumulative probabilities between 0 and 1
476+
cumprob = np.cumsum(counts).astype(np.double) / sample.size
477+
478+
return quantiles, cumprob
479+
480+
481+
fig, axs = plt.subplots(1, 2, figsize=(20, 6))
482+
axs = axs.flatten()
483+
ax = axs[0]
484+
ax1 = axs[1]
485+
hist_data = []
486+
for i in range(1000):
487+
samples = lognorm(s=draws.iloc[i]["Sigma"], scale=np.exp(draws.iloc[i]["Mu"])).rvs(1000)
488+
qe, pe = ecdf(samples)
489+
ax.plot(qe, pe, color="grey", alpha=0.2)
490+
lkup = dict(zip(pe, qe))
491+
hist_data.append([lkup[0.05]])
492+
hist_data = pd.DataFrame(hist_data, columns=["p05"])
493+
samples = lognorm(s=draws["Sigma"].mean(), scale=np.exp(draws["Mu"].mean())).rvs(1000)
494+
qe, pe = ecdf(samples)
495+
ax.plot(qe, pe, color="red", label="Expected CDF for Shock Absorbers Data")
496+
ax.set_xlim(0, 30_000)
497+
ax.set_title("Bootstrapped CDF functions for the Shock Absorbers Data", fontsize=20)
498+
ax1.hist(hist_data["p05"], color="slateblue", ec="black", alpha=0.4, bins=30)
499+
ax1.set_title("Estimate of Uncertainty in the 5% Failure Time", fontsize=20)
500+
ax1.axvline(
501+
hist_data["p05"].quantile(0.025), color="cyan", label="Lower Bound PI for 5% failure time"
502+
)
503+
ax1.axvline(
504+
hist_data["p05"].quantile(0.975), color="cyan", label="Upper Bound PI for 5% failure time"
505+
)
506+
ax1.legend()
507+
ax.legend();
508+
```
509+
510+
Next we'll plot the bootstrapped data and the two estimates of coverage we achieve conditional on the MLE fit. In other words when we want to assess the coverage of a prediction interval based on our MLE fit we can also bootstrap an estimate for this quantity.
463511

464512
```{code-cell} ipython3
465513
mosaic = """AABB
@@ -876,22 +924,6 @@ az.plot_trace(idata, kind="rank_vlines");
876924
az.summary(idata)
877925
```
878926

879-
```{code-cell} ipython3
880-
def ecdf(sample):
881-
882-
# convert sample to a numpy array, if it isn't already
883-
sample = np.atleast_1d(sample)
884-
885-
# find the unique values and their corresponding counts
886-
quantiles, counts = np.unique(sample, return_counts=True)
887-
888-
# take the cumulative sum of the counts and divide by the sample size to
889-
# get the cumulative probabilities between 0 and 1
890-
cumprob = np.cumsum(counts).astype(np.double) / sample.size
891-
892-
return quantiles, cumprob
893-
```
894-
895927
```{code-cell} ipython3
896928
joint_draws = az.extract_dataset(idata, group="posterior", num_samples=1000)[
897929
["alpha", "beta"]

0 commit comments

Comments
 (0)