Machine Learning Academy · Урок

PCA как предварительная обработка: ускорение и снижение шума в конвейерах

Вы встроите PCA в sklearn Pipeline перед классификатором и сравните время обучения и точность на тесте с уменьшением размерности и без него.

Урок 4 из 413 шагов

«PCA как предварительная обработка: ускорение и снижение шума в конвейерах» — бесплатный урок Machine Learning Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Machine Learning Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Machine Learning Academy содержит 4 уроков всего.

PCA на этапе предварительной обработки

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

Почему PCA может уменьшать шум

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

Встраивание PCA в конвейер sklearn

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

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split

X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('pca', PCA(n_components=0.95)),
    ('clf', LogisticRegression(max_iter=500))
])

pipe.fit(X_train, y_train)
print('Test accuracy:', pipe.score(X_test, y_test).round(4))

Сравнение времени обучения с PCA и без него

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

import time
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split

X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

# Without PCA
t0 = time.time()
pipe_full = Pipeline([('sc', StandardScaler()), ('clf', LogisticRegression(max_iter=1000))])
pipe_full.fit(X_train, y_train)
t_full = time.time() - t0

# With PCA
t0 = time.time()
pipe_pca = Pipeline([('sc', StandardScaler()), ('pca', PCA(n_components=0.95)),
                     ('clf', LogisticRegression(max_iter=500))])
pipe_pca.fit(X_train, y_train)
t_pca = time.time() - t0

print(f'Without PCA: {t_full:.3f}s  acc={pipe_full.score(X_test, y_test):.4f}')
print(f'With PCA:    {t_pca:.3f}s  acc={pipe_pca.score(X_test, y_test):.4f}')

Когда PCA помогает, а когда — нет

Предварительная обработка с помощью PCA особенно полезна, когда: число признаков велико по сравнению с числом объектов (много признаков и мало объектов), признаки коррелируют (содержат избыточную информацию) или алгоритм работает медленно с большим числом признаков (например, SVM с ядром RBF). PCA, как правило, НЕ помогает, когда набор данных уже содержит мало информативных признаков или Вы используете модели на основе деревьев (случайный лес, XGBoost), которые сами обрабатывают избыточные признаки и не получают преимуществ от линейного сжатия PCA.

Настройка n_components при поиске по сетке

Поскольку PCA является этапом внутри конвейера, Вы можете настраивать n_components одновременно с гиперпараметрами классификатора с помощью GridSearchCV. Используйте обозначение с двойным подчёркиванием pca__n_components, чтобы обратиться к параметру этапа PCA. Благодаря этому цикл перекрёстной проверки сможет одновременно найти оптимальный уровень сжатия и силу регуляризации модели.

from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_digits

X, y = load_digits(return_X_y=True)

pipe = Pipeline([
    ('sc', StandardScaler()),
    ('pca', PCA()),
    ('clf', LogisticRegression(max_iter=500))
])

param_grid = {
    'pca__n_components': [10, 20, 30, 40],
    'clf__C': [0.1, 1.0, 10.0]
}

grid = GridSearchCV(pipe, param_grid, cv=5, n_jobs=-1)
grid.fit(X, y)
print('Best params:', grid.best_params_)
print('Best CV score:', grid.best_score_.round(4))

PCA перед SVM: классическое сочетание

SVM с ядрами RBF вычисляет попарные расстояния в исходном пространстве признаков, что дорого для данных с большой размерностью. Сначала применяя PCA, Вы уменьшаете размерность, сохраняя значимый сигнал, и сокращаете объём вычислений расстояний. До широкого распространения глубокого обучения это было стандартным подходом в задачах классификации изображений: уменьшить число пикселей изображения с помощью PCA, а затем классифицировать его с помощью SVM.

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.datasets import load_digits
from sklearn.model_selection import cross_val_score
import numpy as np

X, y = load_digits(return_X_y=True)

pipe = Pipeline([
    ('sc', StandardScaler()),
    ('pca', PCA(n_components=30)),
    ('svm', SVC(kernel='rbf', C=10, gamma='scale'))
])

