pca一张图片降维问题

1.去中心化

X_mean=np.mean(X,axis=0)
X_norm=X-X_mean

2.求协方差矩阵

X_cov=np.cov(X_norm,rowvar=False)
print(X_cov.shape)

3.求协方差矩阵的特征值与特征向量

eigvalues, eigvectors =np.linalg.eig(X_cov)

4.按特征排序取出索引

max_eigvalue_index = np.argsort(-eigvalues)[:K]

5.保留最大的K大特征值对应的特征分量

W = eigvectors[:,max_eigvalue_index]

6.降维后数据

X_new = np.dot(X_norm, W)

7.重建图像

X_rec = np.dot(X_new,W.T) + X_mean
return W, X_mean,X_new,X_rec

return X_rec

pca对一张图片降维,X_mean=np.mean(X,axis=0),这里为什么要对X每一列求均值,不应该是把每一个像素作为一个特征吗,但这句语句是把每一列当成一个特征了吗?

PCA 图片降维,可以有多种理解。例如:
(1)多张(m张) 图片,降维至 p(p<m) 张图片来表达,这在天文、遥感等多光谱图片中非常常见;
(2)一张图片,多通道,常见通道数为 3,降维,或将主要方差集中到第 0 维。
(3)一张图片,二维对象的方向校正,通过主成分分析(PCA)获得目标的主方向,将数据投影到主方向及其垂直方向上。
所以,你先要搞清楚你写的这两行程序,是针对哪种情况用的。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    在PCA对一张图片进行降维时,要对X中的每一列进行均值中心化操作,是因为PCA是通过数据的协方差矩阵进行降维的,如果数据没有经过中心化处理,就会存在方差过大或过小的问题,导致降维结果不准确。因此,我们需要对每一列进行均值中心化操作,即对每个像素进行处理,让所有像素都在均值为0的基础上进行降维操作。

    PCA降维的其他步骤包括:

    1.计算协方差矩阵 使用numpy中的cov函数,该函数默认将每一行看作一个变量,每一列看作一个样本,返回的协方差矩阵的每个值都是两个变量之间的协方差。

    2.计算协方差矩阵的特征值和特征向量 使用numpy中的linalg.eig函数,该函数可以计算矩阵的特征值和特征向量,特征向量表示数据在该特征空间下的投影方向。

    3.选取特征值最大的前k个特征向量 特征值越大表示该特征对应的方差越大,即该特征包含的信息越多。因此,我们选择前k个特征值对应的特征向量作为新的特征空间。

    4.将数据投影到新的特征空间上 使用新的特征向量将原始数据进行投影,即将每个样本表示为由k个特征值组成的向量,在新的特征空间中进行降维。

    5.还原数据 将降维后的数据通过特征向量的逆矩阵乘以降维后的数据,还原数据到原始的空间中。

    下面是一个简单的Python示例代码:

    import numpy as np
    import matplotlib.pyplot as plt
    
    def center(X):
        # 对每一列进行均值中心化操作
        mean = np.mean(X, axis=0)
        return X - mean
    
    def PCA(X, k):
        # 计算协方差矩阵
        cov = np.cov(center(X).T)
        # 计算协方差矩阵的特征值和特征向量
        eigvals, eigvecs = np.linalg.eig(cov)
        # 将特征向量按照特征值从大到小排序
        idx = np.argsort(eigvals)[::-1][:k]
        # 选取前k个特征向量,并将其组成特征矩阵
        eigvecs = eigvecs[:, idx]
        # 将数据投影到新的特征空间上
        new_X = np.dot(center(X), eigvecs)
        # 还原数据
        X_reconstructed = np.dot(new_X, eigvecs.T) + np.mean(X, axis=0)
        return new_X, X_reconstructed
    
    # 加载图片数据
    img = plt.imread('test.jpg')
    # 将图片展平
    X = img.reshape(-1, 3)
    # 进行PCA降维,选取前2个主成分
    new_X, X_reconstructed = PCA(X, 2)
    
    # 显示降维后的图片
    plt.subplot(121)
    plt.imshow(X_reconstructed.reshape(img.shape))
    
    # 显示降维后的数据分布
    plt.subplot(122)
    plt.scatter(new_X[:, 0], new_X[:, 1])
    plt.show()
    

    其中,'test.jpg'为待降维的图片路径,运行结果为降维后的图像和降维后的数据分布。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^