PCA как предварительная обработка: ускорение и снижение шума в конвейерах
Вы встроите PCA в sklearn Pipeline перед классификатором и сравните время обучения и точность на тесте с уменьшением размерности и без него.
«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 — локальная установка не требуется.
Все уроки этого курса
- PCA: дисперсия, собственные векторы и главные компоненты
- Проецирование данных и восстановление по компонентам
- t-SNE: сохранение соседства при визуализации
- PCA как предварительная обработка: ускорение и снижение шума в конвейерах