MNIST Python numpy特征向量可视化错误

MNIST Python numpy特征向量可视化错误,python,numpy,machine-learning,pca,eigenvector,Python,Numpy,Machine Learning,Pca,Eigenvector,我正在尝试对数据集执行PCA,作为生成特征向量和可视化顶部特征的过程的一部分。以下是我的算法: 加载图像 减去平均数 生成协方差矩阵 导出特征向量和特征值 这是一个运行起来相当简单的算法;我的第一个任务是将前10个特征向量可视化为图像。以下是我目前掌握的代码: __author__ = "Ajay Krishna Teja Kavuri" import numpy as np import random from mnist import MNIST import matpl

我正在尝试对数据集执行PCA,作为生成特征向量和可视化顶部特征的过程的一部分。以下是我的算法:

  • 加载图像
  • 减去平均数
  • 生成协方差矩阵
  • 导出特征向量和特征值
  • 这是一个运行起来相当简单的算法;我的第一个任务是将前10个特征向量可视化为图像。以下是我目前掌握的代码:

    __author__      =   "Ajay Krishna Teja Kavuri"
    
    
    import numpy as np 
    import random
    from mnist import MNIST
    import matplotlib.pylab as plt
    
    class PCAMNIST:
    
    
        #Initialization
        def __init__(self):
            #Load MNIST datset
            mnistData = MNIST('./mnistData')
            self.imgTrain,self.lblTrain=mnistData.load_training()
            self.imgTrainSmpl=self.imgTrain[:60000]
            np.seterr(all='warn')
    
    
        #1. Subtract the mean because the PCA will work better
        def subMean(self):
            try:
                self.sumImg = np.empty([784,])
                #calculate the sum
                for img in self.imgTrainSmpl:
                    imgArr = np.asarray(img)
                    self.sumImg = np.add(imgArr,self.sumImg)
    
                #Calculate the mean array
                self.meanImg = self.sumImg/(len(self.imgTrainSmpl))
                self.meanImg = np.nan_to_num(self.meanImg)
    
                #subtract it out
                index=0
                for img in self.imgTrainSmpl:
                    imgArr = np.asarray(img)
                    self.imgTrainSmpl[index] = np.subtract(imgArr,self.meanImg).tolist()
                    index += 1
    
                #for img in self.imgTrainSmpl:
                    #print img
            except:
                print Exception 
    
    
        #2. get the covaraince matrix for each digit
        def getCov(self):
            self.imgCov=[]
            dgtArr = np.asarray(self.imgTrainSmpl).T
            dgtCov = np.cov(dgtArr)
            self.imgCov.append(dgtCov)
            #for img in self.imgCov:
                #print img
    
        #3. get the eigen vectors from the covariance matrix
        def getEigen(self):
            self.eigVec=[]
            self.eigVal=[]
            dgtArr = np.asarray(self.imgCov)
            tmpEigVal,tmpEigVec=np.linalg.eig(dgtArr)
            self.eigVal.append(tmpEigVal.tolist())
            self.eigVec.append(tmpEigVec.tolist())
    
            #print "\nEigen values:\n"
            #for img in self.eigVal:
                #print img
    
            #print "\nEigen vectors:\n"
            #for img in self.eigVec:
                #print img
    
    
        def sortEV(self):
            self.eigValArr = np.asarray(self.eigVal[0][0])
            self.eigVecArr = np.asarray(self.eigVec[0][0])
            self.srtdInd = np.argsort(np.abs(self.eigValArr))
            self.srtdEigValArr = self.eigValArr[self.srtdInd]
            self.srtdEigVecArr = self.eigVecArr[self.srtdInd]
            self.srtdEigVec = self.srtdEigVecArr.real.tolist()
            #print self.srtdEigValArr[0]
            print len(self.srtdInd.tolist())
            #print self.eigVec[self.srtdInd[0]]
            #print np.asarray(self.srtdEigVec).shape
            #for img in self.srtdEigVecArr:
                #print img
            #self.drawEig()
    
        def plotVal(self):
            """
            plt.figure()
            plt.scatter(np.asarray(self.eigVal).real)
            plt.show()
            """
    
        def drawEig(self):
            for vec in self.srtdEigVec[:10]:
                self.drawEigV(vec)
    
    
        def drawEigV(self,digit):
            plt.figure()
            fig=plt.imshow(np.asarray(digit).reshape(28,28),origin='upper')
            fig.set_cmap('gray_r')
            fig.axes.get_xaxis().set_visible(False)
            fig.axes.get_yaxis().set_visible(False)
            plt.savefig(str(random.randint(0,10000))+".png")
            #plt.show()
            plt.close()
    
    
    
        def drawChar(self,digit):
            plt.figure()
            fig=plt.imshow(np.asarray(digit).reshape(28,28),clim=(-1,1.0),origin='upper')
            fig.set_cmap('gray_r')
            fig.axes.get_xaxis().set_visible(False)
            fig.axes.get_yaxis().set_visible(False)
            plt.show()
            plt.close()
    
    
        def drawSmpl(self):
            for img in self.imgTrainSmpl:
                self.drawChar(img) 
    
    
        def singleStep(self):
            self.val, self.vec = np.linalg.eig(np.cov(np.array(self.imgTrainSmpl).transpose()))
            self.srtd = np.argsort(self.val)[::-1]
            print self.val
    
    
    #asnmnt4=PCAMNIST()
    #asnmnt4.singleStep()
    asnmnt4=PCAMNIST()
    asnmnt4.subMean()
    asnmnt4.getCov()
    asnmnt4.getEigen()
    asnmnt4.sortEV()
    asnmnt4.drawEig()
    #asnmnt4.plotVal()
    """
    asnmnt4.getSorted()
    asnmnt4.printTopEigenVal()
    """
    
    尽管上述代码运行良好,且所有数组大小都与给定的数据集匹配,但它会生成以下图像作为特征向量:


    显然,特征向量没有任何意义,因为它们必须表示数据集的特征,在这种情况下,这些特征应该是数字。感谢您的帮助。如果您试图运行此代码,您可能必须安装MNIST软件包并从链接下载数据。

    您正在绘制特征向量矩阵的行。本征向量位于矩阵的列中,如中所示

    你应该改变

    self.eigVec.append(tmpEigVec.tolist())
    


    我相信它会像预期的那样工作。

    正如一些用户指出的,问题在于特征向量使其工作,而不是改变附加逻辑,只需修改draw函数,如下所示:

    def drawEig(self):
            for vec in self.srtdEigVecArr.T[:10]:
                self.drawEigV(vec)
    
    现在,特征向量是有意义的:

    另一位用户也指出了同样的问题;他删除了他的解决方案,因为它以一种奇怪的方式附加到列表中,使得形状为(1784784,1),这导致了数组值错误。但感谢您指出这一点,任何替代解决方案都是值得赞赏的。好吧,也许有更好的解决方案,但我相信问题的根源是我在这里提到的:特征向量在列中,而不是在行中。您有什么理由不使用scikit learn这样的工具,而是手动执行此操作?这里有一个在不同数字数据集上使用PCA的示例:只是为了通过艰苦的方式学习。
    def drawEig(self):
            for vec in self.srtdEigVecArr.T[:10]:
                self.drawEigV(vec)