Анализ главных компонентов, или сокращенно PCA, — это широко используемый метод в науке о данных и машинном обучении. Это мощный инструмент, который помогает нам выявлять наиболее важные закономерности и тенденции в больших и сложных наборах данных. В этом сообщении блога мы получим некоторое представление о PCA и реализуем его самостоятельно с нуля, используя Python и NumPy.

Зачем использовать PCA?

PCA особенно полезен при работе с многомерными данными, где имеется множество переменных или функций, которые могут коррелировать друг с другом. Уменьшая количество измерений, PCA упрощает данные, не теряя при этом слишком много информации.

Одним из ключевых преимуществ PCA является то, что он может помочь нам выявить скрытые связи между переменными, которые могут быть не сразу очевидны. Найдя основную структуру данных, PCA может выявить важные идеи, которые в противном случае могли бы быть упущены. PCA также используется для ускорения обучения алгоритма за счет уменьшения количества измерений данных.

Как работает PCA?

Чтобы лучше понять PCA, давайте рассмотрим более простой сценарий, в котором мы стремимся уменьшить размерность двумерных данных до одного измерения.

Здесь проекция xk представляется как

Наша цель — определить оптимальное значение «e» для прогноза, что означает максимизацию дисперсии прогноза. По сути, мы хотим, чтобы данные были как можно шире распределены по линии проекции.

Хотя вывод и доказательство этой концепции выходят за рамки этого блога, вы можете обратиться к предоставленным ссылкам для более глубокого чтения.

PCA с использованием Sklearn

Вот пример использования PCA с использованием sklearn.

from sklearn.decomposition import PCA 
pca_mnist = PCA(n_components=5) 
X_train_dim_red = pca_mnist.fit_transform(X_train_shuffled_sample)

Реализация на питоне

1. Вычтите среднее значение из каждой переменной.

Это позволит центрировать набор данных вокруг начала координат, и это будет полезно при расчете ковариационной матрицы.

X_mean = np.mean(X,axis = 0) 
X_mean_rem = X - X_mean

2. Рассчитать ковариационную матрицу

Ковариационная матрица представляет собой квадратную матрицу, обозначающую ковариацию элементов друг с другом. Ковариация элемента сама по себе — это не что иное, как его дисперсия.

cov_mat = np.cov(X_mean_rem, rowvar = False)

3. Вычислите собственные значения и собственные векторы.

Далее нам нужно вычислить собственные значения и собственные векторы полученной ковариационной матрицы. Полученные нами собственные векторы взаимно ортогональны, и каждый вектор представляет собой главную ось.

Важно отметить, что более высокое собственное значение соответствует большей изменчивости данных. Следовательно, главная ось, связанная с наибольшим собственным значением, будет отражать наибольшую изменчивость данных.

eigen_val, eigen_vec = np.linalg.eigh(cov_mat)

4. Сортировка собственных значений

Расположите собственные значения в порядке убывания вместе с соответствующими собственными векторами. Стоит отметить, что каждый столбец матрицы собственных векторов соответствует главному компоненту. Сортируя их по собственным значениям, мы можем эффективно упорядочить главные компоненты по их соответствующим изменчивостям, причем компоненты с наибольшей изменчивостью появляются первыми.

sorted_indices = np.argsort(eigen_val)[::-1] sorted_eigen_val = eigen_val[sorted_indices] sorted_eigen_vec = eigen_vec[:,sorted_indices]

5. Берем топ D компонентов

Выберите подмножество из перестроенной матрицы собственных значений в соответствии с нашими потребностями. Нам нужно знать, что количество ненулевых собственных значений и собственных векторов, которые мы не выбираем, соответствуют количеству потерянной информации. Если данные плохо справляются с последующими задачами, такими как классификация после PCA, возможно, стоит рассмотреть возможность увеличения количества компонентов.

eigen_vec_subset = sorted_eigen_vec[:,0:self.n_components]

6. Преобразуйте данные

Наконец, преобразуйте данные, имея скалярное произведение между транспонированием подмножества собственных векторов и транспонированием среднецентрированных данных. Транспонируя результат скалярного произведения, мы получаем данные, уменьшенные до более низких измерений из более высоких измерений.

X_dim_red = np.dot(eigen_vec_subset.T, X_mean_rem.T).T

Полный код

class PCA:
    def __init__(self, n_components = 2):
        self.n_components = n_components

    def fit_transform(self, X):
        # 1. subtract mean 
        X_mean = np.mean(X,axis = 0)
        X_mean_rem = X - X_mean
        # 2. Cacluate covariance matrix
        cov_mat = np.cov(X_mean_rem, rowvar = False)
        # 3. Compute Eigen values and Eigen vectors
        eigen_val, eigen_vec = np.linalg.eigh(cov_mat)
        # 4. sort Eigen vlaues
        sorted_indices = np.argsort(eigen_val)[::-1]
        sorted_eigen_val = eigen_val[sorted_indices]
        sorted_eigen_vec = eigen_vec[:,sorted_indices]
        # 5. take top D components
        self.eigen_vec_subset = sorted_eigen_vec[:,0:self.n_components]
        # 6. Transform data
        X_dim_red = np.dot(self.eigen_vec_subset.T, X_mean_rem.T).T
        return X_dim_red

    def transform(self, X):
        # 1. subtract mean 
        X_mean = np.mean(X,axis = 0)
        X_mean_rem = X - X_mean
        # 6. Transform data
        X_dim_red = np.dot(self.eigen_vec_subset.T, X_mean_rem.T).T
        return X_dim_red

Использованная литература:

  1. Вывод и доказательство
  2. Склеарн PCA

Спасибо за прочтение…

Первоначально опубликовано на сайте mindfulmodeler.hashnode.dev.