Подробное теоретическое объяснение и пример scikit-learn

Почему важен анализ главных компонентов?

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

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

По мере увеличения количества функций производительность классификатора через какой-то момент начинает снижаться. Чем больше функций, тем больше комбинаций, которые модель должна изучить, чтобы точно предсказать цель. Следовательно, при одинаковом количестве наблюдений (строк) модели, как правило, лучше работают с наборами данных с меньшим количеством функций. Более того, большое количество функций увеличивает риск переобучения.

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

Что я имею в виду под «хранением как можно большего количества информации»? Как мы измеряем количество информации? Ответ - дисперсия, которая является мерой разброса переменной. Если дисперсия переменной (признака) очень мала, это мало что говорит нам при построении модели. На рисунке ниже показано распределение двух переменных, x и y. Как видите, x находится в диапазоне от 1 до 6, а значения y находятся в диапазоне от 1 до 2. В этом случае x имеет высокую дисперсию. Если это единственные две функции для прогнозирования целевой переменной, роль x в прогнозе намного выше, чем y.

Изменения в текущих наборах данных должны сохраняться в максимально возможной степени при уменьшении размерности. Есть много способов уменьшить размерность. В этом посте я расскажу об одном из наиболее широко используемых алгоритмов уменьшения размерности: Анализ главных компонентов (PCA).

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

Как работает PCA?

Примечание. PCA - это алгоритм уменьшения линейной размерности. Доступны также нелинейные методы.

Сначала нам нужно сместить точки данных так, чтобы центр данных был в начале координат. Хотя положения отдельных точек данных меняются, относительные положения не меняются. Например, точка с наивысшим значением объекта 1 по-прежнему имеет наивысшее значение объекта 1. Затем PCA подгоняет линию к данным, что минимизирует расстояния от точек данных до линии.

Эта красная линия - новая ось или первый главный компонент (ПК1). Большую часть разброса набора данных можно объяснить ПК1. Второй основной компонент может объяснить вертикальную дисперсию по отношению к PC1.

Красная линия сортировки - это второй главный компонент (PC2). Порядок основных компонентов определяется в соответствии с той долей дисперсии исходного набора данных, которую они объясняют. Понятно, что PC1 объясняет гораздо больше отклонений, чем PC2.

Затем главные компоненты и точки данных поворачиваются так, что ПК1 становится новой осью x, а ПК2 становится новой осью y. Относительное положение точек данных не меняется. Основные компоненты ортогональны друг другу и, следовательно, линейно независимы.

Основные компоненты представляют собой линейные комбинации характеристик исходного набора данных.

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

Давайте рассмотрим пример с использованием scikit-learn. Scikit-learn - это библиотека машинного обучения, которая предоставляет простые и эффективные инструменты для прогнозного анализа данных.

Реализация Scikit Learn

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

Мы создаем DataFrame, используя эти точки данных, и назначаем класс для каждой из них.

import numpy as np
import pandas as pd
df = pd.DataFrame({
'feature_a':[2,1.5,2,2.5,3,2.5,3.7,2.8,1.8,3.3],
'feature_b':[1,1.2,2,1.5,3,2.4,3.5,2.8,1.5,2.5],
'target':['a','a','a','a','b','b','b','b','a','b']})

Итак, это задача двоичной классификации с двумя независимыми переменными.

Перед применением PCA нам необходимо стандартизировать данные так, чтобы среднее значение точек данных было равно 0, а дисперсия - 1. Scikit-learn предоставляет StandardScaler () из sklearn.preprocessing import StandardScaler

from sklearn.preprocessing import StandardScaler
df_features = df[['feature_a','feature_b']]
df_features = StandardScaler().fit_transform(df_features)

Затем мы создаем объект PCA () и подгоняем под него точки данных.

from sklearn.decomposition import PCA
pca = PCA(n_components=2)
PCs = pca.fit_transform(df_features)

Затем мы создаем новый фрейм данных, используя основные компоненты:

#Data visualization libraries
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
#Create DataFrame
df_new = pd.DataFrame(data=PCs, columns={'PC1','PC2'})
df_new['target'] = df['target'] #targets do not change

Мы можем нарисовать диаграмму рассеяния, чтобы увидеть новые точки данных:

fig = plt.figure(figsize = (8,4))
ax = fig.add_subplot()
ax.set_xlabel('PC1')
ax.set_ylabel('PC2')
targets = ['a', 'b']
colors = ['r', 'b']
for target, color in zip(targets,colors):
    rows = df_new['target'] == target
    ax.scatter(df_new.loc[rows, 'PC1'],
    df_new.loc[rows, 'PC2'],
    ax.legend(targets)

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

Как вы можете видеть на графике основных компонентов, два класса можно разделить, используя только PC1 вместо использования как feature_a, так и feature_b. Таким образом, можно сказать, что большая часть дисперсии объясняется PC1. Чтобы быть точным, мы можем подсчитать, насколько каждый главный компонент объясняет дисперсию. Scikit-learn предоставляет метод объясненная_вариантность_ для расчета этих сумм:

pca.explained_variance_ratio_
array([0.93606831, 0.06393169])

PC1 объясняет 93,6% отклонения, а PC2 объясняет 6,4%.

Примечание. Основные компоненты представляют собой линейную комбинацию исходных функций.

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

Спасибо за чтение. Пожалуйста, дайте мне знать, если у вас есть какие-либо отзывы.

Мои другие сообщения

Машинное обучение

Анализ данных