Python五行代码完成PCA
原理网上很多,不献丑。
代码包括生成有噪声数据和PCA降维。
效果:
PCA—3维降2维
PCA—二维转1维
代码:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def PCA(Data, k=2):
A = Data-np.array([np.mean(Data,axis=1)]).T
S = A @ A.T / (A.shape[1]-1)
Sigma, U = np.linalg.eig(S)
Dex = np.argsort(-Sigma)
Sigma, U = Sigma[Dex], U[:,Dex]
return U[:,:k],U[:,:k].T @ A
def MakeData2(s1):
# x+y+z=1
D = np.zeros((2, s1))
k = np.random.randint(1,100)
for i in range(s1):
D[0,i] = np.random.randn()
D[1,i] = k*D[0,i]+np.random.randn()*k
return D
def MakeData3(s1):
# x+y+z=1
D = np.zeros((3, s1))
for i in range(s1):
D[0,i] = np.random.randn()
D[1,i] = np.random.randn()
D[2,i] = 1-D[0,i]-D[1,i]+np.random.randn()/2
return D
def Plot2(A,Z):
plt.figure()
plt.scatter(A[0,:],A[1,:],c='b')
plt.scatter(Z[0,:],Z[1,:],c='r')
def Plot3(A,Z):
ax = plt.figure().add_subplot(111, projection = '3d')
ax.scatter(A[0,:],A[1,:],A[2,:])
ax.scatter(Z[0,:],Z[1,:],Z[2,:],c='r')
num = 100 # 样本数目
Data = MakeData3(num)
A = Data-np.array([np.mean(Data,axis=1)]).T
U, Y = PCA(A, 2)
Z = U @ Y
Plot3(A,Z)
Data = MakeData2(num)
A = Data-np.array([np.mean(Data,axis=1)]).T
U, Y = PCA(A, 1)
Z = U @ Y
Plot2(A,Z)