В высокоразмерных данных, одной из ключевых проблем является «проклятие размерности». Большое количество признаков в данных может привести к ухудшению производительности алгоритмов машинного обучения, замедлению вычислений и сложностям в визуализации результатов. В таких сценариях снижение размерности становится критически важным шагом. Оно позволяет уменьшить количество признаков, сохраняя при этом важные характеристики данных.

В этой статье мы рассмотрим методы снижения размерности данных, такие как: «Преобразование главных компонент» (PCA) и "t-SNE" (t-distributed Stochastic Neighbor Embedding). Оба метода обладают своими уникальными характеристиками и предназначены для разных типов данных и задач.

Преобразование главных компонент (PCA)

Преобразование главных компонент (Principal Component Analysis, PCA) – это мощный метод анализа данных, который позволяет находить основные направления изменчивости в многомерных данных и снижать их размерность без существенной потери информации. В основе метода лежит идея нахождения ортогональных направлений (главных компонент), вдоль которых данные имеют наибольшую дисперсию.

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

Расчет ковариационной матрицы и собственных значений

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

import numpy as np

# Генерируем случайные данные (матрица X)
np.random.seed(0)
X = np.random.rand(100, 3)

# Вычисляем среднее значение для центрирования данных
mean = np.mean(X, axis=0)

# Вычисляем ковариационную матрицу
cov_matrix = np.cov(X.T)

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

# Вычисляем собственные значения и собственные векторы
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)

Вычисление главных компонент и их вклад в объяснение дисперсии

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

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

# Вычисляем главные компоненты (проекции данных на новое пространство)
principal_components = np.dot(X - mean, sorted_eigenvectors)

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

# Вычисляем объясненную дисперсию для каждой компоненты
explained_variance = sorted_eigenvalues / np.sum(sorted_eigenvalues)

# Процент объясненной дисперсии для первых n компонент
explained_variance_ratio = np.cumsum(explained_variance)

Кроме базовой реализации, существует множество вариаций PCA, таких как Incremental PCA, Kernel PCA и другие. Они могут быть полезными в различных сценариях и задачах. Важно понимать, что PCA является методом линейного снижения размерности, и он может недостаточно хорошо справляться с данными, содержащими сложные нелинейные зависимости.

Применение PCA для снижения размерности данных

1. Выбор числа главных компонент

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

Один из способов выбора оптимального числа компонент – это использование "доли объясненной дисперсии". Доля объясненной дисперсии показывает, какую часть общей дисперсии данных объясняют первые n главных компонент. Часто устанавливают порог, например, 95% или 99%, и выбирают такое количество компонент, которые в сумме объясняют не менее этой доли.

# Процент объясненной дисперсии для каждой компоненты
explained_variance_ratio = np.cumsum(explained_variance)

# Находим количество компонент, объясняющих не менее 95% дисперсии
num_components = np.argmax(explained_variance_ratio >= 0.95) + 1

2. Проекция данных на новое пространство

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

# Проекция данных на новое пространство
reduced_data = np.dot(X - mean, sorted_eigenvectors[:, :num_components])

Преимущества метода PCA

1. Сохранение информации и сжатие данных

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

2. Линейная природа метода

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

3. Чувствительность к выбросам

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

t-SNE (t-distributed Stochastic Neighbor Embedding)

t-SNE (t-distributed Stochastic Neighbor Embedding) – это метод снижения размерности и визуализации данных, который позволяет сохранить локальные структуры данных и обнаруживать нелинейные зависимости. Основная идея заключается в том, чтобы преобразовать исходные данные таким образом, чтобы схожие объекты в исходном пространстве сохраняли свою схожесть и в новом, сниженном пространстве.

Одной из ключевых особенностей t-SNE является то, что он нацелен на сохранение локальных структур данных, что делает его особенно полезным для визуализации скрытых паттернов в данных.

Расчет условных вероятностей сходства объектов

Процесс работы t-SNE начинается с расчета условных вероятностей сходства объектов в исходном пространстве. Эти вероятности показывают, насколько вероятно, что объект i выберет объект j в качестве своего соседа, если выбирать соседей пропорционально их вероятности быть соседом для i.

from sklearn.metrics import pairwise_distances
from scipy import exp

# Вычисляем матрицу попарных расстояний между объектами
distance_matrix = pairwise_distances(X, metric='euclidean')

