В статье объясняются концепции и использование анализа основных компонентов (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. Вы можете пожертвовать мне несколько чашек кофе, если вам нравится моя работа, и я могу ежедневно улучшать качество контента, продвигаясь вперед в этом писательском путешествии.