В статье объясняются концепции и использование анализа основных компонентов (PCA), а также реализация кода.
Анализ основных компонентов (АГК) – это статистическая процедура, в которой используется метод преобразования набора коррелирующих переменных в набор некоррелированных переменных. В наборе данных морское ушко есть такие характеристики, как Высота и Диаметр. Морское ушко — это существо, похожее на устрицу. Идея заключается в том, чтобы преобразовать приведенные выше переменные в набор других переменных, известных как оси вариации.
Большую ось можно назвать компонентом Размер: малая высота и малый диаметр (внизу слева) в отличие от большой высоты и большого диаметра (вверху справа) . Короткую ось можно назвать компонентом Форма: малая высота и большой диаметр (плоская форма) контрастируют с большой высотой и малым диаметром (круглая форма).

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

PCA также показывает количество вариаций в каждом компоненте. Он показывает, насколько функция Размер влияет на изменение по сравнению с компонентом Форма. PCA уточняет это с помощью процента объясненной дисперсии каждого компонента.
PCA для разработки функций
Существует два способа использования PCA для разработки функций.
Первый способ — использовать его в качестве описательного метода. Поскольку компоненты определяют вариацию, вы можете вычислить баллы Взаимной информации для компонентов и посмотреть, какая вариация наиболее предсказуема для целевой переменной. Это может дать идеи для создания элементов — произведение высоты и диаметра, если, скажем, размер важен, или а соотношение высоты и диаметра, если важен размер. Можно даже попробовать кластеризацию для одного или нескольких компонентов с высокой оценкой.
Второй способ заключается в использовании самих компонентов в качестве функций. Поскольку компоненты напрямую раскрывают вариационную структуру данных, они часто могут быть более информативными, чем исходные признаки. Вот несколько вариантов использования:
- Уменьшение размерности: когда функции сильно повторяются (в частности, мультиколлинеарны), PCA разделяет избыточность на один или несколько компонентов с почти нулевой дисперсией, которые затем можно удалить, так как они будут содержать мало информации или вообще не содержать ее.
- Обнаружение аномалий. В компонентах с низкой дисперсией часто появляются необычные вариации, несовместимые с исходными функциями. Эти компоненты могут быть высокоинформативными в задаче обнаружения аномалий или выбросов.
- Шумоподавление: набор показаний датчиков всегда будет иметь общий фоновый шум. PCA может иногда собирать (информативный) сигнал в меньшее количество признаков, оставляя шум в покое, тем самым повышая отношение сигнал-шум. соотношение.
- Декорреляция. Некоторые алгоритмы машинного обучения борются с высококоррелированными функциями. PCA преобразует коррелированные признаки в некоррелированные компоненты, что облегчает работу алгоритма.
PCA в основном дает прямой доступ к корреляционной структуре данных.
PCA Рекомендации:
При работе с PCA необходимо помнить о некоторых вещах.
- PCA работает только с числовыми функциями,
- PCA чувствителен к масштабу. Перед применением PCA рекомендуется стандартизировать данные.
- Лучше удалить или ограничить выбросы, так как они могут привести к искажению результатов.
Реализация кода PCA
Давайте теперь посмотрим на кодовую реализацию PCA и на то, как она может решить некоторые реальные проблемы. Набор данных amesцены на жилье используется в качестве варианта использования, и мы также можем использовать код для других формулировок проблемы.
#List of installed libraries
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.decomposition import PCA
from sklearn.feature_selection import mutual_info_regression
from sklearn.model_selection import cross_val_score
from xgboost import XGBRegressor
# Set Matplotlib defaults
plt.style.use("seaborn-whitegrid")
plt.rc("figure", autolayout=True)
plt.rc(
"axes",
labelweight="bold",
labelsize="large",
titleweight="bold",
titlesize=14,
titlepad=10,
)
#Standardization and applying PCA to create principal components
def apply_pca(X, standardize=True):
# Standardize
if standardize:
X = (X - X.mean(axis=0)) / X.std(axis=0)
# Create principal components
pca = PCA()
X_pca = pca.fit_transform(X)
# Convert to dataframe
component_names = [f"PC{i+1}" for i in range(X_pca.shape[1])]
X_pca = pd.DataFrame(X_pca, columns=component_names)
# Create loadings
loadings = pd.DataFrame(
pca.components_.T, # transpose the matrix of loadings
columns=component_names, # so the columns are the principal components
index=X.columns, # and the rows are the original features
)
return pca, X_pca, loadings
def plot_variance(pca, width=8, dpi=100):
# Create figure
fig, axs = plt.subplots(1, 2)
n = pca.n_components_
grid = np.arange(1, n + 1)
# Explained variance
evr = pca.explained_variance_ratio_
axs[0].bar(grid, evr)
axs[0].set(
xlabel="Component", title="% Explained Variance", ylim=(0.0, 1.0)
)
# Cumulative Variance
cv = np.cumsum(evr)
axs[1].plot(np.r_[0, grid], np.r_[0, cv], "o-")
axs[1].set(
xlabel="Component", title="% Cumulative Variance", ylim=(0.0, 1.0)
)
# Set up figure
fig.set(figwidth=8, dpi=100)
return axs
#Calculate Mutual Information scores
def make_mi_scores(X, y):
X = X.copy()
for colname in X.select_dtypes(["object", "category"]):
X[colname], _ = X[colname].factorize()
# All discrete features should now have integer dtypes
discrete_features = [pd.api.types.is_integer_dtype(t) for t in X.dtypes]
mi_scores = mutual_info_regression(X, y, discrete_features=discrete_features, random_state=0)
mi_scores = pd.Series(mi_scores, name="MI Scores", index=X.columns)
mi_scores = mi_scores.sort_values(ascending=False)
return mi_scores
# Create model scores
def score_dataset(X, y, model=XGBRegressor()):
# Label encoding for categoricals
for colname in X.select_dtypes(["category", "object"]):
X[colname], _ = X[colname].factorize()
# Metric for Housing competition is RMSLE (Root Mean Squared Log Error)
score = cross_val_score(
model, X, y, cv=5, scoring="neg_mean_squared_log_error",
)
score = -1 * score.mean()
score = np.sqrt(score)
return score
df = pd.read_csv("ames.csv")
В приведенном выше коде мы вычисляем компоненты PCA, оценки взаимной информации и оценку модели для набора данных. В следующем коде мы берем 4 функции из набора данных и находим корреляцию с целевой (Цена продажи) в данном случае.
features = [
"GarageArea",
"YearRemodAdd",
"TotalBsmtSF",
"GrLivArea",
]
print("Correlation with SalePrice:\n")
print(df[features].corrwith(df.SalePrice))
Correlation with SalePrice:
GarageArea 0.640138
YearRemodAdd 0.532974
TotalBsmtSF 0.632529
GrLivArea 0.706780
dtype: float64
Мы будем использовать PCA, чтобы наблюдать корреляцию между функциями и предлагать связи, которые можно с пользой смоделировать с помощью новых функций.
X = df.copy()
y = X.pop("SalePrice")
X = X.loc[:, features]
# `apply_pca`, defined above, reproduces the code from the tutorial
pca, X_pca, loadings = apply_pca(X)
print(loadings)
PC1 PC2 PC3 PC4
GarageArea 0.541229 0.102375 -0.038470 0.833733
YearRemodAdd 0.427077 -0.886612 -0.049062 -0.170639
TotalBsmtSF 0.510076 0.360778 -0.666836 -0.406192
GrLivArea 0.514294 0.270700 0.742592 -0.332837
Интерпретация загрузки компонентов
Первый компонент PC1 похож на компонент "размер" из предыдущей части этой статьи: все функции имеют одинаковый знак (положительный), что указывает на то, что этот компонент описывает контраст между домами с большими значениями и домами с низкими значениями этих характеристик.
Интерпретация третьего компонента PC3 немного сложнее. Функции GarageArea и YearRemodAdd имеют почти нулевую загрузку, поэтому давайте их проигнорируем. Этот компонент в основном касается TotalBsmtSF и GrLivArea. Он описывает контраст между домами с большой жилой площадью, но небольшими (или отсутствующими) подвалами и наоборот: маленькими домами с большими подвалами.
Создавайте новые функции
В этой части мы попробуем создать новые функции, чтобы сравнить их с уже существующими функциями и выяснить, можно ли найти лучшую RMSLE (среднеквадратичную логарифмическую ошибку). Он был рассчитан с использованием функции score_dataset(). Код приведен ниже.
# Solution 1: Inspired by loadings
X = df.copy()
y = X.pop("SalePrice")
X["Feature1"] = X.GrLivArea + X.TotalBsmtSF
X["Feature2"] = X.YearRemodAdd - X.TotalBsmtSF
score = score_dataset(X, y)
print(f"Your score: {score:.5f} RMSLE")
# Solution 2: Uses components
X = df.copy()
y = X.pop("SalePrice")
X = X.join(X_pca)
score = score_dataset(X, y)
print(f"Your score: {score:.5f} RMSLE")
Your score: 0.13478 RMSLE
Your score: 0.13707 RMSLE
Первая часть кода содержит созданные функции (Feature1 и Feature2), и вычисляется оценка. В следующей части компоненты PCA используются для расчета оценки. Значения RMSLE в двух приведенных выше случаях составляют 0,134 и 0,137. Конечно, можно попробовать различные комбинации уже существующих функций и проверить, можно ли уменьшить значение RMSLE ниже 0,140, поскольку это оценка набора данных без PCA или вновь созданных функций.
На этом статья о PCA заканчивается, и я надеюсь, что написал ее понятно, как здесь. Потребуется много практики, чтобы создать хорошую модель, которая будет запущена в производство, и все эти этапы разработки признаков необходимы для достижения цели.
А до тех пор, пожалуйста, ознакомьтесь с моими другими статьями и скажите привет. Также загляните на мой GitHub. Вы можете пожертвовать мне несколько чашек кофе, если вам нравится моя работа, и я могу ежедневно улучшать качество контента, продвигаясь вперед в этом писательском путешествии.