PCA для KNN в numpy

Мне было поручено реализовать мой код PCA для преобразования данных в двумерное поле для назначения KNN. Мой код PCA создает массив с собственными векторами, называемыми PCevecs.

def __PCA(data):
   #Normalize data
   data_cent = data-np.mean(data)

   #calculate covariance
   covarianceMatrix = np.cov(data_cent, bias=True)

   #Find eigenvector and eigenvalue
   eigenvalue, eigenvector= np.linalg.eigh(covarianceMatrix)

   #Sorting the eigenvectors and eigenvalues:
   PCevals = eigenvalue[::-1]
   PCevecs = eigenvector[:,::-1]

   return PCevals, PCevecs

Назначение преобразует обучающие данные с использованием PCA. Возвращенный PCevecs имеет форму (88, 88), заданную вызовом print(PCevecs.shape). Форма обучающих данных (88, 4).

np.dot(trainingFeatures, PCevecs[:, 0:2])

Когда код работает, я получаю сообщение об ошибке «ValueError: фигуры (88,4) и (88,2) не выровнены: 4 (тусклый 1)! = 88 (тусклый 0)». Я вижу, что массивы не совпадают, но я не вижу, что я сделал что-то не так с реализацией PCA. Я пытался посмотреть на подобные проблемы на Stackoverflow. Я не видел, чтобы кто-нибудь сортировал собственные вектора и собственные значения одинаково.


person NBuch    schedule 30.03.2020    source источник
comment
Чего вы хотите добиться с помощью операции np.dot()?   -  person norok2    schedule 30.03.2020


Ответы (1)


(ОТРЕДАКТИРОВАНО с дополнительной информацией из комментариев)

Хотя реализация PCA в целом в порядке, вы можете либо вычислить ее на транспонированных данных, либо убедиться, что вы сообщаете np.cov(), по какой оси ваша размерность определяется параметром rowvar.

Следующее будет работать так, как вы ожидаете:

import numpy as np


def __PCA_fixed(data, rowvar=False):
   # Normalize data
   data_cent = data - np.mean(data)

   # calculate covariance (pass `rowvar` to `np.cov()`)
   covarianceMatrix = np.cov(data_cent, rowvar=rowvar, bias=True)  
   # Find eigenvector and eigenvalue
   eigenvalue, eigenvector= np.linalg.eigh(covarianceMatrix)

   # Sorting the eigenvectors and eigenvalues:
   PCevals = eigenvalue[::-1]
   PCevecs = eigenvector[:,::-1]

   return PCevals, PCevecs

Тестирование с некоторыми случайными числами:

data = np.random.randint(0, 100, (100, 10))
PCevals, PCevecs = __PCA_fixed(data)
print(PCevecs.shape)
# (10, 10)

Также обратите внимание, что в более общем плане разложение по единственному значению (np.linalg.svd() в NumPy) может быть лучшим подходом для анализ главных компонентовпростая связь с декомпозицией собственного значения, которую вы используете и перестановкой).


В качестве примечания к общему стилю кодирования рекомендуется следовать советам PEP. -8, многие из которых могут быть легко проверены с помощью какого-либо автоматизированного инструмента, такого как, например. autopep8.

person norok2    schedule 30.03.2020
comment
‹code› np.dot(trainingFeatures, PCevecs[:,0:2] ‹code› указан в задании. Было бы странно, если бы мне пришлось менять часть магистрали. Я подумал, вычислив собственный вектор и взяв скалярное произведение , вы бы спроецировали данные на то, что в данном случае было бы двумерным полем. Не могли бы вы уточнить нарезку массива? - person NBuch; 30.03.2020
comment
Это может помочь, если я немного уточню текст задания. В нем говорится: Используйте PCA для преобразования данных из 4D в 2D, сохраняя только 2 наиболее репрезентативных собственных вектора. Набор данных представляет собой базу данных цветов ириса. Существует 3 типа радужной оболочки, и каждая характеризуется 4 атрибутами. - person NBuch; 30.03.2020