Машинное обучение — пример визуализации PCA
Представьте, что вы убираете захламлённую комнату, заполненную разными предметами. Чтобы лучше понять планировку комнаты, вы можете сделать несколько фотографий с разных ракурсов (например, спереди, сбоку, сверху).
Анализ главных компонент (PCA)делает нечто подобное в машинном обучении.
PCA — это мощныйинструмент для снижения размерности данныхивизуализации. Когда наши данные содержат сотни или тысячи признаков (измерений), данные находятся как будто в сверхмногомерном пространстве, которое люди не могут интуитивно понять.
PCA помогает нам находить наиболее важные перспективы (т. е. главные компоненты) в данных и проецирует данные на наиболее важные два или три измерения, позволяя нам наблюдать структуру и распределение многомерных данных с помощью двумерных или трёхмерных диаграмм рассеяния.
Проще говоря, цели PCA таковы:
- Снижение размерности:Использование меньшего числа признаков для представления исходных данных, что уменьшает вычисления и объём хранения, а также удаляет шум.
- Визуализация:Сведение многомерных данных к 2D или 3D, чтобы можно было интуитивно наблюдать связи между точками данных (например, кластеризацию, разделение).
Основные принципы и рабочий процесс PCA
Основная идея PCA — найти направления, в которых дисперсия данных максимальна.
Чем больше дисперсия, тем сильнее разбросаны спроецированные точки в этом направлении и тем больше информации они содержат.
Первое найденное направление — этопервая главная компонента (PC1),а второе направление, ортогональное PC1 и имеющее следующую по величине дисперсию, — этовторая главная компонента (PC2),и так далее.
Схема рабочего процесса PCA

