Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

stough 202-

Preview: Intro to 2D PCA.

In the block transform chapter we re-expressed image blocks in terms of different bases (Haar, DCT, and others), and saw that a good basis packs most of a block’s energy into just a few coefficients. Those bases were fixed in advance, the same for every image. Principal Component Analysis (PCA) asks: what is the best basis for this particular data? PCA finds the orthogonal directions along which the data varies the most, ordered from most variance to least. Keep only the first few directions and you have the most faithful low-dimensional summary of the data possible with a linear basis. (In signal processing the same idea is called the Karhunen-Loève Transform, KLT; make_klt_basis in wavelet_utils is exactly this.)

We’ll start in 2D, where we can see everything, with data whose answer we know in advance.

Generate Some Random Data.

gen_pca_data builds data with a known structure. It draws 500 points from an axis-aligned 2D Gaussian with variance 6 along the first axis and 1 along the second. Then it rotates them so those axes point along the directions ⟨1,1⟩\langle 1, 1 \rangle and ⟨1,−1⟩\langle 1, -1 \rangle, normalized to unit length, and shifts the whole cloud to be centered at (10,20)(10, 20). (The first line of the cell above, making X from [4,6], is immediately replaced, so it has no effect.) So if PCA works, it should tell us: mean about (10,20)(10,20), variances about 6 and 1, and directions about ±12⟨1,1⟩\pm\frac{1}{\sqrt{2}}\langle 1, 1 \rangle and ±12⟨1,−1⟩\pm\frac{1}{\sqrt{2}}\langle 1, -1 \rangle.

<Figure size 400x400 with 1 Axes>

 

PCA will find directions in the data space that account for the most variance.

PCA found MEAN: [ 9.83915171 19.93707048]
          VAR : [6.50879959 1.04940098]
components    : 
[[ 0.724062   0.6897349]
 [-0.6897349  0.724062 ]]

Just what we built in, up to sampling noise from having only 500 points. The mean is about (10,20)(10, 20), the variances about 6 and 1, and the rows of components_ are the two diagonal directions, each with entries of about 0.707=120.707 = \frac{1}{\sqrt{2}}. (PCA can’t tell a direction from its opposite, so either one may come out with its sign flipped.)

Where do the components come from?

PCA computes the covariance matrix of the data,

C=1n−1∑i=1n(xi−μ)(xi−μ)⊺\mathbf{C} = \frac{1}{n-1}\sum_{i=1}^{n} (\mathbf{x}_i - \boldsymbol{\mu})(\mathbf{x}_i - \boldsymbol{\mu})^\intercal

whose diagonal holds the variance of each coordinate and whose off-diagonal entries hold how the coordinates vary together. The principal components are the eigenvectors of C\mathbf{C}, and the variance along each is its eigenvalue. Since C\mathbf{C} is symmetric, its eigenvectors are orthogonal, so they form a new orthonormal basis, a rotation of the original axes. Let’s confirm that sklearn is doing exactly this:

covariance matrix:
[[3.91157681 2.72648277]
 [2.72648277 3.64662375]]

eigenvalues : [6.50879959 1.04940098]
eigenvectors (as rows):
[[-0.724062  -0.6897349]
 [ 0.6897349 -0.724062 ]]

Same variances, same directions (again, possibly with signs flipped). Notice the covariance matrix itself: its large off-diagonal entries say that the two coordinates are strongly correlated. In the PCA coordinates, that correlation is gone. Let’s check the covariance of the transformed data Xt:

array([[ 6.509, -0. ], [-0. , 1.049]])

Diagonal: in the new basis the coordinates are uncorrelated, and all the variance has been sorted into the first coordinate as much as possible. This is the same “energy compaction” we wanted from block transforms, but here the basis is tailored to the data.

 

Plot with the PCA directions.

Each dashed line runs from −3σ-3\sigma to +3σ+3\sigma along a principal direction, centered on the mean (orange), where σ\sigma is the standard deviation along that direction. Nearly all the data falls within these lines.

<Figure size 400x400 with 1 Axes>

 

Let’s reconstruct

Very similar to the reconstruction we’ve done in the past with respect to DCT and Haar. Just more general.

Each point is just the mean + sum(coeff*component for every transform coefficient):

x=μ+∑kckvk,ck=vk⋅(x−μ)\mathbf{x} = \boldsymbol{\mu} + \sum_k c_k \mathbf{v}_k, \qquad c_k = \mathbf{v}_k \cdot (\mathbf{x} - \boldsymbol{\mu})

where the vk\mathbf{v}_k are the components. The coefficients ckc_k are exactly what fit_transform gave us in Xt: each is the projection (dot product) of the mean-centered point onto one component.

We'll here attempt to reconstruct 
the point [ 8.60521937 20.56572036] from its 
transform [-0.45984176  1.30626768].
Recall
PCA is MEAN: [ 9.83915171 19.93707048]
       VAR : [6.50879959 1.04940098]
components : 
[[ 0.724062   0.6897349]
 [-0.6897349  0.724062 ]]
The reconstruction is 
     [ 9.83915171 19.93707048] 
plus -0.4598417602677216*[0.724062  0.6897349]
plus 1.306267682788583*[-0.6897349  0.724062 ]
rp is [ 9.50619777 19.61990157] after the first component.
rp is [ 8.60521937 20.56572036] after the second component.

So, pretty close to [ 8.60521937 20.56572036]

With both components we recover the point exactly. The interesting question is what happens with fewer.

 

Dimensionality reduction

Let’s reconstruct every point using only the first component, x≈μ+c0v0\mathbf{x} \approx \boldsymbol{\mu} + c_0 \mathbf{v}_0. That’s describing each 2D point with a single number.

mean squared reconstruction error: 1.047
variance along the dropped component: 1.049
fraction of variance kept: 0.861
<Figure size 400x400 with 1 Axes>

Every point collapses onto the first principal line, its orthogonal projection. The error we make is exactly what we threw away: the mean squared error equals the variance along the dropped second component, up to the nn versus n−1n-1 in the variance formula. With one number per point instead of two, we keep about 67\frac{6}{7} of the variance.

No other single direction would do better. That’s the defining property of PCA: for any number of components kk, the first kk principal components give the smallest possible mean squared reconstruction error among all kk-dimensional linear approximations. In 2D this is a curiosity. With images of faces or handwritten digits, with thousands of pixels each, it’s a powerful way to find the few directions that matter.