This is the basis for my $100 bet used in one of my February 2012 blog posting. The below is not well documented. However, if you follow the blog entry it may make more sense. Here are a couple of references that I found helpful:

http://science.kennesaw.edu/~jdemaio/1107/Central%20Limit%20Theorem.htm
http://www.statisticalengineering.com/central_limit_theorem_(summary).html

Enjoy! Craig on 23-Feb-2012.

First, create the master population. We won’t use all these values and the actual population of values is shown at the very bottom of the file. Notice I used a Chi Square distribution. I wanted to use something that was not “normal” yet seemd real enough to mimic real DBA ages. The normality test showed a pvalue < 0.05, meaning the samples are NOT likely to be normally distributed. The histogram looks pretty normal though.

SeedRandom[41]; (* used 41 for blog posting w/avg age of 40 *)
sampleSetSize=500;
allSamples=RandomVariate[ChiSquareDistribution[40],sampleSetSize];
DistributionFitTest[allSamples]
Histogram[allSamples]

Walk into a room full of Oracle DBAs (perhaps 300). But this is kind of lame... I should have skipped this sub setting the raw data. Must have seemed good at the time.

start=3; (* 3 for blog posting *)
fullSet=Take[allSamples,{start,start+300}]
N[Min[fullSet]]
N[Mean[fullSet]]
N[Median[fullSet]]
N[Max[fullSet]]
N[StandardDeviation[fullSet]]

Ask 25 of the DBAs to walk to the other side of the room. Of those 25, randomly divide them into 5 groups of 5. Ask the others to remain in the room. This is the real data for the initial 5 sample sets.

initialSample=fullSet[[1;;100]]
set1=initialSample[[1;;5]]
set2=initialSample[[6;;10]]
set3=initialSample[[11;;15]]
set4=initialSample[[16;;20]]
set5=initialSample[[21;;25]]

Ask each small group of 5 to determine their average age, with the precision to 1 decimal place, tell me the values. This is where I got the initial five values I wrote about in the blog.

mean1=N[Mean[set1]]
mean2=N[Mean[set2]]
mean3=N[Mean[set3]]
mean4=N[Mean[set4]]
mean5=N[Mean[set5]]

Below is a histogram of the mean sample set. It’s doesn’t look normal, but that will be difficult with only five values. The normality test however clearly exceeded our pvalue threshold of 0.05.

meanSet={mean1,mean2,mean3,mean4,mean5};
Histogram[meanSet]

DistributionFitTest[meanSet]

Since the sample set of the means is normal, I can make all sorts of claims. But I need to calculate it’s mean (i.e., the mean of the sample set of means), standard deviation, and the 90% and 95% confidence intervals.

setMean=Mean[meanSet];
setStdev=StandardDeviation[meanSet];
setStdev2=(Variance[meanSet])^0.5;
lowAge95=setMean-2*setStdev;
highAge95=setMean+2*setStdev;
lowAge90=setMean-1.645*setStdev;
highAge90=setMean+1.645*setStdev;
Print["mean=",setMean, " stdev=",setStdev];
Print["90% low=",lowAge90," high=",highAge90];
Print["95% low=",lowAge95," high=",highAge95];

But really, since we have less than 30 samples, slightly different math should be used. I used the 90% confidence level below. Note: In the blog entry, the “bet” used the high/low values above, not the ones below. The range values below are what I really should have used at the 95% level, but as you can see, the math is a little more complicated.

setStdevP=(Length[meanSet]*Variance[meanSet]/(Length[meanSet]-1))^0.5;
lowAgeP=setMean-2*setStdevP;
highAgeP=setMean+2*setStdevP;
Print["Pop STD: stdevP=",setStdevP," lowP=",lowAgeP," highP=",highAgeP];

Now randomly create 10 groups of 5 DBAs each. Ask each group to determine their average age, write it donw on a pice of paper, and place the paper face down in front of me. 

I now make the bet! “I will bet anyone $100 that 9 out of the 10 averages before me will between x and y.” As  I wrote in the blog, I actually used the 95% confidence numbers because of my small sample set.

Below are 10 groups of 5 ages each, along with their avereage and some other stats. I also included the code to quickly tell me how many of the avereage are within my selected range (using the 95% confidence level).

lowAgeX=lowAge95;
highAgeX=highAge95;
groupSize=5;
groupNum=10;
yesCntrStd=0;
noCntrStd=0;
fullTestSet={};
meanSet={};
Table[
testSet=fullSet[[i;;i+groupSize-1]];
fullTestSet=Join[fullTestSet,testSet];
testAvg=N[Mean[testSet]];
testStdev=N[StandardDeviation[testSet]];
testSE=testStdev/Length[testSet];
AppendTo[meanSet,testAvg];

If[(lowAgeX ≤testAvg)&&(highAgeX>testAvg),
yesCntrStd=yesCntrStd+1,
noCntrStd=noCntrStd+1
];
Print[" avg=",testAvg," stdev=",testStdev," SE=",testSE," set=",testSet];
,
{i,101,100+groupSize*groupNum,groupSize}
];
Print["Yes=",yesCntrStd," No=",noCntrStd," Yes%=",N[100*yesCntrStd/(yesCntrStd+noCntrStd)]];

One of the central limit theorem claims is a sample set made up of means from another sample set (like we have done) is normally distributed. Let’s check it out! Because there are only 10 values the histogram is not convincing, but the noarmality test is! We want a pvalue > 0.05 and it is 0.98 which tells us the 10 values are very likely to be normally distributed!!

meanSet
Histogram[meanSet]
DistributionFitTest[meanSet]

Below is ALL the data that was actually used in this test, including the aveage and a normality check. While I wanted the raw data to NOT be normal, statistically it is... even though it came from a Chi Square distribution!

popSet=Join[set1,set2,set3,set4,set5,fullTestSet]
Length[popSet]
Mean[popSet]
DistributionFitTest[popSet]
Histogram[popSet]