# Вычисляем условные вероятности сходства
P = np.exp(-distance_matrix ** 2 / (2 * (sigma ** 2)))
P /= np.sum(P, axis=1, keepdims=True)  # Нормализуем вероятности

Создание распределения вероятностей для целевого пространства

Затем, t-SNE строит распределение вероятностей для целевого пространства, таким образом, чтобы объекты, которые близки в исходном пространстве, имели высокие вероятности быть близкими и в сниженном пространстве. Это достигается путем оптимизации функции Кульбака-Лейблера между распределениями вероятностей P и Q.

# Инициализируем распределение вероятностей Q для целевого пространства
Q = np.ones((n_samples, n_samples)) / n_samples

# Оптимизируем функцию Кульбака-Лейблера KL(P||Q)
for iteration in range(n_iter):
    # Вычисляем распределение вероятностей Q для целевого пространства
    Q = 1 / (1 + distance_matrix ** 2) / np.sum(1 / (1 + distance_matrix ** 2), axis=1, keepdims=True)
    
    # Обновляем координаты точек в целевом пространстве
    y = y + learning_rate * np.sum((P - Q)[:, :, np.newaxis] * (y[:, np.newaxis, :] - y), axis=0)

Минимизация расхождения Кульбака-Лейблера для получения проекции

Процесс t-SNE заключается в минимизации расхождения Кульбака-Лейблера между двумя распределениями вероятностей: распределением вероятностей P, которое вычисляется для исходных данных, и распределением вероятностей Q, которое строится для целевого (сниженного) пространства. Минимизация расхождения позволяет нам получить проекцию данных в сниженное пространство таким образом, чтобы схожие объекты оставались близкими, а различные объекты – располагались на некотором расстоянии друг от друга.

Применение t-SNE для снижения размерности данных

1. Важность настройки гиперпараметров

Одной из особенностей t-SNE является наличие нескольких гиперпараметров, настройка которых может существенно влиять на результаты. Один из ключевых параметров – это перплексия (perplexity). Она определяет, сколько соседей учитываются в расчете условных вероятностей сходства. Большая перплексия приводит к усреднению вероятностей и созданию более глобальной структуры, в то время как маленькая перплексия подчеркивает локальную структуру.

# Применение t-SNE с разной перплексией
tsne_low_perplexity = TSNE(n_components=2, perplexity=5)
reduced_data_low_perplexity = tsne_low_perplexity.fit_transform(X)

tsne_high_perplexity = TSNE(n_components=2, perplexity=50)
reduced_data_high_perplexity = tsne_high_perplexity.fit_transform(X)

2. Визуализация структуры данных в новом пространстве

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

import matplotlib.pyplot as plt

# Визуализация сниженных размерностей с разной перплексией
plt.figure(figsize=(12, 6))

plt.subplot(1, 2, 1)
plt.scatter(reduced_data_low_perplexity[:, 0], reduced_data_low_perplexity[:, 1], c=labels)
plt.title('t-SNE with Low Perplexity')
plt.colorbar()

plt.subplot(1, 2, 2)
plt.scatter(reduced_data_high_perplexity[:, 0], reduced_data_high_perplexity[:, 1], c=labels)
plt.title('t-SNE with High Perplexity')
plt.colorbar()

plt.tight_layout()
plt.show()

Преимущества метода t-SNE

1. Способность к обнаружению нелинейных зависимостей

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

2. Сохранение локальной структуры

t-SNE сохраняет локальные структуры данных, что делает его полезным для анализа кластеров и визуализации подобных объектов, находящихся близко друг к другу в исходном пространстве.

3. Вычислительная сложность и потребление ресурсов

Тем не менее, следует отметить, что t-SNE является вычислительно сложным методом. Особенно при больших объемах данных, расчет вероятностей и оптимизация распределения Q может потребовать значительное время и вычислительные ресурсы.

При использовании t-SNE важно тщательно подходить к настройке гиперпараметров и интерпретации результатов. Также стоит учитывать, что t-SNE является эвристическим алгоритмом, и его результаты могут варьироваться при каждом запуске.

Примеры применения

A. Загрузка и предобработка текстовых данных

В реальных сценариях анализа данных часто приходится иметь дело с большими объемами текстовых данных, например, обзорами товаров, комментариями пользователей или новостными статьями. Давайте рассмотрим пример анализа текстовых данных с использованием PCA и t-SNE.

