Выполнение PCA обоими методами и сравнение результатов

Разложение по сингулярным числам (SVD) и собственное разложение (ED) — это методы матричной факторизации, основанные на линейной алгебре.

В области машинного обучения (ML) оба могут использоваться в качестве методов сокращения данных (т.е. для уменьшения размерности).

Ранее мы подробно обсуждали собственное разложение. Сегодня мы уделим больше внимания обсуждению СВД.

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

NumPy предоставляет высокоуровневые и простые в использовании функции для выполнения SVD и собственного разложения.

Topics included:
----------------
01. What is singular value decomposition?
02. SVD equation and its terms
03. Singular value decomposition in NumPy - svd() function
04. What is eigendecomposition?
05. Eigendecomposition equation and its terms
06. Eigendecomposition in NumPy - eig() function
07. Performing PCA using singular value decomposition
08. Performing PCA using eigendecomposition
09. Compare the results of both methods
10. Conclusions

Что такое сингулярное разложение?

Разложение по сингулярным числам (SVD) — это метод матричной факторизации. Это важная математическая операция, пришедшая из линейной алгебры.

Существует несколько способов разложить на множители (разложить/разложить) матрицу, как мы можем разложить число 16, например, на 2 х 8 = 16, 4 х 4 = 16, 2 х 2 х 4 = 16, 2 х 2 х 2 x 2 = 16. Не все методы факторизации одинаково важны. Это зависит от варианта использования.

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

Разложение по сингулярным числам — это процесс разложения матрицы A на произведение трех матриц, как в следующем уравнении.

  • A: Матрица, на которой мы выполняем СВД
  • U: квадратная матрица. Это называется правой сингулярной матрицей векторов.
  • Σ: диагональная матрица. Это называется матрицей сингулярных значений, которая имеет тот же размер, что и A.
  • V^T: квадратная матрица. Это называется левой сингулярной матрицей векторов. По умолчанию функция NumPy SVD возвращает V^T, что является преобразованием V.

Матрица A может быть квадратной или неквадратной, поскольку SVD определен как для квадратных, так и для неквадратных матриц. Напротив, собственное разложение определено только для квадратных матриц.

Матрица Σ содержит сингулярные значения, которые всегда неотрицательны. Могут быть включены нулевые значения.

Количество ненулевых сингулярных значений равно рангу матрицы A.

Разложение по сингулярным значениям в NumPy

В NumPy SVD можно легко выполнить с помощью функции svd(). Вот пример.

import numpy as np
A = np.array([[2, 4, 1],
              [5, 7, 6],
              [1, 1, 3]])

U, s, Vt = np.linalg.svd(A)

print("A")
print(A)
print("\nU")
print(U)
print("\ns")
print(s)
print("\nVt")
print(Vt)

Функция NumPy svd() возвращает Σ (матрицу единственного числа) в виде вектора (обозначаемого s), а не диагональной матрицы. Этот вектор содержит все сингулярные значения A.

Если вы хотите получить Σ как есть, вы можете внести некоторые изменения, используя следующий код.

S = np.zeros(np.shape(A))
np.fill_diagonal(S,s)
print(S)

Если вам нужно вычислить только сингулярные значения и не нужны матрицы U и Vt, вы можете запустить следующий код.

s = np.linalg.svd(A, compute_uv=False)
print(s)

Вот как мы можем выполнить SVD в NumPy. Это намного проще, чем вы думаете. Далее мы перейдем к части собственного разложения.

Что такое собственное разложение?

Собственное разложение — еще один важный метод факторизации матриц.

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

  • A: Матрица, на которой мы выполняем собственное разложение. Это должна быть квадратная матрица.
  • λ: скаляр, называемый собственным значением.
  • x: вектор, называемый собственным вектором.

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

Собственные значения могут быть положительными или отрицательными.

Собственные значения и собственные векторы идут парами. Такая пара называется собственной парой. Таким образом, матрица A может иметь несколько таких собственных пар. Приведенное выше уравнение показывает связь между A и одной из его собственных пар [ссылка: Собственное разложение ковариационной матрицы с помощью NumPy]

Собственное разложение в NumPy

В NumPy собственное разложение можно легко выполнить с помощью функции eig(). Вот пример.

import numpy as np
A = np.array([[2, 4, 1],
              [5, 7, 6],
              [1, 1, 3]])

eigen_vals, eigen_vecs = np.linalg.eig(A)

