2013-04-08 3 views
3

Я пытаюсь сделать анализ основных компонентов (PCA) с помощью python. Вот мой код:Ошибка 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([d1,d2*d3]) на b = np.zeros([d2*d3, d1]) я получил ValueError: could not broadcast input array from shape (2760) into shape (112)

кто-нибудь может мне помочь?

ответ

2

Если вы смените b = np.zeros([d2*d3, d1]) вы должны также изменить цикл после этого в противном случае вы пытаетесь поместить массив d1 Dimention в 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, создайте список целых циклов над ним, а затем повторно подключитесь к images. enumerate возвращает итератор с паролем (индекс, значение). Преимущества заключаются в том, что он возвращает только те элементы, которые вам нужны, а затем вам не нужно получать доступ к images непосредственно в цикле.

Возможно, вам также не нужно создавать images, но я не знаю PIL, поэтому я не могу вам помочь. В этом случае, вы можете просто получить размеры с чем-то вроде

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

EDIT

вас, если вы хотите, вы также можете преобразовать содержание файлов Numpy при чтении их.

Для записей это numpy.asarray.

+1

Спасибо за помощь. Я понял, что это более логично, но при попытке кода, который вы предложили избавиться от второй ошибки, я получил еще одну ошибку: 'AttributeError: flatten' – user2229953

+1

Я предполагал, что элементы' img' были numpy массивы. См. Мое редактирование –

+0

снова. У меня есть ошибка, аналогичная второй ошибке: 'ValueError: не удалось передать входной массив из формы (10304) в форму (2760)' – user2229953

Смежные вопросы