Skip to content

Instantly share code, notes, and snippets.

@mu578
Last active August 21, 2021 03:39
Show Gist options
  • Save mu578/715a6c88759683206efb1ea87d1d66bf to your computer and use it in GitHub Desktop.
Save mu578/715a6c88759683206efb1ea87d1d66bf to your computer and use it in GitHub Desktop.
import numpy as np
class pca:
def __svd_thin(self, a):
u, s, vh = np.linalg.svd(a, full_matrices=False, compute_uv=True)
return ( u, s, vh.T )
def __eig_symmetric(self, a):
c = np.dot(a.T, a) / (a.shape[0] - 1)
e, v = np.linalg.eig(c)
i = e.argsort()[::-1]
return ( e[i], v[:,i], c )
def __fit_transform(self, svd=True):
if svd is True:
u, s, v = self.__svd_thin(self.__a)
p = np.square(s) / (self.__m - 1)
x = np.dot(u, np.diag(s))
c = v @ np.diag(p) @ v.T
#c = v @ np.diag(p) @ np.linalg.inv(v)
c_verif = np.dot(self.__a.T, self.__a) / (self.__m - 1)
return ( x, p, v, c, c_verif )
else:
p, v, c_verif = self.__eig_symmetric(self.__a)
x = np.dot(self.__a, v)
c = v @ np.diag(p) @ v.T
#c = v @ np.diag(p) @ np.linalg.inv(v)
return ( x, p, v, c, c_verif )
def __init__(self, a):
self.__a = np.array(a)
self.__m, self.__n = self.__a.shape
self.__a = self.__a - self.__a.mean(axis=0)
def fit(self, svd=True):
return self.__fit_transform(svd)
a = np.random.rand(1200, 3)
o = pca(a)
print("")
x1, p, c, _ = o.fit()
print(x1)
print(p)
print(c)
print("")
x2, p, c, _ = o.fit(False)
print(x2)
print(p)
print(c)
print(np.allclose(np.abs(x1), np.abs(x2), atol=10E-05))
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment