EigenValues of X'.X and X.X' are not matching

68 Views Asked by At

I have 20 weekly demeaned returns of 5 stocks and I am doing eigenvalue/vector decomposition using 'numpy.linalg import eigh'. I found that non zero eigenvalues of X'X and X'X are different. Where I am going wrong? I am expecting same no zero eigenvalues input_df IATV ADCT ADEX ABM ACTM 2000-02-16 -0.153341 0.131426 0.075109 0.103427 0.000188 2000-02-23 -0.094804 0.011775 -0.003919 0.038099 0.088236 2000-03-01 0.189236 -0.014320 0.129573 0.009101 0.208990 2000-03-08 0.056780 0.050969 -0.101161 0.020921 -0.060140 2000-03-15 0.091565 -0.066557 -0.034287 0.005933 -0.034863 2000-03-22 0.089404 0.124820 0.034528 0.031165 0.062288 2000-03-29 0.132605 -0.158519 -0.036778 -0.119378 0.065655 2000-04-05 -0.183140 -0.111664 -0.071937 -0.099150 0.026999 2000-04-12 -0.311738 -0.064767 -0.103590 0.043291 -0.370399 2000-04-19 -0.198327 0.030584 0.000246 0.009976 0.011591 2000-04-26 0.007021 0.027745 -0.163187 0.042351 0.066051 2000-05-03 0.195144 0.027269 0.065502 -0.010899 -0.154931 2000-05-10 -0.190007 -0.130920 0.053181 -0.061937 -0.134020 2000-05-17 0.159747 0.108767 0.014076 -0.024252 -0.065467 2000-05-24 -0.223655 -0.050760 -0.189775 -0.043607 -0.236574 2000-05-31 0.075239 0.038657 -0.010189 0.013378 0.277426 2000-06-07 0.247451 0.001749 0.105771 0.054263 0.112749 2000-06-14 0.035583 0.061647 0.080465 0.014108 0.013676 2000-06-21 0.089355 -0.012215 0.120839 -0.038574 0.119030 2000-06-28 -0.014121 -0.005686 0.035533 0.011782 0.003516

eigh(input_df.cov())[0]

array([0.00101199, 0.00527309, 0.0078702 , 0.01098586, 0.04039286])

last 5 eigenvalues

eigh(input_df.T.cov())[0][15:21]

array([8.87063032e-18, 6.93227345e-03, 2.51868051e-02, 5.19412414e-02, 9.38091465e-02])

1

There are 1 best solutions below

0
On

If I got it right, your NumPy code is something like this:

import numpy as np

X = np.array([
    [-0.153341,  0.131426,  0.075109,  0.103427,  0.000188],
    [-0.094804,  0.011775, -0.003919,  0.038099,  0.088236],
    [ 0.189236, -0.014320,  0.129573,  0.009101,  0.208990],
    [ 0.056780,  0.050969, -0.101161,  0.020921, -0.060140],
    [ 0.091565, -0.066557, -0.034287,  0.005933, -0.034863],
    [ 0.089404,  0.124820,  0.034528,  0.031165,  0.062288],
    [ 0.132605, -0.158519, -0.036778, -0.119378,  0.065655],
    [-0.183140, -0.111664, -0.071937, -0.099150,  0.026999],
    [-0.311738, -0.064767, -0.103590,  0.043291, -0.370399],
    [-0.198327,  0.030584,  0.000246,  0.009976,  0.011591],
    [ 0.007021,  0.027745, -0.163187,  0.042351,  0.066051],
    [ 0.195144,  0.027269,  0.065502, -0.010899, -0.154931],
    [-0.190007, -0.130920,  0.053181, -0.061937, -0.134020],
    [ 0.159747,  0.108767,  0.014076, -0.024252, -0.065467],
    [-0.223655, -0.050760, -0.189775, -0.043607, -0.236574],
    [ 0.075239,  0.038657, -0.010189,  0.013378,  0.277426],
    [ 0.247451,  0.001749,  0.105771,  0.054263,  0.112749],
    [ 0.035583,  0.061647,  0.080465,  0.014108,  0.013676],
    [ 0.089355, -0.012215,  0.120839, -0.038574,  0.119030],
    [-0.014121, -0.005686,  0.035533,  0.011782,  0.003516],
])

print(np.linalg.eigh(np.matmul(X.T, X))[0])
print(np.linalg.eigh(np.matmul(X, X.T))[0])

The output is:

[0.0192277  0.10018871 0.14953362 0.20873121 0.76746377]
[-1.22407003e-16 -4.69841160e-17 -2.05275816e-17 -1.18584471e-17
 -9.52302482e-18 -5.50182816e-18 -1.24091632e-18  3.06511131e-19
  4.36901880e-18  1.13874944e-17  1.29119823e-17  1.83886941e-17
  3.59462295e-17  4.07946365e-17  8.25135700e-17  1.92277041e-02
  1.00188709e-01  1.49533623e-01  2.08731205e-01  7.67463772e-01]

Notice that the top 5 eigenvalues match, and the rest of them are super-small ($0 < \lambda < 10^{-16}$). But we know that $X^TX$ and $XX^T$ can have at most 5 non-zero eigenvalues, so these small eigenvalues are effectively zero. Your confusing result is just a numerical error.

One should not compute eigenvalues of $XX^T$ and $X^TX$ by computing these products. Instead, compute SVD of your matrix. The eigenvalues will be squares of the obtained singular values.