二维数组中 PCA 的平均居中...跨行或跨列?

机器算法验证 主成分分析 意思是 Python 麻木的
2022-04-03 02:25:30

我对此很陌生,我正在逐步完成在 2D numpy 数组上运行 PCA 的步骤。每个子阵列代表图像的所有像素(所有行和列均已展平)。例子:

a = np.array([ [1,2,3], [4,5,6], [7,8,9] ])
# so, a[0], a[1], a[2] each represent a separate image

我将使用 numpy.cov 来计算这些子数组的协方差,但首先我需要对数据进行均值中心化,这就是我感到困惑的地方。

我的新手问题是:是否意味着在每个子阵列中都发生居中?也就是说,我是否应该计算 [1,2,3] 的平均值并将其从每个元素中减去,得到 [-1,0,1],然后对接下来的两个子数组执行相同的操作(即,每个子数组将从每个元素中减去自己的平均值)?或者,应该意味着跨阵列发生居中吗?如果是这样,跨行或跨列?

我已经通过计算沿轴 = 0(行)的平均值(例如,http ://www.janeriksolem.net/2009/01/pca-for-images-using-python.html )和轴=1(列)(例如,http ://glowingpython.blogspot.it/2011/07/pca-and-image-compression-with-numpy.html )。但老实说,我不知道在这种情况下哪个合适。

a:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

np.mean(a):
5.0

np.mean(a, axis=0):
[ 4.  5.  6.]

np.mean(a, axis=1):
[ 2.  5.  8.]

# which of the following mean-centered results makes sense?

a - np.mean(a):
[[-4. -3. -2.]
 [-1.  0.  1.]
 [ 2.  3.  4.]]

a - np.mean(a, axis=0):
[[-3. -3. -3.]
 [ 0.  0.  0.]
 [ 3.  3.  3.]]

a - np.mean(a, axis=1):
[[-1. -3. -5.]
 [ 2.  0. -2.]
 [ 5.  3.  1.]]
2个回答

通常,每一行都是一个“观察”(在你的情况下是图像),每一列是一个变量(在你的情况下是像素值)。因此,您应该在进行 PCA 之前将列居中并缩放。

此外,已经存在许多优秀的 PCA 库,例如sklearn.decomposition.PCA,它可以为您节省大量重新发明轮子的精力。但是,如果您坚持自己实施 PCA,您可能应该通过svd而不是通过协方差矩阵来实现。

这取决于数据的设置方式。例如,如果您将协方差矩阵计算为Σ=1nXX在哪里X是去均值的数据,那么你会想要从每列中删除平均值,反之亦然。