В этой статье я математически выведу, как работает PCA, и реализую его на Python как с нуля, так и с помощью scikit learn.

Снижение размерности относится к методам уменьшения количества функций / переменных в наших данных. Мы уменьшаем размерность до:

  • Визуализируйте многомерные данные на 2D-графиках.
  • Избавьтесь от коррелированных и повторяющихся функций.
  • Не допускайте переобучения данных.
  • Преодолейте ПРОКЛЯТИЕ ИЗМЕРЕНИЯ.

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

Геометрическая интерпретация PCA

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

ПРИМЕЧАНИЕ. Всегда СТАНДАРТИЗИРУЙТЕ свои данные перед применением PCA.

Предположим, у нас есть следующие стандартизированные данные:

Если предположить, что вам нужно выбрать 1 функцию из X1 и X2, какую функцию вы выберете для представления данных? Какая функция, по вашему мнению, кажется более важной? Тот, который объясняет максимальное разброс данных. Это особенность X1. Это именно то, что делает PCA. Он находит функции, которые имеют максимальный разброс, и отбрасывает другие, чтобы минимизировать потерю информации.

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

Здесь обе характеристики X1 и X2 имеют равный разброс. Поэтому мы не можем сказать, какая функция важнее. Но если мы попытаемся найти направление (или ось), которое объясняет изменение данных, мы можем найти линию, которая очень хорошо соответствует данным. Итак, если мы немного повернем нашу ось на theta, мы получим f1 и f2 (перпендикулярно f1). Затем мы можем отбросить f2 и сказать, что f1 - самая важная функция.

Это именно то, что делает PCA. Он берет данные и пытается найти направление f1, такое, чтобы отклонение точек, проецируемых на f1, было максимальным.

Обратите внимание, что мы трансформируем наши данные, создавая новые функции.

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

Математика, лежащая в основе PCA

Наша цель - найти направление с максимальным спредом и спроецировать точки данных в этом направлении.

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

Этот подход называется подходом максимизации дисперсии. Есть еще один способ построения функции оптимизации для PCA.

Другой способ думать о PCA - это то, что он соответствует наилучшей линии, которая проходит через наши данные, с целью минимизировать ошибку проекции d для каждой точки. Этот подход называется подходом минимизации расстояния .

Обратите внимание, что обе проблемы оптимизации, хотя и выглядят по-разному, но одинаковы. Поскольку член (x ^ T * x) не зависит от u, поэтому, чтобы минимизировать функцию, мы должны максимизировать (u ^ t * u) ², что совпадает с нашей первой задачей оптимизации.

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

Предположим, X - наша матрица данных с n наблюдениями и d функциями.

  1. Матрица ковариаций

Ковариационная матрица (или ковариационная матрица дисперсии) представляет собой квадратную матрицу формы = количество функций, диагональные элементы которой представляют собой дисперсию каждой функции, а недиагональные элементы - ковариацию между функциями.

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

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

Решение проблемы оптимизации

Давайте еще раз посмотрим на нашу задачу оптимизации.

Теперь давайте попробуем решить нашу модифицированную задачу оптимизации с помощью множителя Лагранжа.

Пусть лямбда будет множителем нашего лагранжа.

Таким образом, u - собственный вектор ковариационной матрицы S, соответствующий наибольшему собственному значению лямбда.

Давайте еще раз напишем все шаги:

Предположим, наша матрица данных X имеет d функций, и мы хотим сократить их до k функций.

  1. Столбец стандартизирует ваши данные.
  2. Найдите ковариационную матрицу.
  3. Найдите все собственные значения и собственные векторы ковариационной матрицы.
  4. Тогда v1, соответствующее наибольшему собственному значению lambda1, - это направление с максимальной дисперсией, v2, соответствующее лямбда 2, - направление со второй максимальной дисперсией и так далее.
  5. Чтобы получить k функций, умножьте исходную матрицу данных на матрицу собственных векторов, соответствующих верхним k наибольшим собственным значениям.

Результирующая матрица - это матрица с сокращенными функциями.

Давайте разберемся с интерпретацией собственных значений.

PCA на Python

Я использую PCA для набора данных iris. Ссылка:

С нуля

#Importing the data
data= pd.read_csv("Iris.csv")
data.head()

X = data.iloc[:, 0:4]
y = data.species
#Step 1: Let's scale the data.
from sklearn.preprocessing import StandardScaler
X_scaled = StandardScaler().fit_transform(X)
#Step 2: Find the covariance matrix.
covar_matrix = (1 / X_scaled.shape[0]) * np.matmul(X_scaled.T,X_scaled)
print (covar_matrix.shape)

#Step 3: Find the eigenvalues and eigenvectors.
from scipy.linalg import eigh
#eigh function returns the eigenvalues in ascending order
#We specify the top 2 eigenvalues (out of 0, 1, 2, 3)
values, vectors = eigh(covar_matrix, eigvals=(2, 3))
print (vectors.shape)
print (vectors)

#Step 4: Project the original data on eigenvectors.
pca_components = np.matmul(X_scaled, vectors)
pca_data = pd.DataFrame(np.hstack((pca_components, y.to_numpy().reshape(-1, 1))), columns=["Component 1", "Component 2", "Species"])
pca_data.head()

#Let's calculate the percentage of variation explained.
print (values.sum() / eigh(covar_matrix)[0].sum() * 100)

#Now let’s plot the principal components.
sns.scatterplot(x= "Component 1", y= "Component 2", hue= "Species", data= pca_data)

Использование scikit learn

from sklearn.decomposition import PCA
#Using the n_components argument
pca = PCA(n_components= 2)
pca_components = pca.fit_transform(X_scaled)
pca_data = pd.DataFrame(np.hstack((pca_components, y.to_numpy().reshape(-1, 1))), columns=["Component 1", "Component 2", "Species"])
pca_data.head()

Обратите внимание, что в реализации sklearn компоненты поменялись местами.

print (pca.explained_variance_ratio_.sum() *100)

sns.scatterplot(x= “Component 1”, y= “Component 2”, hue= “Species”, data= pca_data)

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

Вы можете связаться со мной в LinkedIn: www.linkedin.com/in/madhav-samariya-7a636b17a