Анализ основных компонентов используется для уменьшения размерности и выяснения того, как переменные ковариируют.

В области машинного обучения (МО) и искусственного интеллекта (ИИ) существует два основных подхода к работе с данными: контролируемое и неконтролируемое машинное обучение. В отличие от обучения с учителем, при котором мы помещаем данные в таблицу для обучения модели, при обучении без учителя мы этого не делаем. Таким образом, контролируемые методы в основном предназначены для прогнозирования. Для неконтролируемого обучения, поскольку нет никакой истинной истины / ярлыка, мы в основном используем его для описательного анализа. Другими словами, неконтролируемое обучение используется для открытия знаний.

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

Анализ основных компонентов (PCA)

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

где i находится в диапазоне от 1 до общего количества переменных. Веса называются нагрузками компонентов. Они преобразуют исходные переменные в главные компоненты. Первый главный компонент, Z1, представляет собой линейную комбинацию, которая лучше всего объясняет общую вариацию. Второй главный компонент, Z2, ортогонален первому и объясняет как можно большую часть оставшейся вариации. (Если бы были дополнительные компоненты, каждый дополнительный был бы ортогонален другим) [1].

Реализация PCA на Python

Чтобы продемонстрировать применение PCA к реальным задачам, мы применяем PCA к набору данных Фондовый рынок. Полный набор данных можно скачать с веб-сайта Kaggle. Он состоит из нескольких цен акций 29 из 30 компаний, входящих в индекс DJIA (исключая V, потому что у него нет данных за все 12 лет). Мы будем использовать пакет Sci-kit Learn для реализации PCA при возврате акций. Полный код можно найти здесь.

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

dic_stock_return = defaultdict(int)
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))
        df = pd.read_csv(os.path.join(dirname, filename))
        df['return'] = (df.Close - df.Open) / df.Open
        dic_stock_return[df.Name[0]] = df['return']
df_stock_return = pd.DataFrame(dic_stock_return)
df_stock_return.head()

Первые 5 строк этого фрейма данных выглядят следующим образом:

#drop last row since it is NaN
tech_px = tech_px.drop(3019)
pcs = PCA(n_components=2)
pcs.fit(tech_px)
loadings = pd.DataFrame(pcs.components_, columns=tech_px.columns)
print(loadings)

нагрузки будут

Как это интерпретировать? Первый главный компонент представляет собой среднее значение GOOGL и AAPL, отражающее корреляцию между двумя энергетическими компаниями. Второй главный компонент показывает, когда цены акций GOOGL и AAPL расходятся. Чтобы визуализировать анализ основных компонентов, мы можем использовать следующий код Python.

def abline(slope, intercept, ax):
    """Calculate coordinates of a line based on slope and intercept"""
    x_vals = np.array(ax.get_xlim())
    return (x_vals, intercept + slope * x_vals)
ax = tech_px.plot.scatter(x='GOOGL', y='AAPL', alpha=0.3, figsize=(14, 14))
ax.set_xlim(-0.2, 0.2)
ax.set_ylim(-0.2, 0.2)
ax.plot(*abline(loadings.loc[0, 'AAPL'] / loadings.loc[0, 'GOOGL'], 0, ax),
        '--', color='C1')
ax.plot(*abline(loadings.loc[1, 'AAPL'] / loadings.loc[1, 'GOOGL'], 0, ax),
        '--', color='C1')
plt.tight_layout()
plt.show()

Результат будет

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

#remove rows with at least one NaN values
nan_rows = df_stock_return[df_stock_return.isnull().T.any()]
df_stock_return = df_stock_return.drop(list(nan_rows.index))
syms = sorted(['MMM', 'AXP', 'AAPL', 'BA', 'CAT', 'CVX', 'CSCO', 'KO', 'DIS', 'XOM', 'GE',
               'GS', 'HD', 'IBM', 'INTC', 'JNJ', 'JPM', 'MCD', 'MRK', 'MSFT', 'NKE', 'PFE',
               'PG', 'TRV', 'UTX', 'UNH', 'VZ', 'WMT', 'GOOGL', 'AMZN', 'AABA'])
top_df = df_stock_return[syms]
sp_pca = PCA()
sp_pca.fit(top_df)
explained_variance = pd.DataFrame(sp_pca.explained_variance_)
#showing the first value
ax = explained_variance.head(10).plot.bar(legend=False, figsize=(8, 4))
ax.set_xlabel('Component')
plt.tight_layout()
plt.show()

Первые 10 объясненных отклонений для компонентов будут следующими:

Для нагрузок первых 5 компонентов имеем

loadings = pd.DataFrame(sp_pca.components_[0:5, :], 
                        columns=top_df.columns)
maxPC = 1.01 * np.max(np.max(np.abs(loadings.loc[0:5, :])))
f, axes = plt.subplots(5, 1, figsize=(15, 10), sharex=True)
for i, ax in enumerate(axes):
    pc_loadings = loadings.loc[i, :]
    colors = ['C0' if l > 0 else 'C1' for l in pc_loadings]
    ax.axhline(color='#888888')
    pc_loadings.plot.bar(ax=ax, color=colors)
    ax.set_ylabel(f'PC{i+1}')
    ax.set_ylim(-maxPC, maxPC)
plt.tight_layout()
plt.show()

Нагрузки первых 5 компонентов могут быть показаны как

Как интерпретировать PCA?

Нагрузки для первой главной компоненты имеют одинаковый знак: это характерно для данных, в которых все столбцы имеют общий фактор (в данном случае общий тренд фондового рынка). Второй компонент фиксирует изменения цен акций Tech по сравнению с другими акциями. Третья составляющая – это прежде всего контраст в движениях JP Morgan (JPM) и Goldman Sachs (GS). Четвертый компонент противопоставляет движения акций UnitedHealth (UNH) другим энергетическим компаниям. Наконец, в пятом компоненте преобладают нетехнологические компании.

Ссылка

[1] Брюс, Питер, Эндрю Брюс и Питер Гедек. Практическая статистика для специалистов по данным: более 50 основных концепций использования R и Python. О'Рейли Медиа, 2020.