I wrote a small utility function that compares two covariance matrices across time horizon using Box M test. Please use it and let me know if you run into any issues. It is a useful function to see how covariance matrices change with time.
I wrote a small utility function that compares two covariance matrices across time horizon using Box M test. Please use it and let me know if you run into any issues. It is a useful function to see how covariance matrices change with time.
Here is the paper for reference in case I messed up the calculations. http://www.ncss.com/wp-content/themes/ncss/pdf/Procedures/NCSS/Equality_of_Covariance.pdf
Revised method with minor fixes:
def boxMtest(covs, n0, n1):
(p, p) = np.shape(covs[0])
k = len(covs)
N = n0 + n1
S = (n0-1.) * covs[0] + (n1 - 1.) * covs[1]
S = S / (N - k)
M1 = (N - k) * np.log(np.linalg.det(S))
M2 = (n0 - 1.) * np.log(np.linalg.det(covs[0])) + (n1 - 1.) * np.log(np.linalg.det(covs[1]))
M = M1 - M2
A1 = (2. * (p**2) + 3. * p + 1.) / (6. * (p+1)* (k-1))
A1 *= (1. / (n0 - 1.) + 1. / (n1 - 1.)) - 1. / (N - k)
v1 = p * (p + 1.) * (k -1.) / 2.
A2 = (p - 1.) * (p + 2.) / (6. * (k-1.))
A2 *= (1. / (n0 - 1.)**2 + 1. / (n1 - 1.))**2 - 1. / (N - k)**2
Adiff = A2 - A1**2
if Adiff > 0:
v2 = (v1 + 2) / Adiff
b = v1 / (1-A1 - (v1/v2))
F = M / b
else:
v2 = (v1 + 2) / -Adiff
b = v2 / (1-A1 + (2./v2))
F = (v2 * M) / (v1 * (b - M))
p_value = 1 - scipy.stats.f.cdf(F, v1, v2)
print p_value
if p_value <= 0.05:
print "covariance are unequal"
else:
print "covariance equal"```