-
Notifications
You must be signed in to change notification settings - Fork 1
/
encoders.py
52 lines (40 loc) · 1.24 KB
/
encoders.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import numpy as np
"""
Contains class definitions related to latent factor models, whose behaviours are
encapsulated by the "learned encoders", which are objects implementing encode() method.
"""
class LinearEncoder:
"""
Latent factor models that can "encode" X into Z, and "decode" Z into X based on latent factors W.
"""
mu = None
W = None
def encode(self, X):
"""
Use the column-wise mean and principal components to
compute the "component scores" to encode
"""
X = X - self.mu
return X @ self.W.T
def decode(self, Z):
"""
Transforms "component scores" back into the original data space.
"""
return Z @ self.W + self.mu
class PCAEncoder(LinearEncoder):
"""
Solves the PCA problem min_{Z,W} (Z*W - X)^2 using SVD
"""
def __init__(self, k):
self.k = k
def fit(self, X):
"""
Learns the principal components by delegating to SVD solver.
"Fitting" here is the matter of populating:
self.mu: the column-wise mean
self.W: the principal components
"""
self.mu = np.mean(X, axis=0)
X = X - self.mu
U, s, Vh = np.linalg.svd(X)
self.W = Vh[: self.k]