Добро пожаловать в блог этой недели! В нашем последнем посте мы обсудили концепцию уменьшения размерности в науке о данных и то, как ее можно применять в других областях. Если вы хотите получить общее представление о снижении размерности, я настоятельно рекомендую прочитать первую часть нашего руководства: Укрощение сложности нелинейных данных: Учебное пособие по методам уменьшения размерности, часть I.

Сегодня мы углубимся в один из наиболее часто используемых методов уменьшения размерности: анализ основных компонентов (PCA). Мы также исследуем его отношение к разнообразному обучению. Итак, приступим!

Краткий обзор многообразного обучения и PCA

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

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

Интуитивно понятный PCA

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

Хотя это немного упрощено, самое простое объяснение состоит в том, что PCA пытается подогнать к данным n-мерный эллипс.

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

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

PCA основан на линейной алгебре и может быть реализован с использованием различных алгоритмов, таких как разложение по сингулярным числам (SVD) или собственное разложение ковариационной матрицы.

Как выполнить ПКА

Вот общие шаги для выполнения анализа основных компонентов (PCA):

  1. Стандартизируйте данные: PCA чувствителен к масштабу данных, поэтому первым шагом является стандартизация данных путем вычитания среднего значения и деления на стандартное отклонение.
  2. Вычислите ковариационную матрицу: Ковариационная матрица описывает отношения между парами переменных в данных. Он вычисляется путем скалярного произведения матрицы стандартизированных данных с ее транспонированием.
  3. Вычислите собственные векторы и собственные значения ковариационной матрицы: собственные векторы ковариационной матрицы представляют направления максимальной дисперсии данных, а соответствующие собственные значения представляют величину дисперсии, объясняемую каждым собственным вектором.
  4. Выберите количество основных компонентов. Количество сохраняемых основных компонентов часто выбирается на основе величины объясненной дисперсии. Общее эмпирическое правило состоит в том, чтобы сохранить достаточно основных компонентов, чтобы объяснить не менее 70–80% общей дисперсии.
  5. Спроецируйте данные на основные компоненты. Последний шаг — проецирование стандартизированных данных на выбранные основные компоненты. Это приводит к новому набору переменных, которые не коррелированы и отсортированы по величине дисперсии, которую они объясняют.

PCA можно выполнять с использованием различных пакетов программного обеспечения, включая scikit-learn Python, MATLAB и R. Однако конкретные детали реализации могут различаться в зависимости от пакета программного обеспечения и выбранных конкретных параметров.

Давайте сделаем это шаг за шагом

Давайте начнем с генерации некоторых данных.

# import necessary libraries
import numpy as np
import matplotlib.pyplot as plt

# generate data.
# points are sampled from a two dimensional normal distribution 
# user defined given mean and covariance matrix.

np.random.seed(19680801) # for reproducibilty

n = 1000
mean = np.array([3,5])
cov = np.array([[6, -4], [-4, 3.5]])

x, y = np.random.multivariate_normal(mean, cov, n).T
X = np.array([x,y]).T
plt.scatter(X[:,0],X[:,1])
plt.axis('equal')
plt.show()

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

Математические шаги для стандартизации данных следующие:

  1. Вычислите среднее значение каждого признака/столбца: μᵢ = (1/n) ∑xᵢ, где xᵢ — i-е значение признака, а n — количество выборок в наборе данных.
  2. Рассчитайте стандартное отклонение каждого признака/столбца: σᵢ = √((1/n) ∑(xᵢ-μᵢ)²), где xᵢ — i-е значение признака, а n — количество выборок в наборе данных.
  3. Стандартизируйте данные, вычитая среднее значение и разделив на стандартное отклонение: zᵢ = (xᵢ — μᵢ)/σᵢ, где xᵢ — значение i-го признака, μᵢ — среднее значение i-го признака, а σᵢ — стандарт отклонение i-го признака.

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

# Calculate the mean of each feature/column
means = np.mean(X,axis=0)

# Calculate the standard deviation of each feature/column
stds = np.std(X,axis=0)

# Standardize the data by subtracting the mean and dividing by the standard deviation
Xs = (X-means) / stds

# check standardized X (aka Xs) has mean of 0 and std of 1 in each column
print("Means of each feature in standardized X:")
print(np.mean(Xs,axis=0))
print("Standard deviations of each feature in standardized X:")
print(np.std(Xs,axis=0))

# Plot the data together
fig, ax = plt.subplots()
plt.scatter(X[:,0],X[:,1], label="Original data")
plt.scatter(Xs[:,0],Xs[:,1], label="Standardized data")
ax.legend()
plt.axis('equal')
plt.show()

