Это выдержка из главы 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 до ее реконструкции, и для этого мы используем норму L². Что сводится к нашей функции кодирования 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()
Это преобразованные данные.
Вы можете прочитать этот раздел и следующие темы:
- 02.01 — Скаляры, векторы, матрицы и тензоры
- 02.02 — Умножение матриц и векторов
- 02.03 — Тождественные и обратные матрицы
- 02.04 — Линейная зависимость и размах
- 02.05 — Нормы
- 02.06 — Специальные виды матриц и векторов
- 02.07 — Собственное разложение
- 02.08 — Разложение по сингулярным числам
- 02.09 — Псевдоинверсия Мура-Пенроуза
- 02.10 — Оператор трассировки
- 02.11 — Определяющая
- 02.12 — Пример: анализ основных компонентов
на Глубокое обучение с TF 2.0: 02.00-Линейная алгебра. Вы можете получить код этой статьи и остальной части главы здесь. Ссылки на блокнот в Google Colab и Jupyter Binder находятся в конце блокнота.