scores = cross_val_score(pipe, X, y, cv=5)
print(f'Accuracy: {np.mean(scores):.4f} +/- {np.std(scores):.4f}')

PCA для уменьшения шума: конкретный пример

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

import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_digits
from sklearn.model_selection import cross_val_score

X, y = load_digits(return_X_y=True)
X_noisy = X + np.random.randn(*X.shape) * 5.0  # heavy noise

for nc in [None, 10, 20, 30, 40]:
    steps = [('sc', StandardScaler())]
    if nc:
        steps.append(('pca', PCA(n_components=nc)))
    steps.append(('clf', LogisticRegression(max_iter=500)))
    pipe = Pipeline(steps)
    acc = cross_val_score(pipe, X_noisy, y, cv=5).mean()
    label = f'PCA({nc})' if nc else 'No PCA'
    print(f'{label:10s}  acc={acc:.4f}')

Всегда обучайте PCA только на обучающих данных

Критически важное правило: никогда не обучайте преобразование PCA на тестовой выборке. Обучение на тестовых данных приводит к утечке статистик тестовой выборки в предварительную обработку и даёт чрезмерно оптимистичные оценки качества. Использование конвейера автоматически обеспечивает соблюдение этого правила: когда Вы вызываете pipeline.fit(X_train, y_train), каждый этап, включая PCA, обучается только на обучающей части.

Экономия памяти благодаря PCA

В наборах данных с миллионами объектов и тысячами признаков (например, в текстовых матрицах TF-IDF и геномных данных) PCA значительно уменьшает объём занимаемой памяти. Матрица размером 1M×5000 с типом float32 занимает 20 ГБ; после уменьшения до 100 компонент с помощью PCA матрица размером 1M×100 занимает 400 МБ — это сокращение в 50 раз. В таких случаях используйте IncrementalPCA из scikit-learn: он обучает PCA по частям и никогда не загружает всю матрицу в RAM.

from sklearn.decomposition import IncrementalPCA
import numpy as np

# Simulate large dataset as batches
n_samples, n_features = 10000, 500
n_components = 50
batch_size = 500

ipca = IncrementalPCA(n_components=n_components)
for i in range(0, n_samples, batch_size):
    batch = np.random.randn(batch_size, n_features)
    ipca.partial_fit(batch)

print('Explained variance ratio sum:', ipca.explained_variance_ratio_.sum().round(4))

Объединение PCA с ColumnTransformer

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

Быстрая проверка

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

Итоги урока

В этом уроке Вы узнали, что PCA внутри Pipeline предотвращает утечку данных, обучая преобразование только на обучающих данных; PCA может ускорить обучение и уменьшить шум, особенно при большой размерности или коррелированных наборах признаков; а n_components можно настраивать с помощью GridSearchCV одновременно с другими гиперпараметрами модели, используя обозначение с двойным подчёркиванием. Далее мы создадим первый полноценный конвейер scikit-learn, объединяющий масштабировщик и классификатор.

Можно начать бесплатно

Изучай Python с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
30
Уроки
120

Часто задаваемые вопросы

Урок «PCA как предварительная обработка: ускорение и снижение шума в конвейерах» бесплатный?

Да — полный текст урока «PCA как предварительная обработка: ускорение и снижение шума в конвейерах» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Machine Learning Academy, подпишись на CoddyKit PRO. Курс Machine Learning Academy содержит 4 уроков всего.

Чему я научусь в уроке «PCA как предварительная обработка: ускорение и снижение шума в конвейерах»?

Вы встроите PCA в sklearn Pipeline перед классификатором и сравните время обучения и точность на тесте с уменьшением размерности и без него. Ты практикуешь Machine Learning Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Machine Learning Academy?

Предыдущий опыт не требуется. Machine Learning Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «PCA как предварительная обработка: ускорение и снижение шума в конвейерах»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Machine Learning Academy?

Да. Каждый урок Machine Learning Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. PCA: дисперсия, собственные векторы и главные компоненты
  2. Проецирование данных и восстановление по компонентам
  3. t-SNE: сохранение соседства при визуализации
  4. PCA как предварительная обработка: ускорение и снижение шума в конвейерах
← Назад к Machine Learning Academy