Если вы запустите приведенный выше код, вы увидите, что стандартизированное среднее численно равно нулю, а стандартное отклонение равно 1.

После того, как данные стандартизированы, математические шаги для вычисления ковариационной матрицы выглядят следующим образом:

  1. Создайте матрицу X, содержащую стандартизированные данные, где каждая строка соответствует образцу, а каждый столбец соответствует признаку.
  2. Вычислите транспонирование X, обозначаемое как Xᵀ.
  3. Вычислите скалярное произведение Xᵀ с X, чтобы получить ковариационную матрицу C: C = (1/n) XᵀX, где n — количество выборок в наборе данных.

Обратите внимание, что ковариационная матрица представляет собой квадратную матрицу с размерами, равными количеству признаков в наборе данных. Элемент Cᵢⱼ в ковариационной матрице представляет собой ковариацию между i-м и j-м признаками. Если Cᵢⱼ положительный, это указывает на то, что эти две функции имеют тенденцию изменяться вместе в одном направлении, а если он отрицательный, это указывает на то, что они имеют тенденцию изменяться в противоположных направлениях. Если Cᵢⱼ близок к нулю, это указывает на то, что эти две функции не коррелированы.

# Calculate covariance matrix
C = 1/n * np.matmul(Xs.T,Xs) # or np.cov(Xs.T)

Математические шаги для вычисления собственных векторов и собственных значений ковариационной матрицы следующие:

  1. Имея ковариационную матрицу C, вычислите ее собственные значения λ и собственные векторы v, решив следующее уравнение: Cv = λv, где v — собственный вектор матрицы C, а λ — соответствующее собственное значение.
  2. Перепишите приведенное выше уравнение следующим образом: (C — λI)v = 0, где I — единичная матрица того же размера, что и C.
  3. Найдите λ, найдя значения λ, которые удовлетворяют уравнению: det(C — λI) = 0, где det() — определяющая функция.
  4. Как только собственные значения найдены, найдите соответствующие собственные векторы v, решив уравнение: (C — λI)v = 0
  5. Нормализуйте каждый собственный вектор v, разделив его на длину, т. е. вычислив квадратный корень из суммы квадратов его элементов: v_normalized = v / ||v||
  6. Расположите собственные векторы v в матрице V так, чтобы каждый столбец матрицы V соответствовал собственному вектору, отсортированному в порядке убывания их соответствующих собственных значений.

Обратите внимание, что собственные векторы и собственные значения ковариационной матрицы важны для выполнения анализа главных компонентов (PCA), поскольку собственные векторы формируют основу для главных компонентов, а собственные значения указывают дисперсию, объясняемую каждым главным компонентом.

# calculate eigenvalues and eigenvectors
eigvals, eigvecs = np.linalg.eig(C) 

# Previous step might not provide sorted eigenvalues and eigenvectors. 
# We need to sort manually here.
idx = eigvals.argsort()[::-1]   
eigvals = eigvals[idx]
eigvecs = eigvecs[:,idx]

PCA включает в себя выбор количества сохраняемых основных компонентов. Это решение часто основывается на величине дисперсии, объясняемой каждым основным компонентом, а также на конкретных потребностях анализа.

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

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

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

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

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

# Select the number of components.
# Since our data is two dimensional in the original form, let's project it
# to one dimension.
k = 1

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

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

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

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

# Project the data onto the principal components
selected_dirs = eigvecs[:,0:k]
projection = np.matmul(Xs,selected_dirs)

# These points lie in the direction of the first eigenvector, 
# let's find the coordinates
Xs_new = np.matmul(projection,selected_dirs.T)

# Transform the standardized projected coordinates to original
X_new = Xs_new * stds + means

fig, ax = plt.subplots()
plt.scatter(X[:,0],X[:,1], label="Original")
plt.scatter(Xs[:,0],Xs[:,1], label="Standardized")
plt.scatter(Xs_new[:,0],Xs_new[:,1], label="Reduced standardized")
plt.scatter(X_new[:,0],X_new[:,1], label="Reduced standardized transformed")
ax.legend()
plt.axis('equal')
plt.show()

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

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

# Using one of the standard libraries
from sklearn.decomposition import PCA

pca = PCA(n_components=1)
pca.fit(X)
X_pca = pca.transform(X)
X_new = pca.inverse_transform(X_pca)

plt.scatter(X[:, 0], X[:, 1], alpha=0.2)
plt.scatter(X_new[:, 0], X_new[:, 1], alpha=0.8)
plt.axis('equal');

Что дальше?

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

Заключительные комментарии

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