GitHub profile

Eigenvector and Eigenvalue Decomposition

Notation

As defined in the Definitions page, the eigenvalue equation $\mathbf{A}\vec{v} = \lambda \vec{v}$ decomposes the covariance matrix $\mathbf{A}$ built in Step 6 into its eigenvector/eigenvalue pairs. Stacked together this is $\mathbf{A}\mathbf{V} = \mathbf{V}\boldsymbol{\Lambda}$, i.e. $\mathbf{A} = \mathbf{V}\boldsymbol{\Lambda}\mathbf{V}^{-1}$.

Since $\mathbf{A}$ is real and symmetric, the spectral theorem guarantees real eigenvalues and mutually orthogonal eigenvectors, so we use numpy.linalg.eigh rather than the general eig. Components are ordered by descending eigenvalue, so PC1 corresponds to the direction of greatest variance.

step 1 - calculate the eigenvalues


import subprocess  
%run ./dataframes/step7_eigendecomposition.py  
%run ./dataframes/truncate_with_ellipsis.py  
df = eigenvalues()  
subprocess.run(['wl-copy'], input=truncate_with_ellipsis(df, 3).to_html(index=False).encode())  
component eigenvalue
PC1 27.95052
PC2 2.109532
PC3 0.262332
... ...
PC69 0.0
PC70 0.0
PC71 0.0

step 2 - calculate the eigenvectors (loadings)


import subprocess  
%run ./dataframes/step7_eigendecomposition.py  
%run ./dataframes/truncate_with_ellipsis.py  
df = eigenvectors()  
subprocess.run(['wl-copy'], input=truncate_with_ellipsis(df, 3).to_html(index=True).encode())  
PC1 PC2 PC3 ... PC69 PC70 PC71
5 0.241234 0.364534 -0.595643 ... -0.005661 -0.002342 -0.001463
5.5 0.231665 0.30687 -0.34615 ... 0.007878 0.006084 -0.000137
6 0.218301 0.267447 -0.264316 ... -0.000466 -0.001903 -0.000203
... ... ... ... ... ... ... ...
39 0.093087 -0.117291 -0.010104 ... -0.082599 -0.112586 -0.163042
39.5 0.093675 -0.11656 -0.006303 ... 0.148812 0.155426 -0.033265
40 0.093779 -0.118031 -0.007279 ... 0.02058 0.065204 0.063545

Python

filename: step7_eigendecomposition.py

from dataframes.step6_covariance import *
import numpy as np
import pandas as pd

def eigenvalues():
    A = covariance_matrix()
    vals = np.linalg.eigvalsh(A.values)
    vals = vals[::-1]
    component = [f"PC{i+1}" for i in range(len(vals))]
    return pd.DataFrame({"component": component, "eigenvalue": vals})

def eigenvectors():
    A = covariance_matrix()
    vals, vecs = np.linalg.eigh(A.values)
    order = np.argsort(vals)[::-1]
    vecs = vecs[:, order]
    component = [f"PC{i+1}" for i in range(vecs.shape[1])]
    return pd.DataFrame(vecs, index=A.index, columns=component)
eigenvalues and eigenvectors (loadings) of the covariance matrix