Сравните реализацию с PCA Scikit-Learn.

Эта статья является продолжением рассказа Редукция переменных с помощью анализа главных компонент. В предыдущем посте я рассказал об одном из самых известных и широко используемых методов, называемом анализом главных компонентов. Он использует эффективное линейное преобразование, которое уменьшает размерность многомерного набора данных при захвате максимального информационного содержания. Он генерирует основные компоненты, которые представляют собой линейные комбинации исходных функций в наборе данных. Кроме того, я шаг за шагом показал, как реализовать эту технику с помощью Python. Сначала я подумал, что поста достаточно для объяснения PCA, но я почувствовал, что чего-то не хватает. Я реализовал PCA, используя отдельные строки кода, но они неэффективны, когда вы хотите вызывать их каждый раз для решения другой проблемы. Лучшим способом является создание класса, который эффективен, когда вы хотите инкапсулировать структуры данных и процедуры в одном месте. Более того, его действительно легче модифицировать, так как весь код находится в этом уникальном классе.

Оглавление:

  1. Набор данных
  2. Реализация СПС
  3. СПС без стандартизации
  4. АСП со стандартизацией
  5. PCA со Sklearn

1. Набор данных

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

import pandas as pd
import numpy as np
import random
from sklearn.datasets import load_breast_cancer
import plotly.express as px
data = load_breast_cancer(as_frame=True)
X,y,df_bre = data.data,data.target,data.frame
diz_target = {0:'malignant',1:'benign'}
y = np.array([diz_target[y1] for y1 in y])
df_bre['target'] = df_bre['target'].apply(lambda x: diz_target[x])
df_bre.head()

Мы можем заметить, что есть 30 числовых признаков и целевая переменная, которые определяют, является ли опухоль доброкачественной (цель = 1) или злокачественной (цель = 0). Я преобразовываю целевую переменную в строку, так как она не используется PCA и понадобится нам только в визуализациях позже.

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

fig = px.scatter_matrix(df_bre,dimensions=list(df_bre.columns)[:5], color="target")
fig.show()

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

2. Реализация СПС

Шаги для получения основных компонентов (или k-мерных векторов признаков) приведены на иллюстрации выше. Та же логика будет применяться для построения класса.

Мы определяем класс PCA_impl, который имеет три инициализированных в начале атрибута. Наиболее важным атрибутом является количество компонентов, которые мы хотим извлечь. Более того, мы также можем каждый раз воспроизводить одни и те же результаты, установив random_state равным True и стандартизировав набор данных, только если нам это нужно.

Этот класс также включает два метода, fit и fit_transform, аналогично PCA scikit-learn. В то время как первый метод обеспечивает большую часть процедуры для вычисления главных компонентов, метод fit_transform также применяет преобразование к исходной матрице признаков X. В дополнение к этим двум методам я также хотел визуализировать главные компоненты, не указывая каждый раз функции. Плотли Экспресс. Может быть очень полезно ускорить анализ скрытых переменных, генерируемых PCA.

3. PCA без стандартизации

Наконец, класс PCA_impl определен. Нам нужно только вызвать класс и соответствующие методы без каких-либо усилий.

Мы можем получить доступ к атрибутам var_explained и cum_var_explained, которые были рассчитаны с помощью методов fit и fit_transform. Стоит отметить, что мы захватываем 98% всего одним компонентом. Давайте также визуализируем 2D- и 3D-диаграммы рассеяния, используя метод, определенный ранее:

pca1.pca_plot2d()

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

pca1.pca_plot3d()

Теперь мы рассмотрим трехмерную диаграмму рассеяния с первыми тремя компонентами. Это менее ясно, чем предыдущая диаграмма рассеяния, но похожее поведение проявляется даже на этом графике. Безусловно, есть две различные группы, основанные на целевой переменной. Глядя на это трехмерное изображение, открывается новая информация: два пациента со злокачественным раком имеют совершенно разные значения по отношению ко всем другим пациентам. Этот аспект можно слегка заметить, глядя на 2D-график или в матрицу рассеяния, которую мы отображали ранее.

4. PCA со стандартизацией

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

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

pca1.pca_plot2d()

Эти наблюдения подтверждаются, если взглянуть на диаграмму рассеяния с первыми двумя компонентами. Кластеры гораздо более отчетливы и имеют более низкие значения.

pca1.pca_plot3d()

Трехмерное представление легче читать и понимать. В итоге можно сделать вывод, что две группы пациентов имеют разную вариабельность признаков. Более того, есть еще две точки данных, которые лежат отдельно от остальных данных.

5. PCA со Sklearn

На этом этапе мы можем применить PCA, реализованный Sklearn, чтобы сравнить его с моей реализацией. Я должен отметить, что есть некоторые различия, которые следует учитывать в этом сравнении. В то время как моя реализация PCA основана на ковариационной матрице, PCA scikit-learn включает центрирование входных данных и использует разложение по сингулярным значениям для проецирования данных в низкомерное пространство.

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

X_copy = X.copy().astype('float32')
X_copy /= np.std(X_copy, axis=0)

Теперь мы передаем количество компонентов и random_state классу PCA и вызываем метод fit_transform для получения основных компонентов.

Те же результаты реализованного PCA со стандартизацией достигаются с помощью PCA sklearn.

fig = px.scatter(components, x=0, y=1, color=df.label,labels={'0': 'PC 1', '1': 'PC 2'})
fig.show()

fig = px.scatter_3d(components, x=0, y=1,z=2, color=df.label,labels={'0': 'PC 1', '1': 'PC 2','2':'PC 3'})
fig.show()

Точно так же диаграммы рассеяния повторяют то, что мы видели в предыдущем разделе.

Последние мысли:

Я надеюсь, что вы нашли этот пост полезным. Цель этой статьи состояла в том, чтобы предоставить более компактную реализацию анализа главных компонентов. В этом случае моя реализация и PCA Sklearn дали одинаковые результаты, но может случиться так, что иногда они немного отличаются, если вы используете другой набор данных. Код GitHub находится здесь. Спасибо за прочтение. Хорошего дня!

Ссылки:

[1] Рак молочной железы, штат Висконсин (диагностический) набор данных

Вам понравилась моя статья? Стань участником и получай неограниченный доступ к новым публикациям по науке о данных каждый день! Это косвенный способ поддержать меня без каких-либо дополнительных затрат для вас. Если вы уже являетесь участником, подпишитесь, чтобы получать электронные письма всякий раз, когда я публикую новые руководства по науке о данных и Python!