Ключевые шаги рабочего процесса:
Стандартизация:Сделать так, чтобы каждый признак имел среднее значение 0 и стандартное отклонение 1, обеспечивая всем признакам одинаковую важность при вычислениях.
Ковариационная матрица:Вычислить корреляции между признаками. PCA находит основные направления изменения данных, анализируя эту матрицу.
Собственные значения и собственные векторы:
- Собственные векторы:Это искомые направления главных компонент.
- Собственные значения:Они соответствуют дисперсии данных вдоль направления собственного вектора. Чем больше собственное значение, тем важнее соответствующая главная компонента.
Выбор главных компонент:Мы сортируем собственные значения от наибольшего к наименьшему и выбираем собственные векторы, соответствующие K наибольшим собственным значениям. K — это целевая размерность, до которой мы хотим уменьшить данные (например, для визуализации K=2 или 3).
Преобразование данных:Используйте выбранные K собственных векторов, чтобы сформировать матрицу проекции, затем умножьте исходные данные на эту матрицу, чтобы получить координаты в K новых главных компонентах, то есть данные после уменьшения размерности.
Практический пример: визуализация набора данных Iris
Мы будем использовать классическийнабор данных Irisдля демонстрации PCA. Этот набор данных содержит 150 образцов, каждый с 4 признаками (длина чашелистика, ширина чашелистика, длина лепестка, ширина лепестка), и относится к 3 различным видам.
Наша цель — использовать PCA, чтобы уменьшить эти 4-мерные данные до 2 измерений и построить их на 2D-плоскости, чтобы увидеть, можно ли различить разные виды цветов.
Подготовка окружения и загрузка данных
Сначала убедитесь, что у вас установлены необходимые библиотеки Python:scikit-learn, matplotlib, numpy,pandas。
Пример
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# Установить китайский шрифт и стиль графиков (необязательно)
plt.rcParams['font.sans-serif'] = ['SimHei'] # Используется для корректного отображения китайских подписей
plt.rcParams['axes.unicode_minus'] = False # Используется для правильного отображения отрицательных знаков
# Загрузить набор данных Iris
iris = datasets.load_iris()
X = iris.data # Данные признаков, форма (150, 4)
y = iris.target # Целевые метки (виды), форма (150,)
target_names = iris.target_names # Названия видов: ['setosa', 'versicolor', 'virginica']
print(f"Форма набора данных: {X.shape}")
print(f"Имена признаков: {iris.feature_names}")
print(f"Целевые классы: {target_names}")
Вывод:
数据集形状: (150, 4) 特征名称: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] 目标类别: ['setosa' 'versicolor' 'virginica']
Стандартизация данных
Перед применением PCA стандартизация данных — этоважнейшийшаг.
Поскольку PCA очень чувствителен к масштабу признаков. Если один признак имеет числовой диапазон (например, длина лепестка, измеренная в сантиметрах, значения от 1 до 10) намного больший, чем другой признак (например, ширина чашелистика, измеренная в миллиметрах, значения от 0.1 до 1), то признак с большим диапазоном будет доминировать в направлении главных компонент, что обычно не то, что нам нужно.
Пример
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
print("После стандартизации первые 5 образцов:")
print(X_scaled[:5])
Применение PCA для снижения размерности
Мы используемscikit-learnизPCAкласс PCA, который может легко выполнить все математические вычисления.
Пример
pca = PCA(n_components=2)
# Обучаем модель PCA на стандартизированных данных и преобразуем данные
X_pca = pca.fit_transform(X_scaled)
print(f"Форма данных после снижения размерности: {X_pca.shape}")
print(f"Координаты первых 5 образцов на PC1 и PC2:\n{X_pca[:5]}")
# Проверяем долю объяснённой дисперсии каждой главной компоненты
print(f"Доля объяснённой дисперсии главных компонент: {pca.explained_variance_ratio_}")
print(f"Суммарная объяснённая доля дисперсии первых двух главных компонент: {sum(pca.explained_variance_ratio_):.4f}")
Пояснение к коду:
n_components=2: Указывает, что мы хотим уменьшить данные до 2 измерений.
fit_transform(X_scaled): Этот метод выполняет сразу две вещи:
fit: На основе входных данных,X_scaledвычислить параметры, необходимые для PCA (например, направления главных компонент).transform: Использовать вычисленные параметры, чтобыX_scaledпреобразовать данные в новое двумерное пространство.
explained_variance_ratio_: Это очень важный атрибут. Он сообщает намдолю дисперсии исходных данных, объясняемую каждой главной компонентой.Например, если вывод равен[0.73, 0.23], это означает, что PC1 сохраняет 73% информации в исходных данных, PC2 сохраняет 23%, а вместе они сохраняют 96% информации. Это помогает нам оценить потерю информации после снижения размерности.
Результаты визуализации
Теперь у нас есть двумерные данныеX_pca, и мы можем легко визуализировать их с помощью диаграммы рассеяния.
Пример
plt.figure(figsize=(8, 6))
# Установите разные цвета и маркеры для каждого вида
colors = ['navy', 'turquoise', 'darkorange']
lw = 2 # Ширина линии
# Пройдите в цикле по трём видам и постройте график для каждого
for color, i, target_name in zip(colors, [0, 1, 2], target_names):
plt.scatter(X_pca[y == i, 0], # Выберите координаты PC1 образцов, принадлежащих виду i
X_pca[y == i, 1], # Выберите координаты PC2 образцов, принадлежащих виду i
color=color, alpha=0.8, lw=lw,
label=target_name)
# Добавьте заголовок диаграммы и подписи осей
plt.title('2D-визуализация PCA набора данных Iris')
plt.xlabel(f'Первая главная компонента (PC1) - доля объяснённой дисперсии: {pca.explained_variance_ratio_)
plt.ylabel(f'Вторая главная компонента (PC2) - доля объяснённой дисперсии: {pca.explained_variance_ratio_)
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.grid(True, linestyle='--', alpha=0.6)
# Отобразить график
plt.tight_layout()
plt.show()
Интерпретация результатов визуализации:После запуска приведённого выше кода вы получите двумерную диаграмму рассеяния.
- Ось X (PC1): Представляет направление максимальной дисперсии среди исходных 4 признаков и является наиболее важным измерением для различения данных. Как видно из рисунка, она хорошо отделяет видSetosaот двух других видов.
- Ось Y (PC2): Представляет направление, ортогональное PC1, со второй по величине дисперсией, и даёт дополнительную различающую информацию. Это помогает дополнительно различитьVersicolorиVirginica (ирис виргинский), хотя они частично перекрываются.
- Вывод: С помощью PCA мы успешно спроецировали 4-мерные данные на 2D-плоскость и чётко увидели кластеризацию трёх видов. Setosa полностью отделяется, тогда как Versicolor и Virginica частично перекрываются на 2D-проекции, что указывает на то, что использования только первых двух главных компонент (сохраняющих около 95% информации) недостаточно для идеального различения последних двух видов, но основные тенденции их распределения уже очень очевидны.
Дальнейшее исследование и размышления
Как выбрать число главных компонент (значение K)?
В реальных проектах мы можем не знать, до какого числа измерений нужно уменьшить размерность. Распространённый метод — построитьScree Plot, который показывает долю объяснённой дисперсии каждой главной компоненты.
Пример
pca_full = PCA()
pca_full.fit(X_scaled)
# Построим график каменистой осыпи
plt.figure(figsize=(8, 5))
plt.plot(range(1, len(pca_full.explained_variance_ratio_) + 1),
pca_full.explained_variance_ratio_, 'o-', linewidth=2)
plt.title('График каменистой осыпи доли объяснённой дисперсии PCA')
plt.xlabel('Индекс главной компоненты')
plt.ylabel('Доля объяснённой дисперсии')
plt.grid(True, linestyle='--', alpha=0.6)
plt.xticks(range(1, len(pca_full.explained_variance_ratio_) + 1))
plt.tight_layout()
plt.show()
# Построим график накопленной доли объяснённой дисперсии
plt.figure(figsize=(8, 5))
plt.plot(range(1, len(pca_full.explained_variance_ratio_) + 1),
np.cumsum(pca_full.explained_variance_ratio_), 's-', linewidth=2, color='red')
plt.title('Накопленная доля объяснённой дисперсии PCA')
plt.xlabel('Число главных компонент')
plt.ylabel('Накопленная доля объяснённой дисперсии')
plt.axhline(y=0.95, color='gray', linestyle='--', label='порог 95%') # Обычный порог
plt.legend()
plt.grid(True, linestyle='--', alpha=0.6)
plt.xticks(range(1, len(pca_full.explained_variance_ratio_) + 1))
plt.tight_layout()
plt.show()
Как выбрать значение K?
- Посмотрите на точку локтя: На графике каменистой осыпи найдите точку, где снижение доли объяснённой дисперсии внезапно замедляется (то есть локоть). Главные компоненты после неё вносят меньший вклад.
- Задайте порог: На графике накопленной дисперсии выберите наименьшее значение K, при котором накопленная объяснённая доля достигает удовлетворительного порога (например, 95% или 99%). Из графика накопленной дисперсии для данных iris первые две главные компоненты уже объясняют более 95% дисперсии, поэтому K=2 — хороший выбор.
Понимание смысла главных компонент
Мы также можем посмотреть нанагрузкиглавных компонент, то есть веса вклада каждого исходного признака в главные компоненты, что помогает интерпретировать фактический смысл главных компонент.
Пример
pca_components = pca.components_ # Форма: (2, 4)
# Используйте DataFrame для более наглядного отображения
df_components = pd.DataFrame(pca_components,
columns=iris.feature_names,
index=['PC1', 'PC2'])
print("Матрица нагрузок главных компонент (собственные векторы):")
print(df_components)
# Можно визуализировать с помощью тепловой карты
import seaborn as sns
plt.figure(figsize=(8, 4))
sns.heatmap(df_components, annot=True, cmap='RdBu_r', center=0)
plt.title('Тепловая карта нагрузок главных компонент')
plt.tight_layout()
plt.show()
Интерпретация матрицы нагрузок:
- ДляPC1, если длина и ширина лепестка имеют относительно большиеправильныевеса, тогда как ширина чашелистика имеет относительно большиеотрицательныевеса, тогда PC1 может в основном представлять комплексную особенность контраста между размером лепестка и шириной чашелистика.
- ДляPC2, картина весов отличается, и она может представлять другую комбинацию признаков. Анализируя эти веса, мы можем придать абстрактным главным компонентам некоторый практический биологический или бизнес-смысл.
Итоги и практические упражнения
Краткое изложение ключевых моментов
- Что такое PCA: метод линейного снижения размерности без учителя, который заново выражает данные, находя ортогональные направления (главные компоненты) с максимальной дисперсией данных.
- Основные шаги: стандартизация -> вычисление ковариационной матрицы -> вычисление собственных значений и собственных векторов -> выбор главных компонент -> проецирование данных.
- Важные понятия:
- Главные компоненты: новые, некоррелированные оси признаков.
- Доля объяснённой дисперсии: метрика, которая измеряет важность каждой главной компоненты.
- Нагрузки: мост, соединяющий исходные признаки и главные компоненты, используемый для объяснения смысла главных компонент.
- Основные применения: визуализация данных, удаление шума и избыточности, а также использование в качестве этапа предварительной обработки для других моделей (таких как классификация, регрессия) для ускорения обучения.
Практическое занятие
Чтобы закрепить свои знания, попробуйте выполнить следующие упражнения:
Упражнение 1: Изучите различные наборы данныхПопробуйтеscikit-learnв других наборах данных (таких какdigitsнабор данных рукописных цифр илиwineнабор данных wine) для выполнения визуализации PCA. Посмотрите, сохраняют ли изображения после уменьшения размерности различие между разными категориями.
Пример
from sklearn.datasets import load_wine
wine = load_wine()
# ... Повторите процесс PCA
Упражнение 2: 3D-визуализацияСократите данные iris до 3 измерений и используйтеmpl_toolkits.mplot3dбиблиотеку, чтобы нарисовать 3D-диаграмму рассеяния. Посмотрите, уменьшается ли перекрытие между Versicolor и Virginica после добавления одного измерения.
Пример
pca3 = PCA(n_components=3)
X_pca3 = pca3.fit_transform(X_scaled)
# ... Создать 3D-фигуру для построения графика