2013-04-08 112 views
3

我正在嘗試使用python進行主成分分析(PCA)。這裏是我的代碼:Python - 主成分分析(PCA)錯誤

import os 
from PIL import Image 
import numpy as np 
import glob 
from matplotlib.mlab import PCA 

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

# Step2: create 2D flattened version of 3D input array 
d1,d2,d3 = images.shape 
b = np.zeros([d1,d2*d3]) 
for i in range(len(images)): 
    b[i] = images[i].flatten() 

#Step 3: PCA 
results = PCA(b) 
results.Wt 

但我得到一個錯誤RuntimeError: we assume data in a is organized with numrows>numcols

我試圖通過b = np.zeros([d2*d3, d1])更換b = np.zeros([d1,d2*d3])ValueError: could not broadcast input array from shape (2760) into shape (112)

誰能幫助我?

回答

2

如果更改爲 b = np.zeros([d2*d3, d1])你也應該改變循環之後,否則你嘗試將 d1漁政船陣成 d2*d3之一。

你應該擺脫的第二個錯誤做的這個

你可以簡單地轉b

# Step2: create 2D flattened version of 3D input array 
d1,d2,d3 = images.shape 
b = np.empty([d1,d2*d3]) #if you know that you are filling the whole array it's faster that using np.zeros or np.ones 
for i, im in enumerate(images): 
    b[i,:] = im.flatten() 

#Step 3: PCA 
results = PCA(b.T) 

我也有我的想法是一個更好的版本取代你的循環:在你的實現你首先找到images的維度,創建一個整數列表循環它,然後重新訪問imagesenumerate返回一個有一對(索引,值)的迭代器。好處是它只返回你需要的元素,然後你不必直接在循環中訪問images

也許你也不需要創建images,但我不知道PIL,所以我不能幫你。在這種情況下,你可以簡單地得到的東西的尺寸一樣

d1,d2,d3 = len(img), img[0].shape 

編輯

你,如果你願意,你也可以轉換的文件的內容,閱讀時他們NumPy的。

有關記錄,這是numpy.asarray

+1

感謝您的幫助。我明白了你的觀點,並且我發現它更符合邏輯,但是在嘗試代碼時,建議擺脫第二個錯誤,我得到了另一個錯誤:'AttributeError:flatten' – user2229953 2013-04-09 09:40:27

+1

我假設'img'的元素是numpy陣列。再次看到我的編輯 – 2013-04-09 09:42:14

+0

我得到了類似於第二個錯誤的錯誤:'ValueError:無法將形狀(10304)中的輸入數組廣播到形狀(2760)' – user2229953 2013-04-09 10:08:55