Для начала давайте загрузим и предобработаем текстовые данные:

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import TruncatedSVD
Загрузка текстовых данных
data = pd.read_csv('reviews.csv')
Преобразование текстов в TF-IDF векторы
tfidf_vectorizer = TfidfVectorizer(max_features=1000)
tfidf_matrix = tfidf_vectorizer.fit_transform(data['review_text'])
Применение TruncatedSVD (PCA для разреженных матриц)
svd = TruncatedSVD(n_components=100)
reduced_tfidf = svd.fit_transform(tfidf_matrix)

B. Применение PCA для анализа текстовых данных

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

# Применение PCA для снижения размерности
pca_text = PCA(n_components=2)
reduced_pca_text = pca_text.fit_transform(reduced_tfidf)
Визуализация результата PCA для текстовых данных
plt.figure(figsize=(10, 6))
plt.scatter(reduced_pca_text[:, 0], reduced_pca_text[:, 1], alpha=0.5)
plt.title('PCA Visualization of Text Data')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()

Применение t-SNE для анализа текстовых данных

Далее, применим t-SNE для анализа текстовых данных. Этот шаг позволит нам увидеть, какие группы текстов могут образоваться в сниженном пространстве.

from sklearn.manifold import TSNE
Применение t-SNE для снижения размерности
tsne_text = TSNE(n_components=2, perplexity=30)
reduced_tsne_text = tsne_text.fit_transform(reduced_tfidf)
Визуализация результата t-SNE для текстовых данных
plt.figure(figsize=(10, 6))
plt.scatter(reduced_tsne_text[:, 0], reduced_tsne_text[:, 1], alpha=0.5)
plt.title('t-SNE Visualization of Text Data')
plt.xlabel('t-SNE Component 1')
plt.ylabel('t-SNE Component 2')
plt.show()

Визуализация многомерных данных перед анализом

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

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

from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# Генерируем случайные цветные изображения (матрица X)
np.random.seed(0)
X = np.random.randint(0, 256, (100, 64, 64, 3))

# Преобразуем изображения в векторы пикселей
X_flatten = X.reshape(100, -1)

# Применяем PCA для снижения размерности до 2 компонент
pca = PCA(n_components=2)
reduced_data = pca.fit_transform(X_flatten)

# Визуализация сниженных размерностей
plt.figure(figsize=(10, 6))
sns.scatterplot(x=reduced_data[:, 0], y=reduced_data[:, 1])
plt.title('PCA for Image Visualization')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.show()
Результат
Результат

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

Второй важной областью применения методов снижения размерности является подготовка данных перед применением алгоритмов машинного обучения. Многие алгоритмы могут столкнуться с проблемой избыточности данных или мультиколлинеарности при большом числе признаков, что может привести к ухудшению производительности. Применение PCA или t-SNE позволяет снизить размерность данных, удалив избыточные и коррелированные признаки, что может повысить производительность алгоритмов.

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

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

# Загружаем набор данных Iris
data = load_iris()
X = data.data
y = data.target

# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

# Применяем t-SNE для снижения размерности до 2 компонент
tsne = TSNE(n_components=2)
reduced_train = tsne.fit_transform(X_train)

# Обучаем классификатор ближайших соседей на сниженных данных
knn_classifier = KNeighborsClassifier(n_neighbors=3)
knn_classifier.fit(reduced_train, y_train)

# Применяем обученный классификатор к тестовым данным
reduced_test = tsne.transform(X_test)
y_pred = knn_classifier.predict(reduced_test)

# Оценка точности классификации
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

Заключение

В зависимости от характера данных, целей анализа и типа вопросов, на которые мы ищем ответы, мы можем выбирать между PCA и t-SNE или даже комбинировать их для более полного понимания данных. Важно помнить, что каждый метод имеет свои сильные стороны и ограничения, и правильный выбор зависит от контекста задачи.


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

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

Комментарии (1)


  1. nikolz
    28.08.2023 15:16

    Вообще-то метод главных компонент называют преобразованием Карунена — Лоэва (ПКЛ). Это вообще-то основы матричной алгебры.

    Но прикольно то, что для стационарных случайных процессов ПКЛ сводится к ДПФ.

    Наличие БПФ привело к тому, что вместо ПКЛ в цифровой обработке данных успешно применяется ДПФ(БПФ). Рекомендую БПФ.