使用python的主成分分析(PCA)

使用python的主成分分析(PCA),python,arrays,matrix,numpy,face-recognition,Python,Arrays,Matrix,Numpy,Face Recognition,我正在尝试使用python通过主成分分析(PCA)实现人脸识别。我将按照本教程中的步骤进行操作: 这是我的密码: import os from PIL import Image import numpy as np import glob import numpy.linalg as linalg #Step1: put database images into a 2D array filenames = glob.glob('C:\\Users\\Karim\\Downloads\\at

我正在尝试使用python通过主成分分析(PCA)实现人脸识别。我将按照本教程中的步骤进行操作:

这是我的密码:

import os
from PIL import Image
import numpy as np
import glob
import numpy.linalg as linalg


#Step1: put database images into a 2D array
filenames = glob.glob('C:\\Users\\Karim\\Downloads\\att_faces\\New folder/*.pgm')
filenames.sort()
img = [Image.open(fn).convert('L').resize((90, 90)) for fn in filenames]
images = np.asarray([np.array(im).flatten() for im in img])


#Step 2: find the mean image and the mean-shifted input images
mean_image = images.mean(axis=0)
shifted_images = images - mean_image


#Step 3: Covariance
c = np.cov(shifted_images)


#Step 4: Sorted eigenvalues and eigenvectors
eigenvalues,eigenvectors = linalg.eig(c)
idx = np.argsort(-eigenvalues)
eigenvalues = eigenvalues[idx]
eigenvectors = eigenvectors[:, idx]


#Step 5: Only keep the top 'num_eigenfaces' eigenvectors
num_components = 20
eigenvalues = eigenvalues[0:num_components].copy()
eigenvectors = eigenvectors[:, 0:num_components].copy()


#Step 6: Finding weights
w = eigenvectors.T * np.asmatrix(shifted_images)


#Step 7: Input image
input_image = Image.open('C:\\Users\\Karim\\Downloads\\att_faces\\1.pgm').convert('L').resize((90, 90))
input_image = np.asarray(input_image)


#Step 8: get the normalized image, covariance, eigenvalues and eigenvectors for input image
shifted_in = input_image - mean_image
cov = np.cov(shifted_in)
eigenvalues_in, eigenvectors_in = linalg.eig(cov)
我得到一个错误:
回溯(最近一次呼叫最后一次):
文件“C:/Users/Karim/Desktop/bacher 2/New folder/new3.py”,第47行,在
移位图像=输入图像-平均图像
ValueError:操作数无法与形状(90,90)(8100)一起广播。

我试图从步骤1中删除
.flatte()
,但这在计算特征值和特征向量时产生了另一个错误:
回溯(最近一次呼叫最后一次):
文件“C:/Users/Karim/Desktop/bacher 2/New folder/new3.py”,第25行,在
特征值,特征向量=linalg.eig(c)
文件“C:\Python27\lib\site packages\numpy\linalg\linalg.py”,第1016行,在eig中
_资产等级2(a)
文件“C:\Python27\lib\site packages\numpy\linalg\linalg.py”,第155行,位于\u assertRank2中
'二维''%len(a.shape))
LinalError:给定了4维数组。数组必须是二维的

我还尝试将
.flatte()
添加到步骤7,但在计算输入图像的特征值和特征向量时,它也产生了另一个错误:
回溯(最近一次呼叫最后一次):
文件“C:/Users/Karim/Desktop/bacher 2/New folder/new3.py”,第49行,在
特征值_in,特征向量_in=linalg.eig(cov)
文件“C:\Python27\lib\site packages\numpy\linalg\linalg.py”,第1016行,在eig中
_资产等级2(a)
文件“C:\Python27\lib\site packages\numpy\linalg\linalg.py”,第155行,位于\u assertRank2中
'二维''%len(a.shape))
LinalError:给定了0维数组。数组必须是二维的


任何人都可以提供帮助???

我终于看了您提供的教程,似乎作者建议您将图像展平。您现在还可以继续使用展平阵列,因为它与该教程更匹配

我相信在第7步中可以解决这个问题,在这里你可以得到输入图像的协方差。但是,输入图像的协方差矩阵将是一个标量,您无法找到它的特征值和特征向量。您可以将其投影为大小为
(1,1)
的2d矩阵,但该矩阵的特征值仅为协方差,特征向量为
[[1]]

就是比如说,

In [563]: input_image = np.random.rand(90,90).flatten()

In [564]: c = np.cov(input_image)

In [565]: c
Out[565]: array(0.08280644230318886)

In [566]: c.shape
Out[566]: ()

In [567]: c.ndim
Out[567]: 0
因此,我们将
c
重塑为2d:

In [568]: cmat = c.reshape(1,1) # equivalent to cmat = c[...,np.newaxis,np.newaxis]

In [569]: cmat
Out[569]: array([[ 0.08280644]])

In [570]: cmat.shape
Out[570]: (1, 1)

In [571]: cmat.ndim
Out[571]: 2
现在我们可以找到本征函数:

In [572]: ceigval, ceigvec = linalg.eig(cmat)
但是对于一个元素矩阵,只有一个特征值和一个特征向量,特征值是矩阵的元素,特征向量是长度为1的单位向量/恒等式,所以我不确定这是否真的是你想要做的人脸识别

In [573]: ceigval
Out[573]: array([ 0.08280644])

In [574]: ceigvec
Out[574]: array([[ 1.]])

In [576]: np.isclose(c, ceigval)
Out[576]: True
顺便说一下,这就是为什么我们必须制作
c
2d:

In [577]: linalg.eig(c)
---------------------------------------------------------------------------
LinAlgError: 0-dimensional array given. Array must be two-dimensional

另一方面,您可以得到未展平输入图像的协方差,然后您将得到
N
特征值和
N
特征向量:

In [582]: input_image = np.random.rand(90,90)

In [583]: c = np.cov(input_image)

In [584]: c.shape
Out[584]: (90, 90)

In [585]: ceigval, ceigvec = linalg.eig(c)

In [586]: ceigval.shape
Out[586]: (90,)

In [587]: ceigvec.shape
Out[587]: (90, 90)

关于输入图像的协方差,您是对的。谢谢你那句有用的话,但老实说,我不明白你说的投影它是2d的意思matrix@user2229953我已经用一个例子说明了这一点。