Olasılıksal PCA

Olasılık temel bileşenler analizi (PCA) bir alt boyutlu gizli boşluk yoluyla verileri analiz bir boyut indirgeme tekniğidir ( Devirme Bishop 1999 ). Genellikle verilerde eksik değerler olduğunda veya çok boyutlu ölçekleme için kullanılır.

ithalat

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')

Model

Bir veri seti düşünün X={xn} arasında N her bir veri noktası olan veri noktaları, Dboyutlu,  mathbfxn in mathbbRD\(.Weaimtorepresenteach\) mathbfxnbirlatentdeğişkenaltında znRK düşük bir boyuta sahip, K<D\(.Thesetofprincipalaxes\) mathbfB verilerine gizli değişkenler ile ilgilidir.

Spesifik olarak, her bir gizli değişkenin normal dağıldığını varsayıyoruz,

znN(0,I).

Karşılık gelen veri noktası bir projeksiyon yoluyla oluşturulur,

xnznN(Wzn,σ2I),

burada matris WRD×K ana eksen olarak da bilinir. Olasılık PCA, biz genellikle ana eksenleri tahmin ilgilenen edilir W ve gürültü terimiσ2.

Olasılıksal PCA, klasik PCA'yı genelleştirir. Gizli değişkeni marjinalleştirerek, her veri noktasının dağılımı

xnN(0,WW+σ2I).

Gürültü kovaryans sonsuz küçüklükteki, olduğunda Klasik PCA olasılık PCA özgül durumda σ20.

Aşağıdaki modelimizi kurduk. Bizim analizde, biz varsayalım σ bilinir ve bunun yerine tahmin noktasının W bir modeli parametresi olarak, biz ana eksen üzerinde dağılımını anlamak amacıyla üzerine bir önceki yerleştirin. Özellikle, biz kullanacağız, bir TFP JointDistribution olarak modelini ifade edeceğiz 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)

Veri

Modeli, ortak ön dağılımdan örnekleyerek veri üretmek için kullanabiliriz.

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)

Veri setini görselleştiriyoruz.

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

Maksimum Arka Çıkarım

İlk önce, sonsal olasılık yoğunluğunu maksimize eden gizli değişkenlerin nokta tahminini ararız. Bu maksimum olarak a posteriori (MAP) çıkarsama bilinmektedir ve değerlerinin hesaplanması yapılır W ve Z arka yoğunluğu en üst düzeye çıkarmak p(W,ZX)p(W,Z,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

Biz bilgilerin tahmin değerleri için örnek verilerine modeli kullanabilirsiniz W ve Zve biz koşuluna gerçek veri kümesine karşılaştırın.

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

Varyasyon çıkarımı

MAP, sonsal dağılımın modunu (veya modlardan birini) bulmak için kullanılabilir, ancak bununla ilgili başka bir bilgi sağlamaz. Önümüzdeki arka distribtion varyasyon parazitine kullanmak p(W,ZX) bir varyasyon dağıtım kullanılarak yaklaşılır q(W,Z) tarafından parametrize λ. Amaç varyasyon parametreler bulmaktır λ q ve posterior arasında KL ayrışmayı en aza o KL(q(W,Z)∣∣p(W,ZX))alt bağlı delilleri maksimize eşdeğer veya Eq(W,Z;λ)[logp(W,Z,X)logq(W,Z;λ)].

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

Teşekkür

Bu eğitimde başlangıçta Edward 1,0 (yazılmış kaynak ). Bu sürümü yazmaya ve revize etmeye katkıda bulunan herkese teşekkür ederiz.

Referanslar

[1]: Michael E. Bahşiş ve Christopher M. Bishop. Olasılıksal temel bileşen analizi. Kraliyet İstatistik Derneği Dergisi: Seri B (İstatistiksel Metodolojisi), 61 (3): 611-622, 1999.