Вероятностный PCA

Посмотреть на TensorFlow.org Запускаем в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

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

Импорт

import functools
import warnings

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

import tensorflow.compat.v2 as tf
import tensorflow_probability as tfp

from tensorflow_probability import bijectors as tfb
from tensorflow_probability import distributions as tfd

tf.enable_v2_behavior()

plt.style.use("ggplot")
warnings.filterwarnings('ignore')

Модель

Рассмотрим множество данных \(\mathbf{X} = \{\mathbf{x}_n\}\) из \(N\) точек, где каждая точка данных является \(D\)-мерном, $ \ mathbf {х} _n \ в \ mathbb {R} ^ D\(. We aim to represent each \)\ mathbf {х} _n $ под скрытой переменной \(\mathbf{z}_n \in \mathbb{R}^K\) с меньшей размерности, $ K <D\(. The set of principal axes \)\ mathbf {W} $ относится скрытые переменные к данным.

В частности, мы предполагаем, что каждая скрытая переменная имеет нормальное распределение,

\[ \begin{equation*} \mathbf{z}_n \sim N(\mathbf{0}, \mathbf{I}). \end{equation*} \]

Соответствующая точка данных создается с помощью проекции,

\[ \begin{equation*} \mathbf{x}_n \mid \mathbf{z}_n \sim N(\mathbf{W}\mathbf{z}_n, \sigma^2\mathbf{I}), \end{equation*} \]

где матрица \(\mathbf{W}\in\mathbb{R}^{D\times K}\) известны как главные оси. В вероятностной PCA, мы , как правило , заинтересованы в оценке главных осей \(\mathbf{W}\) , а термин шум\(\sigma^2\).

Вероятностный PCA обобщает классический PCA. За исключением скрытой переменной, распределение каждой точки данных выглядит следующим образом:

\[ \begin{equation*} \mathbf{x}_n \sim N(\mathbf{0}, \mathbf{W}\mathbf{W}^\top + \sigma^2\mathbf{I}). \end{equation*} \]

Классическая PCA является частным случаем вероятностного PCA , когда ковариация шума становится бесконечно малым, \(\sigma^2 \to 0\).

Мы настроили нашу модель ниже. В нашем анализе мы предполагаем \(\sigma\) известно, и вместо оценки точки \(\mathbf{W}\) в качестве параметра модели, мы размещаем перед над ним для того , чтобы вывести распределение по главным осям. Мы выражаем модель как TFP JointDistribution, в частности, мы будем использовать JointDistributionCoroutineAutoBatched .

def probabilistic_pca(data_dim, latent_dim, num_datapoints, stddv_datapoints):
  w = yield tfd.Normal(loc=tf.zeros([data_dim, latent_dim]),
                 scale=2.0 * tf.ones([data_dim, latent_dim]),
                 name="w")
  z = yield tfd.Normal(loc=tf.zeros([latent_dim, num_datapoints]),
                 scale=tf.ones([latent_dim, num_datapoints]),
                 name="z")
  x = yield tfd.Normal(loc=tf.matmul(w, z),
                       scale=stddv_datapoints,
                       name="x")
num_datapoints = 5000
data_dim = 2
latent_dim = 1
stddv_datapoints = 0.5

concrete_ppca_model = functools.partial(probabilistic_pca,
    data_dim=data_dim,
    latent_dim=latent_dim,
    num_datapoints=num_datapoints,
    stddv_datapoints=stddv_datapoints)

model = tfd.JointDistributionCoroutineAutoBatched(concrete_ppca_model)

Данные

Мы можем использовать модель для генерации данных путем выборки из совместного предварительного распределения.

actual_w, actual_z, x_train = model.sample()

print("Principal axes:")
print(actual_w)
Principal axes:
tf.Tensor(
[[ 2.2801023]
 [-1.1619819]], shape=(2, 1), dtype=float32)

Визуализируем набор данных.

plt.scatter(x_train[0, :], x_train[1, :], color='blue', alpha=0.1)
plt.axis([-20, 20, -20, 20])
plt.title("Data set")
plt.show()

PNG

Максимум апостериорного вывода

Сначала мы ищем точечную оценку скрытых переменных, которая максимизирует апостериорную плотность вероятности. Это известно как максимум апостериорного (MAP) вывод, и делается путем вычисления значений \(\mathbf{W}\) и \(\mathbf{Z}\) , которые максимизируют заднюю плотность \(p(\mathbf{W}, \mathbf{Z} \mid \mathbf{X}) \propto p(\mathbf{W}, \mathbf{Z}, \mathbf{X})\).

w = tf.Variable(tf.random.normal([data_dim, latent_dim]))
z = tf.Variable(tf.random.normal([latent_dim, num_datapoints]))

target_log_prob_fn = lambda w, z: model.log_prob((w, z, x_train))
losses = tfp.math.minimize(
    lambda: -target_log_prob_fn(w, z),
    optimizer=tf.optimizers.Adam(learning_rate=0.05),
    num_steps=200)
