Внедрение PCA с Numpy - PullRequest
       14

Внедрение PCA с Numpy

4 голосов
/ 02 ноября 2019

Я хотел реализовать PCA с классом, аналогичным классу в sklearn.

Мой алгоритм поиска PCA с k основным компонентом следующий:

  • Вычислитьвыберите среднее значение и переведите набор данных так, чтобы он центрировался вокруг начала координат.
  • Вычислите ковариационную матрицу нового переведенного набора.
  • Найдите собственные значения и собственные векторы, отсортируйте их в порядке убывания.
  • Проецирование набора данных на векторное пространство, охватываемое первыми k собственными векторами.
import numpy as np


class MyPCA:
    def __init__(self, n_components):
        self.n_components = n_components

    def fit_transform(self, X):
        """
        Assumes observations in X are passed as rows of a numpy array.
        """

        # Translate the dataset so it's centered around 0
        translated_X = X - np.mean(X, axis=0)

        # Calculate the eigenvalues and eigenvectors of the covariance matrix
        e_values, e_vectors = np.linalg.eigh(np.cov(translated_X.T))

        # Sort eigenvalues and their eigenvectors in descending order
        e_ind_order = np.flip(e_values.argsort())
        e_values = e_values[e_ind_order]
        e_vectors = e_vectors[e_ind_order]

        # Save the first n_components eigenvectors as principal components
        principal_components = np.take(e_vectors, np.arange(self.n_components), axis=0)

        return np.matmul(translated_X, principal_components.T)

Однако при работе с набором данных Iris эта реализация дает совершенно другие результаты, чем у sklearn, ирезультаты не показывают, что в данных есть три разные группы:

from sklearn import datasets
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt


def plot_pca_results(pca_class, dataset, plot_title):
    X = dataset.data
    y = dataset.target
    y_names = dataset.target_names

    pca = pca_class(n_components=1)
    B = pca.fit_transform(X)
    B = np.concatenate([B, np.zeros_like(B)], 1)

    scatter = plt.scatter(B[:, 0], B[:, 1], c=y)
    scatter_objects, _ = scatter.legend_elements()
    plt.title(plot_title)
    plt.legend(scatter_objects, y_names, loc="lower left", title="Classes")
    plt.show()


dataset = datasets.load_iris()
plot_pca_results(MyPCA, dataset, "Iris - my PCA")
plot_pca_results(PCA, dataset, "Iris - Sklearn")

Results of my PCA Intended results

Что можетбыть причиной для таких различий? Где мой подход или мои расчеты неверны?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...