赞
踩
我们需要明白PCA的目的是什么。PCA是一种降维技术,它的目的是将高维的数据投影到低维的空间中,同时保留数据的最大变化信息¹。PCA的原理是通过找到一组正交的基向量,使得数据在这组基向量上的投影方差最大²。
PCA的关键在于对特征向量和特征值的求解,通常有两种方式:
对于大规模数据,方法2更为高效。我们可以直接对1500 x 786432的图像数据矩阵进行SVD分解:
[U, S, V] = svd(images_matrix)
然后V的前200列就是我们要的纹理空间的基向量组成的矩阵。
方法一
具体来说,假设我们有一个n维的数据集X,其中每一行是一个样本,每一列是一个特征。我们想要将X降维到k维(k<n),那么我们可以按照以下步骤进行:
为了演示这个过程,我给出一个简单的例子。假设我们有以下四个样本,每个样本有三个特征(x,y,z),我们想要将它们降维到二维:
x | y | z |
---|---|---|
1 | 2 | 3 |
2 | 3 | 4 |
3 | 4 | 5 |
4 | 5 | 6 |
那么我们可以用以下代码来实现PCA:
- import numpy as np
- from sklearn.preprocessing import StandardScaler
-
- # 原始数据
- X = np.array([[1,2,3],[2,3,4],[3,4,5],[4,5,6]])
- print("原始数据:")
- print(X)
-
- # 中心化和标准化
- scaler = StandardScaler()
- Z = scaler.fit_transform(X)
- print("中心化和标准化后的数据:")
- print(Z)
-
- # 协方差矩阵
- C = np.cov(Z.T)
- print("协方差矩阵:")
- print(C)
-
- # 特征值和特征向量
- eig_val, eig_vec = np.linalg.eig(C)
- print("特征值:")
- print(eig_val)
- print("特征向量:")
- print(eig_vec)
-
- # 选择前两个最大的特征值对应的特征向量
- k = 2
- W = eig_vec[:,np.argsort(-eig_val)[:k]]
- print("选择的特征向量:")
- print(W)
-
- # 降维后的数据
- Y = Z.dot(W)
- print("降维后的数据:")
- print(Y)
运行结果如下:
- 原始数据:
- [[1 2 3]
- [2 3 4]
- [3 4 5]
- [4 5 6]]
- 中心化和标准化后的数据:
- [[-1.34164079 -1.34164079 -1.34164079]
- [-0.4472136 -0.4472136 -0.4472136 ]
- [ 0.4472136 0.4472136 0.4472136 ]
- [ 1.34164079 1.34164079 1.34164079]]
- 协方差矩阵:
- [[1.33333333 1.33333333 1.33333333]
- [1.33333333 1.33333333 1.33333333]
- [1.33333333 1.33333333 1.33333333]]
- 特征值:
- [4.00000000e+00 2.22044605e-16 2.22044605e-16]
- 特征向量:
- [[-0.57735027 -0.81649658 -0.15430335]
- [-0.57735027 -0.40824829 0.6172134 ]
- [-0.57735027 0.40824829 -0.6172134 ]]
- 选择的特征向量:
- [[-0.57735027 -0.81649658]
- [-0.57735027 -0.40824829]
- [-0.57735027 0.40824829]]
- 降维后的数据:
- [[-2.30940108 -1.41421356]
- [-0.76980036 -0.47140452]
- [ 0.76980036 0.47140452]
- [ 2.30940108 1.41421356]]
从结果中我们可以看出,原始的三维数据被成功地降维到了二维,而且保留了数据的最大变化信息。这就是PCA的基本过程和效果。
方法二
- import numpy as np
- from sklearn.decomposition import PCA
- import matplotlib.pyplot as plt
-
- # 生成一组三维数据
- np.random.seed(0)
- n_samples = 100
- mean = [0, 0, 0]
- cov = [[1, 0.8, 0.8], [0.8, 1, 0.8], [0.8, 0.8, 1]]
- data = np.random.multivariate_normal(mean, cov, n_samples)
-
- # 创建PCA模型,指定降维到2维
- pca = PCA(n_components=2)
-
- # 拟合数据并进行降维
- pca.fit(data)
- data_2d = pca.transform(data)
-
- ##########################
- # 奇异值和奇异向量
- u, s, vh = np.linalg.svd(data)
- print("奇异值:")
- print(s)
- print("左奇异向量:")
- print(u)
- print("右奇异向量:")
- print(vh)
-
- # 选择前两个最大的奇异值对应的右奇异向量
- k = 2
- W = vh[:k,:].T
- print("选择的右奇异向量:")
- print(W)
-
- # 降维后的数据
- Y = data.dot(W)
- print("降维后的数据:")
- print(Y)
- ##########################
- # 绘制原始数据和降维后的数据
- plt.figure(figsize=(10, 4))
-
- plt.subplot(1, 3, 1)
- plt.scatter(data[:, 0], data[:, 1])
- plt.title("Original 3D Data")
- plt.xlabel("Feature 1")
- plt.ylabel("Feature 2")
-
- plt.subplot(1, 3, 2)
- plt.scatter(data_2d[:, 0], data_2d[:, 1])
- plt.title("2D Data after PCA")
- plt.xlabel("Principal Component 1")
- plt.ylabel("Principal Component 2")
-
- plt.subplot(1, 3, 3)
- plt.scatter(Y[:, 0], Y[:, 1])
- plt.title("2D Data after PCA")
- plt.xlabel("Principal Component 1")
- plt.ylabel("Principal Component 2")
-
-
- plt.tight_layout()
- plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。