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