Testing Normality
Normality tests check whether a sample is consistent with having been drawn from a normal distribution. The null hypothesis is that the sample comes from a normal population. A small p-value is evidence against normality, while failure to reject does not prove that the data are normal.
Choosing a test
Use the ShapiroWilkTest as a strong default for small to moderate samples. It is valid for sample sizes from 3 to 5000.
Use the AndersonDarlingTest when sensitivity in the tails is especially important.
Use the JarqueBeraTest for a simple omnibus test based on sample skewness and kurtosis.
Use the DAgostinoPearsonOmnibusTest when you want a skewness and kurtosis omnibus test with transformed z-score diagnostics.
A one-sample Kolmogorov-Smirnov test against a fitted normal distribution can be useful as a descriptive check, but remember that the usual KS reference distribution does not account for parameters estimated from the same sample.
Comparing several normality tests
The following example constructs four normality tests for the same sample.
var sample = Vector.Create(
18.830, 20.800, 21.657, 23.030, 23.230, 24.050,
24.321, 25.500, 25.520, 25.800, 26.690, 26.770,
26.780, 27.050, 27.670, 29.900, 31.110, 33.200,
33.730, 33.760, 33.890, 34.760, 35.750, 35.910,
36.980, 37.080, 37.090, 39.580, 44.045, 45.290,
45.381);
ShapiroWilkTest shapiroWilk = new ShapiroWilkTest(sample);
AndersonDarlingTest andersonDarling = new AndersonDarlingTest(sample);
JarqueBeraTest jarqueBera = new JarqueBeraTest(sample);
DAgostinoPearsonOmnibusTest dagostinoPearson = new DAgostinoPearsonOmnibusTest(sample);You can compare the test statistic, p-value, and rejection decision from each test directly:
var sample2 = Vector.Create(
18.830, 20.800, 21.657, 23.030, 23.230, 24.050,
24.321, 25.500, 25.520, 25.800, 26.690, 26.770,
26.780, 27.050, 27.670, 29.900, 31.110, 33.200,
33.730, 33.760, 33.890, 34.760, 35.750, 35.910,
36.980, 37.080, 37.090, 39.580, 44.045, 45.290,
45.381);
HypothesisTest[] tests =
{
new ShapiroWilkTest(sample2),
new AndersonDarlingTest(sample2),
new JarqueBeraTest(sample2),
new DAgostinoPearsonOmnibusTest(sample2)
};
foreach (HypothesisTest test in tests)
{
Console.WriteLine("{0}", test.Name);
Console.WriteLine(" Statistic: {0:F4}", test.Statistic);
Console.WriteLine(" P-value: {0:F4}", test.PValue);
Console.WriteLine(" Reject? {0}", test.Reject() ? "yes" : "no");
}The Shapiro-Wilk test
The Shapiro-Wilk statistic W is based on the ordered sample values and their expected values under normality. Smaller values of W indicate a departure from normality.
In Numerics.NET, the ShapiroWilkTest class exposes a constructor that takes the sample to test.
The Anderson-Darling test
The Anderson-Darling test is an EDF-based normality test that gives extra weight to the tails. It is often useful when tail behavior matters more than central fit.
The AndersonDarlingTest class can be constructed with no arguments, with a sample, with a sample and a distribution, with a sample and a CDF, or with a sample plus a known normal mean and standard deviation.
The Jarque-Bera test
The Jarque-Bera test is based on the sample skewness S and kurtosis K, reported using the excess-kurtosis convention so that normal samples have K = 0. Its test statistic is:
Under the null hypothesis, the statistic is compared to a chi-square distribution with two degrees of freedom. This makes the test especially useful for detecting departures from normality that show up as skewness or abnormal tail weight. Because the p-value is based on an asymptotic approximation, it should be interpreted cautiously for small samples.
Jarque-Bera is commonly treated as more reliable for larger samples, where its asymptotic chi-square approximation is more accurate.
The JarqueBeraTest class also exposes the computed skewness and excess kurtosis as diagnostic properties.
The D'Agostino-Pearson omnibus test
The D'Agostino-Pearson omnibus test transforms the sample skewness and kurtosis into approximately standard normal z-scores and combines them into a single statistic:
The statistic is compared to a chi-square distribution with two degrees of freedom, so its p-value is also based on an asymptotic approximation that should be interpreted cautiously for small samples.
The DAgostinoPearsonOmnibusTest class exposes the transformed SkewnessZScore and KurtosisZScore properties in addition to the raw skewness and kurtosis diagnostics, where the kurtosis value uses the excess-kurtosis convention.
Inspecting diagnostic values
Jarque-Bera and D'Agostino-Pearson expose useful diagnostic components that you can inspect alongside the omnibus p-value:
var sample3 = Vector.Create(
18.830, 20.800, 21.657, 23.030, 23.230, 24.050,
24.321, 25.500, 25.520, 25.800, 26.690, 26.770,
26.780, 27.050, 27.670, 29.900, 31.110, 33.200,
33.730, 33.760, 33.890, 34.760, 35.750, 35.910,
36.980, 37.080, 37.090, 39.580, 44.045, 45.290,
45.381);
JarqueBeraTest jb = new JarqueBeraTest(sample3);
DAgostinoPearsonOmnibusTest dp = new DAgostinoPearsonOmnibusTest(sample3);
Console.WriteLine("Jarque-Bera skewness: {0:F4}", jb.Skewness);
Console.WriteLine("Jarque-Bera kurtosis: {0:F4}", jb.Kurtosis);
Console.WriteLine("D'Agostino skewness z: {0:F4}", dp.SkewnessZScore);
Console.WriteLine("D'Agostino kurtosis z: {0:F4}", dp.KurtosisZScore);