Introduction

In January 1986, the space shuttle Challenger exploded shortly after launch. An investigation was launched into the cause of the crash and attention focused on the rubber 0-ring seals in the rocket boosters. At lower temperatures, rubber becomes more brittle and is a less effective sealant. At the time of the launch, the temperature was 31F. Could the failure of the 0-rings have been predicted? In the 23 previous shuttle missions for which data exists, some evidence of damage due to blow by and erosion was recorded on some 0-rings. Each shuttle had two boosters, each with three 0-rings. For each mission, we know the number of 0-rings out of six showing some damage and the launch temperature.

Model 1: \(P(t)= \Phi{(\beta_0+\beta_1t, 1)}\)
Model 2: \(P(t)= \Phi{(\beta_0+\beta_1t+\beta_2t^2, 1)}\)

Data We were Given

temp (t) number damaged (d) number exposed temp (t) number damaged (d) number exposed
53 5 6 70 1 6
57 1 6 70 0 6
58 1 6 72 0 6
63 1 6 73 0 6
66 0 6 75 0 6
67 0 6 75 1 6
67 0 6 76 0 6
67 0 6 76 0 6
68 0 6 78 0 6
69 0 6 79 0 6
70 1 6 81 0 6
70 0 6

Presentation Outline

  1. Theory
  2. Model 1: Beta
  3. Model 1: Latent Variables
  4. Model 2: Beta
  5. Model 2: Latent Variables
  6. Plots
  7. Conclusion

Theory

  • Let \(Y_1,\ldots,Y_N\) be independent Binary random variables, with \(Y_i|p_i\ \sim Bernoulli(p_i)\) and \(p_i\ =\ F({\underline{x}}_i^\prime,\ \underline{\beta}), i=1,\ldots,N\), where F is a known distribution function.

  • Let us consider \(F=\Phi\)=Standard normal c.d.f. That is, \(F(x)=\frac{1}{\sqrt{2\pi}}\int_{-\infty}^{x}e^{\frac{-u^2}{2}}du\) and
    \(f(x)=\frac{d}{dx}(F(x))=\frac{e^{\frac{-x^2}{2}}}{\sqrt{2\pi}}\) = standard normal density function.

  • \(\underline{\beta_{p*1}}\ \epsilon\ \mathbb{R}^p\) is a vector of unknown parapters.