print("A")
print(A)
print("\nEigenvalues")
print(eigen_vals)
print("\nEigenvectors")
print(eigen_vecs)

Функция NumPy eig() возвращает собственные значения в виде вектора. Этот вектор содержит все собственные значения A.

Мы выполнили как SVD, так и собственное разложение на одной и той же матрице A. Глядя на результаты, мы можем сказать, что:

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

Выполнение PCA с использованием разложения по сингулярным числам

PCA часто выполняется путем применения SVD к ковариационной матрице стандартизированных данных. Ковариационная матрица стандартизированных данных точно такая же, как корреляционная матрица нестандартизированных данных.

Мы стандартизируем данные перед SVD, потому что сингулярные значения очень чувствительны к относительным диапазонам исходных признаков.

Чтобы продемонстрировать процесс PCA с использованием SVD, мы будем использовать набор данных Wine, который имеет 13 входных функций.

Шаг 1. Получение данных Wine.

from sklearn.datasets import load_wine

wine = load_wine()
X = wine.data
y = wine.target

print("Wine dataset size:", X.shape)

Шаг 2. Стандартизация данных.

from sklearn.preprocessing import StandardScaler

X_scaled = StandardScaler().fit_transform(X)

Шаг 3. Вычисление ковариационной матрицы стандартизированных данных.

import numpy as np
cov_mat = np.cov(X_scaled.T)

Шаг 4. Выполнение SVD на ковариационной матрице и получение сингулярных значений ковариационной матрицы.

U, s, Vt = np.linalg.svd(cov_mat)
print(s)

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

Шаг 5. Преобразование единичных значений в объясненную дисперсию.

exp_var = (s / np.sum(s)) * 100
print(exp_var)

Первый компонент отражает 36,2-процентную дисперсию данных. Второй компонент фиксирует 19,2-процентную дисперсию данных и так далее.

Шаг 6. Визуализация сингулярных значений для выбора правильного количества компонентов

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

cum_exp_var = np.cumsum(exp_var)

# a = Number of input features + 1
a = X.shape[1] + 1

import matplotlib.pyplot as plt
plt.bar(range(1, a), exp_var, align='center',
        label='Individual explained variance')

plt.step(range(1, a), cum_exp_var, where='mid',
         label='Cumulative explained variance', color='red')

plt.ylabel('Explained variance percentage')
plt.xlabel('Principal component index')
plt.xticks(ticks=list(range(1, a)))
plt.legend(loc='best')
plt.tight_layout()

plt.savefig("cumulative explained variance plot.png")

Итак, совершенно очевидно, что первые 7 компонентов охватывают около 90% дисперсии данных. Итак, мы можем выбрать первые 7 компонентов для набора данных Wine.

Все критерии отбора смотрите здесь.

Выполнение PCA с использованием собственного разложения

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

Первые 3 шага такие же, как и раньше. Итак, я продолжу с четвертого шага.

Шаг 1, шаг 2, шаг 3. То же, что и раньше.

Шаг 4. Выполнение собственного разложения ковариационной матрицы и получение собственных значений ковариационной матрицы.

eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
print(eigen_vals)

Собственные значения точно такие же, как сингулярные значения. Причина в том, что ковариационная матрица симметрична.

В целом можно сказать, что:

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

Другими словами,

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

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

# Sort the eigenvalues in descending order
eigen_vals = np.sort(eigen_vals)[::-1]
print(eigen_vals)

Шаг 5, Шаг 6. То же, что и раньше.

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

Выводы

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

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

Это конец сегодняшней статьи.

Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы или отзывы.

Читать дальше (рекомендуется)

Как насчет курса ИИ?

Поддержите меня как автора

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



Присоединяйтесь к моему личному списку адресов электронной почты

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

Большое спасибо за вашу постоянную поддержку! Увидимся в следующей статье. Всем удачного обучения!

Информация о винном наборе данных

  • Источник набора данных: исходный набор данных можно скачать здесь.
  • Лицензия на набор данных: этот набор данных доступен по лицензии CC BY 4.0 (Creative Commons Attribution 4.0).
  • Цитирование: Личман, М. (2013). Репозиторий машинного обучения UCI [https://archive.ics.uci.edu/ml]. Ирвин, Калифорния: Калифорнийский университет, Школа информационных и компьютерных наук.

Рукшан Прамодита
20–03–2023