Метод главных компонент (PCA): цель и реализация

🎯 Что такое PCA и зачем он нужен?

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

Основные цели PCA:

  • 📉 Уменьшение размерности: Сократить количество признаков, убрав менее значимые.
  • 🔍 Визуализация: Представить многомерные данные в 2D или 3D.
  • 📊 Шумоподавление: Убрать случайные колебания в данных.

💡 PCA не выбирает отдельные признаки, а создает новые — главные компоненты — которые являются комбинациями исходных.


🧮 Математическая основа PCA

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

Шаги алгоритма:

  1. 📏 Стандартизация данных: Приводим все признаки к одному масштабу (среднее = 0, стандартное отклонение = 1).
  2. 📐 Вычисление ковариационной матрицы: Показывает, как признаки связаны между собой.
  3. 🔢 Нахождение собственных векторов и собственных значений: Собственные векторы — это направления главных компонент, а собственные значения — их важность (дисперсия).
  4. 📊 Выбор главных компонент: Сортируем компоненты по убыванию собственных значений и выбираем нужное количество.
  5. 🔄 Преобразование данных: Проецируем исходные данные на выбранные главные компоненты.

Формула стандартизации:

z = (x - mean) / std

Ковариационная матрица для двух признаков:

cov(X,Y) = Σ[(xᵢ - mean_x) * (yᵢ - mean_y)] / (n-1)

📘 Собственные векторы ковариационной матрицы указывают направления максимальной дисперсии, а собственные значения показывают величину этой дисперсии.


🛠️ Реализация PCA на Python

Давай реализуем PCA шаг за шагом на примере простого набора данных!

Сначала импортируем необходимые библиотеки:

import numpy as np
from sklearn.preprocessing import StandardScaler

Создадим синтетические данные для демонстрации:

# Создаем коррелированные данные
np.random.seed(42)
x = np.random.normal(0, 1, 100)
y = 2 * x + np.random.normal(0, 0.5, 100)
data = np.column_stack((x, y))

Теперь стандартизируем данные:

scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

Вычисляем ковариационную матрицу:

cov_matrix = np.cov(data_scaled.T)
print("Ковариационная матрица:\n", cov_matrix)

Находим собственные значения и собственные векторы:

eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
print("Собственные значения:", eigenvalues)
print("Собственные векторы:\n", eigenvectors)

Выбираем главные компоненты (сортируем по убыванию собственных значений):

# Сортируем собственные значения и векторы
idx = eigenvalues.argsort()[::-1]
eigenvalues = eigenvalues[idx]
eigenvectors = eigenvectors[:, idx]

# Выбираем первую главную компоненту
first_pc = eigenvectors[:, 0]

Преобразуем данные в новое пространство:

transformed_data = data_scaled.dot(eigenvectors)

💡 На практике обычно используют готовую реализацию PCA из библиотеки sklearn, но понимание математики важно!


📊 PCA с использованием Scikit-learn

Теперь покажем, как использовать PCA с помощью удобной библиотеки:

from sklearn.decomposition import PCA

# Создаем объект PCA с 2 компонентами
pca = PCA(n_components=2)

# Применяем к нашим данным
principal_components = pca.fit_transform(data_scaled)

# Смотрим результаты
print("Объясненная дисперсия:", pca.explained_variance_ratio_)
print("Главные компоненты:\n", principal_components[:5])

Визуализируем результат:

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 4))

# Исходные данные
plt.subplot(1, 2, 1)
plt.scatter(data_scaled[:, 0], data_scaled[:, 1])
plt.title("Исходные данные (стандартизированные)")
plt.xlabel("Признак 1")
plt.ylabel("Признак 2")

# После PCA
plt.subplot(1, 2, 2)
plt.scatter(principal_components[:, 0], principal_components[:, 1])
plt.title("После PCA")
plt.xlabel("Первая главная компонента")
plt.ylabel("Вторая главная компонента")

plt.tight_layout()
plt.show()


🎯 Как выбрать количество компонент?

Один из ключевых вопросов — сколько главных компонент оставить. Есть несколько подходов:

Метод Описание Пример
📈 Правило локтя Смотрим на график объясненной дисперсии и ищем "излом" Оставляем компоненты до резкого спада важности
🎯 Порог объясненной дисперсии Накопленная объясненная дисперсия должна быть выше порога Оставляем столько компонент, чтобы сохранить 95% дисперсии
🔢 Правило Кайзера Оставляем компоненты с собственными значениями > 1 Для стандартизированных данных

Пример выбора по порогу объясненной дисперсии:

pca = PCA()
pca.fit(data_scaled)

# Вычисляем накопленную объясненную дисперсию
cumulative_variance = np.cumsum(pca.explained_variance_ratio_)

# Находим, сколько компонент нужно для 95% дисперсии
n_components = np.argmax(cumulative_variance >= 0.95) + 1
print(f"Нужно {n_components} компонент для 95% дисперсии")


🧠 Практическая задача

Условие: У нас есть данные о покупателях с 10 признаками. Нужно уменьшить размерность так, чтобы сохранить 90% дисперсии и визуализировать данные в 2D.

Скрыть рекламу навсегда

🧠 Учёба без воды и зубрёжки

Закрытый Boosty с наработками опытного преподавателя.

Объясняю сложное так, чтобы щелкнуло.

🚀 Забрать доступ к Boosty