Theory Cont.

  • Since \(Y_1,\ldots,Y_N\) are independent Bernoulli randonm variables, the joint probability function of \(Y_1,\ldots,Y_N|\underline{\beta}\) is given by \(f(\underline{y}|\underline{\beta})=\prod^{N}_{i=1} {F({x}_i^\prime \beta)^{y_{i}}}(1-F({x}_i^\prime \beta)^{1-y_{i}}\)

  • Let \(\tau(\underline{\beta})\) be a prior density on \(\underline{\beta}\)
  • Then the posterior density of \(\underline{\beta}\) is given by \(\tau(\underline{\beta}|\underline{y})=\frac{\prod^{N}_{i=1}f(\underline{y}|\underline{\beta})\tau(\beta)}{\int_{\mathbb{R}^p}{\prod^{N}_{i=1}f(\underline{y}|\underline{\upsilon })\tau(u)}du}\) where \(F=\Phi\)

Theory Cont.

  • \(Z_1,\ldots,Z_N \sim N(\underline{{x}_i^\prime}\underline{\beta},1)\)

  • \(Z_i\) has distribution function \(\Phi(\underline{{x}_i^\prime}\underline{\beta})\)

Fully Conditional Posterior Density: \[\tau(\underline{\beta}|\underline{Z},\underline{y})\alpha \prod^{N}_{i=1}{[I(Z_{i}>0,y_{i}=1)+I(Z_{i}\leq0,y_{i}=0)}]*e^{\frac{-(Z_{i}-\underline{{x}_i^\prime}\underline{\beta})^2}{2}}*\tau(\beta)\]

Theory Cont.

Let \(\hat{\beta_{z}}\) be equal to \((x' x)x' z\) and an unbiased estimator for \(\beta\)

\((z-x\beta)'(z-x\beta)\)=

\([(z-x\hat{\beta_{z}})+(x\hat{\beta_{z}}-x\beta)]'*[(z-x\hat{\beta_{z}})+(x\hat{\beta_{z}}-x\beta)]\)=

\((z-x\hat{\beta_{z}})'(z-x\hat{\beta_{z}})\)+ \((z-x\hat{\beta_{z}})'(x\hat{\beta_{z}}-x\beta)\)+
\((x\hat{\beta_{z}}-x\beta)'(z-x\hat{\beta_{z}})\)+ \((x\hat{\beta_{z}}-x\beta)'(x\hat{\beta_{z}}-x\beta)\)

Because \(\hat{\beta_{z}}\) is unbiased, terms that include \((x\hat{\beta_{z}}-x\beta)\) will equal zero
\((z-x\beta)'(z-x\beta)\)= \((z-x\hat{\beta_{z}})'(z-x\hat{\beta_{z}})\)+ \((\beta-\hat{\beta_{z}})x' x(\beta-\hat{\beta_{z}})\)

Because the first term doesn’t depend on \(\beta\), we can drop it.

What we know so far

Model 1: \(P(t)= \Phi{(\beta_0+\beta_1t, 1)}\)
Model 2: \(P(t)= \Phi{(\beta_0+\beta_1t+\beta_2t^2, 1)}\)

Model 1: \(\underline{\beta} \sim \mathcal{N}(\underline{\widehat\beta_z},\,(X'X)^{-1})\) with \(\underline{\beta}=\begin{bmatrix}\beta_0\\\beta_1\end{bmatrix}\), \(\widehat{\underline{\beta_z}}=(X'X)^{-1}X'\underline{Z}\)

\(\underline{Z_i} \sim \mathcal{N}(\underline{x_i'} \underline{\beta},\,1)\)

Model 2: \(\underline{\beta} \sim \mathcal{N}(\underline{\widehat\beta_z},\,(X'X)^{-1})\) with \(\underline{\beta}=\begin{bmatrix}\beta_0\\\beta_1\\\beta_2\end{bmatrix}\), \(\widehat{\underline{\beta_z}}=(X'X)^{-1}X'\underline{Z}\)

\(\underline{Z} \sim \mathcal{N}(\underline{x_i'} \underline{\beta},\,1)\)

Data We were Given

temp (t) number damaged (d) number exposed temp (t) number damaged (d) number exposed
53 5 6 70 1 6
57 1 6 70 0 6
58 1 6 72 0 6
63 1 6 73 0 6
66 0 6 75 0 6
67 0 6 75 1 6
67 0 6 76 0 6
67 0 6 76 0 6
68 0 6 78 0 6
69 0 6 79 0 6
70 1 6 81 0 6
70 0 6

Converting the Data to a Binary Form

Data in Binary Form
temperature affected
53 1
53 1
53 1
53 1
53 1
53 0
57 1
57 0
57 0
57 0

Model 1: Code

y <- dat$affected # Binary list of damaged/not danaged
n_obs <- length(y)
# Model 1 X Matrix
X <- cbind(rep(1, n_obs), dat$temperature)

burn_in <- 50000
n_iter <- 90000

XtX <- t(X) %*% X
XtXi <- solve(XtX)

n_params <- 2
z0 <- rnorm(n=n_obs, mean=0, sd=1) # Random  init z
beta_hat <- solve(XtX) %*% t(X) %*% z0

Model 1: Code Cont.

# Matrices to use later
beta_out <- matrix(data = NA, 
                   nrow = n_iter, ncol = n_params)

zed_out <- matrix(data = NA, 
                  nrow = n_iter, ncol = 138)

meanz_out <- matrix(data= NA, nrow= n_iter, ncol= 138)

zed <- vector(length=138)

# Values needed for rtruncnorm function
ones <- matrix(data = 1, nrow = 1, ncol = 138)
num_ones <- sum(dat$affected)
num_zeroes <- length(dat$affected[dat$affected == 0])

Model 1: For-loop

for (i in (1:n_iter)) {
  beta <- mvrnorm(n = 1, mu = beta_hat, XtXi)
  zed[y == 0] <- rtruncnorm(n=num_zeroes, 
                            mean = X[y ==0,] %*% beta, 
                            sd = 1, a = -Inf, b = 0)
  
  zed[y == 1] <- rtruncnorm(n=num_ones, 
                            mean = X[y == 1,] %*% beta, 
                            sd = 1, a = 0, b = Inf)
  # Update our beta_hat based off previous iteration
  beta_hat <- solve(XtX) %*% t(X) %*% zed
  # Outputs
  beta_out[i, ] <- beta
  zed_out[i, ] <- zed
  meanz_out[i,] <- X %*% beta
}

Model 1: Plot for \(\beta_0\)

Model 1: Plot for \(\beta_1\)

Model 1: Finding Mean

n_samples <- 2000
mean_beta1=0
mean_beta2=0
for (h in (1:n_samples)) {
  mean_beta1 <- mean_beta1 + beta_out[burn_in+(20*h),1]
  mean_beta2 <- mean_beta2 + beta_out[burn_in+(20*h),2]
}

mean_b1 <- mean_beta1/n_samples
mean_b2 <- mean_beta2/n_samples

Model 1: The Mean for the distribution \(\underline{\beta}\)

5.7814351
-0.1091448

Model 1: The Covariance matrix for \(\underline{\beta}\)

0.7433862 -0.0105820
-0.0105820 0.0001521

Model 1: MLE for \(\underline{\beta}\)

x
(Intercept) 5.591464
temperature -0.105804

Meanz_out

# Matrices to use later
beta_out <- matrix(data = NA, 
                   nrow = n_iter, ncol = n_params)

zed_out <- matrix(data = NA, 
                  nrow = n_iter, ncol = 138)

meanz_out <- matrix(data= NA, nrow= n_iter, ncol= 138)

zed <- vector(length=138)

# Values needed for rtruncnorm function
ones <- matrix(data = 1, nrow = 1, ncol = 138)
num_ones <- sum(dat$affected)
num_zeroes <- length(dat$affected[dat$affected == 0])

Model 1: For-loop

for (i in (1:n_iter)) {
  beta <- mvrnorm(n = 1, mu = beta_hat, XtXi)
  zed[y == 0] <- rtruncnorm(n=num_zeroes, 
                            mean = X[y ==0,] %*% beta, 
                            sd = 1, a = -Inf, b = 0)
  
  zed[y == 1] <- rtruncnorm(n=num_ones, 
                            mean = X[y == 1,] %*% beta, 
                            sd = 1, a = 0, b = Inf)
  # Update our beta_hat based off previous iteration
  beta_hat <- solve(XtX) %*% t(X) %*% zed
  # Outputs
  beta_out[i, ] <- beta
  zed_out[i, ] <- zed
  meanz_out[i,] <- X %*% beta
}

Model 1: Mean of Latent Variables (13)

Model 1: Mean of Latent Variables (101)

Model 1: The Mean of the Latent Variables

mean_z <- rep(0,138)
for(h in (1:n_samples)){
  for(i in (1:138)) {
    mean_z[i] <- mean_z[i] + 
      meanz_out[burn_in+(20*h),i]
  }
}
mean_z <- mean_z/n_samples

Model 1: Mean of the Latent Variables

## Warning in kable_pipe(x = structure(c("-0.0032383", "-0.4398175",
## "-0.5489622", : The table should have a header (column names)
-0.0032383 -1.858700
-0.4398175 -1.858700
-0.5489622 -1.858700
-1.0946861 -2.076989
-1.4221205 -2.186134
-1.5312653 -2.404424
-1.5312653 -2.404424
-1.5312653 -2.513568
-1.6404101 -2.513568
-1.7495548 -2.731858
-1.8586996 -2.841003

Model 2: Code

y <- dat$affected # Binary list of damaged/not damaged
n_obs <- length(y)

# Model 2 X Matrix
X <- cbind(rep(1, n_obs), dat$temperature, 
           (dat$temperature)^2)

XtX <- t(X) %*% X
XtXi <- solve(XtX)

n_params <- 3

z0 <- rnorm(n=n_obs, mean=0, sd=1) # Random init z
beta_hat <- solve(XtX) %*% t(X) %*% z0

Model 2: Code Cont.

# Matrices to use later
beta_out <- matrix(data = NA, nrow = n_iter, 
                   ncol = n_params)

zed_out <- matrix(data = NA, nrow = n_iter,
                  ncol = 138)

meanz_out <- matrix(data = NA, nrow = n_iter, 
                    ncol = 138)
zed <- vector(length=138)

# Values needed for rtruncnorm function
ones <- matrix(data = 1, nrow = 1, ncol = 138)
num_ones <- sum(dat$affected)
num_zeroes <- length(dat$affected[dat$affected == 0])

Model 2: For-loop

for (i in (1:n_iter)) {
  beta <- mvrnorm(n = 1, mu = beta_hat, XtXi)
  zed[y == 0] <- rtruncnorm(n=num_zeroes, 
                            mean = X[y ==0,] %*% beta,
                            sd = 1, a = -Inf, b = 0)
  
  zed[y == 1] <- rtruncnorm(n=num_ones, 
                            mean = X[y == 1,] %*% beta, 
                            sd = 1, a = 0, b = Inf)
  # Update out beta_hat based off previous iteration
  beta_hat <- solve(XtX) %*% t(X) %*% zed
  # Outputs
  beta_out[i, ] <- beta
  zed_out[i, ] <- zed
  meanz_out[i,] <- X %*% beta
}

Model 2: Plot for \(\beta_0\)

Model 2: Plot for \(\beta_1\)

Model 2:Plot for \(\beta_2\)

Model 2: Finding Mean

n_samples <- 2000
mean_beta1 <- 0
mean_beta2 <- 0
mean_beta3 <- 0

for (h in (1:n_samples)) {
  mean_beta1 <- mean_beta1 + beta_out[burn_in+(20*h),1]
  mean_beta2 <- mean_beta2 + beta_out[burn_in+(20*h),2]
  mean_beta3 <- mean_beta3 + beta_out[burn_in+(20*h),3]
}

mean_b1 <- mean_beta1/n_samples 
mean_b2 <- mean_beta2/n_samples 
mean_b3 <- mean_beta3/n_samples

Model 2: The Mean for \(\underline{\beta}\)

26.6870801
-0.7622871
0.0050309

Model 2: The Variances for \(\underline{\beta}\)

40.8647602 -1.2138516 0.0089185
-1.2138516 0.0362391 -0.0002675
0.0089185 -0.0002675 0.0000020

Model 2: MLE for \(\underline{\beta}\)

x
(Intercept) 28.1394302
temperature -0.8128708
I(temperature^2) 0.0054676

Meanz_out

# Matrices to use later
beta_out <- matrix(data = NA, nrow = n_iter, 
                   ncol = n_params)

zed_out <- matrix(data = NA, nrow = n_iter,
                  ncol = 138)

meanz_out <- matrix(data = NA, nrow = n_iter, 
                    ncol = 138)
zed <- vector(length=138)

# Values needed for rtruncnorm function
ones <- matrix(data = 1, nrow = 1, ncol = 138)
num_ones <- sum(dat$affected)
num_zeroes <- length(dat$affected[dat$affected == 0])

Model 2: For-loop

for (i in (1:n_iter)) {
  beta <- mvrnorm(n = 1, mu = beta_hat, XtXi)
  zed[y == 0] <- rtruncnorm(n=num_zeroes, 
                            mean = X[y ==0,] %*% beta,
                            sd = 1, a = -Inf, b = 0)
  
  zed[y == 1] <- rtruncnorm(n=num_ones, 
                            mean = X[y == 1,] %*% beta, 
                            sd = 1, a = 0, b = Inf)
  # Update out beta_hat based off previous iteration
  beta_hat <- solve(XtX) %*% t(X) %*% zed
  # Outputs
  beta_out[i, ] <- beta
  zed_out[i, ] <- zed
  meanz_out[i,] <- X %*% beta
}

Model 2: Mean of Latent Variables (13)

Model 2: Mean of Latent Variables (101)

Model 2: The Mean of the Latent Variables

mean_z <- rep(0,138)
for(m in (1:n_samples)){
  for(j in (1:138)) {
    mean_z[j] <- mean_z[j] +
      meanz_out[burn_in+(20*m),j]
  }
}
mean_z <- mean_z/n_samples

Mean of the Latent Variables

## Warning in kable_pipe(x = structure(c("0.4177726", "-0.4177625", "-0.6014916", :
## The table should have a header (column names)
0.4177726 -2.021414
-0.4177625 -2.021414
-0.6014916 -2.021414
-1.3692088 -2.117202
-1.7090967 -2.150002
-1.8022688 -2.185419
-1.8022688 -2.185419
-1.8022688 -2.188034
-1.8853791 -2.188034
-1.9584276 -2.163079
-2.0214141 -2.135508

Plots

dam <- c(5,1,1,1,0,0,0,0,0,0,1,0,1,0,0,
         0,0,1,0,0,0,0,0)
exposed <- c(rep(6,23))

proportion <- dam / exposed

temp <- c(53,57,58,63,66,67,67,67,68,69,70,70,
          70,70,72,73,75,75,76,76,78,79,81)

xmat <- cbind(rep(1, length(temp)), temp)
xmat2 <- cbind(rep(1, length(temp)), temp, temp^2)

Plots Cont.

References

  • Bayesian Analysis of Binary and Polychotomous Response Data
    Author(s): James H. Albert and Siddhartha Chib
    Source: Journal of the American Statistical Association, Vol. 88, No. 422 (Jun., 1993), pp. 669- 679
  • Dr. E. Olusegun George’s Lectures