Это выдержка из главы 2, раздела двенадцатой книги Глубокое обучение с Tensorflow 2.0.

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

Ранее, когда мы выполняли транспонирование или обратную матрицу, мы полагались на встроенные функции Tensorflow, но для PCA такой функции нет, кроме одной в Tensorflow Extended (tft).

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

Причина включения PCA в линейную алгебру состоит в том, чтобы показать, что PCA можно реализовать с помощью теорем, которые мы изучали в этой главе.

# To start working with PCA, let’s start by creating a 2D data set
x_data = tf.multiply(5, tf.random.uniform([100], minval=0, maxval=100, dtype = tf.float32, seed = 0))
y_data = tf.multiply(2, x_data) + 1 + tf.random.uniform([100], minval=0, maxval=100, dtype = tf.float32, seed = 0)
X = tf.stack([x_data, y_data], axis=1)
plt.rc_context({‘axes.edgecolor’:’orange’, ‘xtick.color’:’red’, ‘ytick.color’:’red’})
plt.plot(X[:,0], X[:,1], ‘+’, color=’b’)
plt.grid()

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

def normalize(data):
 # creates a copy of data
 X = tf.identity(data)
 # calculates the mean
 X -=tf.reduce_mean(data, axis=0)
 return X
normalized_data = normalize(X)
plt.plot(normalized_data[:,0], normalized_data[:,1], ‘+’, color=’b’)
plt.grid()

Напомним, что PCA можно рассматривать как применение сжатия с потерями к набору точек данных x. Мы можем минимизировать потерю точности, найдя некоторую функцию декодирования f(x) ≈ c, где c будет соответствующим вектором.

PCA определяется нашим выбором этой функции декодирования. В частности, чтобы упростить декодер, мы решили использовать умножение матриц для отображения c и определить g(c) = Dc. Наша цель — минимизировать расстояние между входной точкой x до ее реконструкции, и для этого мы используем норму . Что сводится к нашей функции кодирования c = D^T x.

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

Обратите внимание, что следующее уравнение является окончательной версией многих матричных преобразований. Я не привожу производные, потому что цель состоит в том, чтобы сосредоточиться на математической реализации, а не на выводе. Но для любопытных Вы можете прочитать о выводе в Главе 2 Разделе 11.

d^* = argmax_d Tr(d^T X^T Xd) с учетом dd^T = 1

Чтобы найти d, мы можем вычислить собственные векторы X^T X.

# Finding the Eigne Values and Vectors for the data
eigen_values, eigen_vectors = tf.linalg.eigh(tf.tensordot(tf.transpose(normalized_data), normalized_data, axes=1))
print(“Eigen Vectors: \n{} \nEigen Values: \n{}”.format(eigen_vectors, eigen_values))
Eigen Vectors:
[[-0.8908606 -0.45427683]
[ 0.45427683 -0.8908606 ]]
Eigen Values:
[ 16500.715 11025234. ]

Собственные векторы (главные компоненты) определяют направления нового пространства признаков, а собственные значения определяют их величину.

Теперь давайте используем эти собственные векторы для поворота наших данных. Цель поворота состоит в том, чтобы в конечном итоге получить новую систему координат, в которой данные некоррелированы и, следовательно, где базисные оси собирают всю дисперсию. Тем самым уменьшая размерность.

Вспомним нашу функцию кодирования c = D^T x, где D — матрица, содержащая собственные векторы, которые мы вычислили ранее.

X_new = tf.tensordot(tf.transpose(eigen_vectors), tf.transpose(normalized_data), axes=1)
plt.plot(X_new[0, :], X_new[1, :], ‘+’, color=’b’)
plt.xlim(-500, 500)
plt.ylim(-700, 700)
plt.grid()

Это преобразованные данные.

Вы можете прочитать этот раздел и следующие темы:

на Глубокое обучение с TF 2.0: 02.00-Линейная алгебра. Вы можете получить код этой статьи и остальной части главы здесь. Ссылки на блокнот в Google Colab и Jupyter Binder находятся в конце блокнота.