plt.plot(losses)
[<matplotlib.lines.Line2D at 0x7f19897a42e8>]

PNG

Мы можем использовать эту модель для выборки данных для выведенных значений для \(\mathbf{W}\) и \(\mathbf{Z}\), и сравнить с фактическим набором данных мы кондиционированными на.

print("MAP-estimated axes:")
print(w)

_, _, x_generated = model.sample(value=(w, z, None))

plt.scatter(x_train[0, :], x_train[1, :], color='blue', alpha=0.1, label='Actual data')
plt.scatter(x_generated[0, :], x_generated[1, :], color='red', alpha=0.1, label='Simulated data (MAP)')
plt.legend()
plt.axis([-20, 20, -20, 20])
plt.show()
MAP-estimated axes:
<tf.Variable 'Variable:0' shape=(2, 1) dtype=float32, numpy=
array([[ 2.9135954],
       [-1.4826864]], dtype=float32)>

PNG

Вариационный вывод

MAP можно использовать для поиска режима (или одного из режимов) апостериорного распределения, но он не дает никаких других сведений об этом. Далее мы используем вариационное умозаключение, где задняя distribtion \(p(\mathbf{W}, \mathbf{Z} \mid \mathbf{X})\) аппроксимируется с помощью вариационной распределения \(q(\mathbf{W}, \mathbf{Z})\) параметризуется \(\boldsymbol{\lambda}\). Цель состоит в том, чтобы найти в вариациях параметров \(\boldsymbol{\lambda}\) , что свести к минимуму расхождения между KL д и задним, \(\mathrm{KL}(q(\mathbf{W}, \mathbf{Z}) \mid\mid p(\mathbf{W}, \mathbf{Z} \mid \mathbf{X}))\), или , что эквивалентно, что максимизирует доказательства нижней границы, \(\mathbb{E}_{q(\mathbf{W},\mathbf{Z};\boldsymbol{\lambda})}\left[ \log p(\mathbf{W},\mathbf{Z},\mathbf{X}) - \log q(\mathbf{W},\mathbf{Z}; \boldsymbol{\lambda}) \right]\).

qw_mean = tf.Variable(tf.random.normal([data_dim, latent_dim]))
qz_mean = tf.Variable(tf.random.normal([latent_dim, num_datapoints]))
qw_stddv = tfp.util.TransformedVariable(1e-4 * tf.ones([data_dim, latent_dim]),
                                        bijector=tfb.Softplus())
qz_stddv = tfp.util.TransformedVariable(
    1e-4 * tf.ones([latent_dim, num_datapoints]),
    bijector=tfb.Softplus())
def factored_normal_variational_model():
  qw = yield tfd.Normal(loc=qw_mean, scale=qw_stddv, name="qw")
  qz = yield tfd.Normal(loc=qz_mean, scale=qz_stddv, name="qz")

surrogate_posterior = tfd.JointDistributionCoroutineAutoBatched(
    factored_normal_variational_model)

losses = tfp.vi.fit_surrogate_posterior(
    target_log_prob_fn,
    surrogate_posterior=surrogate_posterior,
    optimizer=tf.optimizers.Adam(learning_rate=0.05),
    num_steps=200)
print("Inferred axes:")
print(qw_mean)
print("Standard Deviation:")
print(qw_stddv)

plt.plot(losses)
plt.show()
Inferred axes:
<tf.Variable 'Variable:0' shape=(2, 1) dtype=float32, numpy=
array([[ 2.4168603],
       [-1.2236133]], dtype=float32)>
Standard Deviation:
<TransformedVariable: dtype=float32, shape=[2, 1], fn="softplus", numpy=
array([[0.0042499 ],
       [0.00598824]], dtype=float32)>

PNG

posterior_samples = surrogate_posterior.sample(50)
_, _, x_generated = model.sample(value=(posterior_samples))

# It's a pain to plot all 5000 points for each of our 50 posterior samples, so
# let's subsample to get the gist of the distribution.
x_generated = tf.reshape(tf.transpose(x_generated, [1, 0, 2]), (2, -1))[:, ::47]

plt.scatter(x_train[0, :], x_train[1, :], color='blue', alpha=0.1, label='Actual data')
plt.scatter(x_generated[0, :], x_generated[1, :], color='red', alpha=0.1, label='Simulated data (VI)')
plt.legend()
plt.axis([-20, 20, -20, 20])
plt.show()

PNG

Благодарности

Этот учебник был изначально написан на Эдварде 1.0 ( источник ). Мы благодарим всех участников за написание и исправление этой версии.

использованная литература

[1]: Майкл Э. Типпинг и Кристофер М. Бишоп. Вероятностный анализ главных компонент. Журнал Королевского статистического общества: Серия B (Статистическая методология), 61 (3): 611-622, 1999.