Multivariate Normal Distribution

In this lab, we will explore the multivariate normal distribution and samples thereof. First of all, we need install some tools for later use. Open MS-DOS window, change directory and make a new subdirectory called _Help as follows (I assume that you have already set up your h:\stat524\_Data directory in the previous lab)
cd h:\stat524\_Data
mkdir _Help
Open Netscape, and go to http://lib.stat.cmu.edu/S/ellipse, and save it to h:\stat524\ as a text file, you can call it ellipse.txt, which is an packed file. To unpack ellipse.txt, go to http://lib.stat.cmu.edu/DOS/S/SWin, find unshar.ext, click on it, and save it as h:\stat524\unshar.exe. Then, go back to MS-DOS widow, make sure that you are in h:\stat524\, and type
unshar ellipse.txt
The above procedure generates several files including the source code ellipse.s. Now, open Splus from standard software\statistical package. It again takes a couple of minutes to bring out Splus. In command window, enter
>attach("h:\\stat524\\_Data", pos=1)
>source('h:\\stat524\\ellipse.s')
Now you are ready to start today's lab. Note: ellipse could be set up in your local library or in the system Splus library, I still didn't quite sort it out yet. At this stage, we will just use some functions from this package. There are also quite a lot packages available in http://lib.stat.cmu.edu/S/, if you are interested, you can explore them. Now we need a function to calculate the bivariate normal density, please check the text or the lecture notes if you have forgot the form. You can copy and paste, or directly type, the function into your Splus Command Window:
>dbinorm_function(x, mu, sigma) {
det_sigma[1,1]*sigma[2,2]-sigma[1,2]*sigma[2,1]
a_t(x-mu)%*%solve(sigma)%*%(x-mu)
exp(-a/2)/(sqrt(det)*2*pi)
}
where t is the transposition operator, %*% is the multiplication between two matrices, solve() gives the inverse of a nonsingular square matrix. Now create an identity variance matrix and a zero mean vector:
>sigma_matrix(c(1,0,0,1),ncol=2)
>sigma
>mu_c(0,0)
>mu
Create the range of values for which we want to plot the density:
>x_seq(-3,3,len=20)
>y_seq(-3,3,len=20)
Create a matrix to store the density at points (x[i],y[j]):
>z_matrix(0,ncol=20,nrow=20)
Compute the density over for the points (x[i],y[j]):
for(i in 1:20) {
   for(j in 1:20){
    z[i,j]_dbinorm(c(x[i],y[j]),mu,sigma)
}
}
Plot the result in two ways:
>win.graph()
>persp(x,y,z)
>contour(x,y,z)
Let's construct a distribution with some correlation. The determinant of the variance matrix is chosen to be one so that the scale will be similar to the identity case.
>sigmac_matrix(c(sqrt(2),1,1,sqrt(2)),ncol=2)
>sigmac
Recompute the density:
>for(i in 1:20){
   for(j in 1:20){
    z[i,j]_dbinorm(c(x[i],y[j]),mu,sigmac)
}
}

Replot:

>persp(x,y,z)
>contour(x,y,z)
Now we generate a sample with identity variance matrix and plot:
>d_matrix(rnorm(200),ncol=2)
>plot(d[,1],d[,2])
Where rnorm(200) generates 200 independent observations from the standard normal distribution. Now compute and draw the 50% and 90% ellipsoids of the true density:
>lines(ellipse(sigma, centre=mu, level=0.50))
>lines(ellipse(sigma, centre=mu, level=0.90))
We can generate a sample in the correlated case in this manner:
>A_t(chol(sigmac))
>nd_d %*% A
and plot as before:
>plot(nd)
>lines(ellipse(sigmac,centre=mu,level=0.50))
>lines(ellipse(sigmac,centre=mu,level=0.90))
See what will happen when we use the estimates of mean and variance rather than the true values:
>mus_apply(nd,2,mean)
>mus
>sigmas_var(nd)
>sigmas
>lines(ellipse(sigmas,centre=mus,level=0.50),lty=2)
>lines(ellipse(sigmas,centre=mus,level=0.90),lty=2)
The second part of this lab is about checking multivariate normality. In a quality control test of microwave ovens, radiation readings were taken with door open and with the door closed. Data for 42 ovens are available. First save the data to your own directory for plain data sets, such as h:\stat524\Datasets\radiation.data, and then read in and examine the data:
>rad_read.table("h:\\stat524\\Datasets\\radiation.data",header=T)
>rad
Now plot the data:
>plot(rad[,1],rad[,2],xlab="Closed",ylab="Open")
Does it look normal? Now make the QQ plots:
>qqnorm(rad[,1])
>qqline(rad[,1])
>qqnorm(rad[,2])
>qqline(rad[,2])
Do these look normal? Now compute the mean and variance:
>radvar_var(rad)
>radvar
>radmean_apply(rad,2,mean)
Now make the chi-square plot, recall that the generalized distances are also called Mahalanobis distances:
>md_mahalanobis(rad,radmean,radvar)
>plot(sort(md),qchisq((1:42)/43,2))
where sort() sorts md from smallest to largest, and qchisq(,2) gives the quantiles of chi-square distribution with 2 degrees of freedom. Notice that the quantiles given here are sightly different from those given in the text. Now, does it look normal? Let's apply some transformation and redo the plots
>srad_sqrt(rad)
>plot(srad)
>qqnorm(srad[,1])
>qqline(srad[,1])
>qqnorm(srad[,2])
>qqline(srad[,2])
And redo the chi-square plots:
>sradvar_var(srad)
>sradmean_apply(srad,2,mean)
>smd_mahalanobis(srad,sradmean,sradvar)
>plot(sort(smd),qchisq((1:42)/43,2))
>abline(0,1)
This looks better. We can plot the estimated 95th percentile contour for the mean:
>plot(srad)
>lines(ellipse(sradvar,centre=sradmean, level=0.95),lty=2)
Finally, it is interesting to see how the region look when we transform back to the original scale of measurement:
>plot(rad[,1],rad[,2], xlab="Closed", ylab="Open")
>square_function(x) x^2
>lines(square(ellipse(sradvar,centre=sradmean,level=0.95)),lty=2)
>lines(square(ellipse(sradvar,centre=sradmean,t=squrt(qchisq(0.95,2)/42))))
Now, let us determine what is the best Box-Cox transformation for data that does not show normality. We will use the radiation data with door close as an example.
>x_rad[,1]
>lambda_seq(-2,2,by=0.1)
>m_length(lambda)
>g_rep(0,m)
We calculate the values of l(lambda) at various lambda between -2 and 2, and save them in g.
>for(i in 1:m) {
if(lambda[i]!=0) a_(n-1)*var((x^{lambda[i]}-1)/lambda[i])/n
if(lambda[i]==0) a_(n-1)*var(log(x))/n
b_sum(log(x))
g[i]_-n*log(a)/2+(lambda[i]-1)*b
}
Nest, plot lambda against g, choose the maximum as the transformation for x.
>plot(lambda,g, type="l")
Approximately what lambda you should use in the Box-Cox transformatoin? Use QQ plot to check the normality of the transformed data.