[PYTHON] Nicht parametrische Buchten mit Pyro

Nichtparametrische Felder werden als Modelle mit unendlich dimensionalen Feldern bezeichnet. Der in Vorheriger Artikel durchgeführte Gauß-Prozess ist ebenfalls nicht parametrisch, aber ein anderer berühmter Prozess ist der ** Diricre-Prozess **. Eine theoretische Erklärung finden Sie unter "Nichtparametrische Buchten (professionelle Serie für maschinelles Lernen)" und Qiita-Artikel hier.

Zunächst wird die Bayes'sche Inferenz in den folgenden drei Schritten durchgeführt. (1) Definieren Sie die vorherige Verteilung der Parameter und das Wahrscheinlichkeitsmodell des Ereignisses (2) Berechnen Sie die Wahrscheinlichkeit aus den erhaltenen Daten und dem Wahrscheinlichkeitsmodell und berechnen Sie die Parameter-Posterior-Verteilung, indem Sie sie mit der Parameter-Vorverteilung multiplizieren (Bayes-Theorem). (3) Generieren Sie eine vorhergesagte Wahrscheinlichkeitsverteilung von Daten aus dem Parameter posteriorer Verteilung und Wahrscheinlichkeitsmodell Die Verteilung, bei der die vorherige Verteilung und die hintere Verteilung in ② gleich sind, wird als konjugierte vorherige Verteilung bezeichnet. So wie die Beta-Verteilung die konjugierte vorherige Verteilung des Binomialverteilungsmodells ist, ist die Diricre-Verteilung die konjugierte vorherige Verteilung des Polynomverteilungsmodells. Mit anderen Worten, die Diricre-Verteilung ist eine multivariate Verteilung der Beta-Verteilung.

Der Diricle-Prozess berücksichtigt die Diricle-Verteilung in unendlichen Dimensionen. Es scheint, dass der Gaußsche Prozess eine unendlich dimensionale multivariate Gaußsche Verteilung ist. Während der Gaußsche Prozess kontinuierlich ist, ist der Diricre-Prozess diskret. Da es diskret ist, ist es ein Bild, das als stochastisches Modell für Cluster dient. Dies ermöglicht das Clustering (Diliquere Process Mixing Model (DPMM)), das automatisch die Anzahl der Cluster bestimmt. Der Diricle-Prozess ist jedoch aufgrund der unendlichen Anzahl von Elementen schwierig zu implementieren. Es gibt also zwei Möglichkeiten. (1) Eine Methode zur Approximation mit endlichen Dimensionen anstelle von unendlich. Es verwendet den Cut-Off-Bar-Folding-Prozess (TSB) und die endliche symmetrische Richtungsverteilung (FSD). Es ist möglich, mit der Variante Bayes zu lösen. (2) Eine Methode unter Verwendung des chinesischen Restaurantprozesses (CRP) und des Pitman-Yo-Prozesses, bei der eine unendliche Anzahl von Elementen integriert und eliminiert wird. Diese Methode erlaubt keine variablen Einschübe, nur MCMC.

Dieses Mal werden wir von ① mit Pyro implementieren.

Diricle Process Mixed Model (TSB) mit Pyro

Beispielsweise ist es bei der k-means-Methode und beim Clustering im Gaußschen Mischmodell erforderlich, die Anzahl der Cluster als Parameter anzugeben. (AIC berechnen und anpassen usw.) Andererseits kann beim Clustering mit diesem gemischten Prozess des Diricle-Prozesses die Anzahl der Cluster automatisch bestimmt werden, was ein flexibles Clustering ermöglicht.

In Pyro hat der Diricle-Prozess keine dedizierte Klasse wie der Gauß-Prozess, daher wird er aus dem Modell implementiert. Dieses Mal implementieren wir TSB (Cut-Off-Bar-Faltprozess) unter Bezugnahme auf Beispiel eines offiziellen Tutorials.

import torch
import pyro
import pyro.distributions as dist
import matplotlib.pyplot as plt
pyro.set_rng_seed(101)

Erstellen Sie zunächst die Daten. Probieren Sie 200 Daten aus jeder der vier zweidimensionalen Gaußschen Verteilungen aus.

num = 200
data = torch.cat((dist.MultivariateNormal(-8 * torch.ones(2), torch.eye(2)).sample([num]),
                  dist.MultivariateNormal(8 * torch.ones(2), torch.eye(2)).sample([num]),
                  dist.MultivariateNormal(torch.tensor([-5., 5.]), torch.eye(2)).sample([num]),
                  dist.MultivariateNormal(torch.tensor([6., -5.]), torch.eye(2)).sample([num])
                 ))
plt.scatter(data[:, 0], data[:, 1])
plt.show()

image.png

Clusteren Sie diese 800 Daten, ohne die Anzahl der Cluster anzugeben.

Definieren Sie eine Funktion zum Falten eines Balkens.

import torch.nn.functional as F
def mix_weights(beta):
    beta1m_cumprod = (1 - beta).cumprod(-1)
    return F.pad(beta, (0, 1), value=1) * F.pad(beta1m_cumprod, (1, 0), value=1)

Definiert ein Wahrscheinlichkeitsmodell für TSB. Alpha ist ein Konzentrationsparameter, der den Grad der Klassenvariation darstellt. T ist die Obergrenze der Anzahl von Clustern. Diesmal habe ich es auf 10 gesetzt.

N = data.shape[0]
T = 10
alpha = 0.1
def model(data):
    with pyro.plate("beta_plate", T-1):
        beta = pyro.sample("beta", dist.Beta(1, alpha))
    with pyro.plate("mu_plate", T):
        mu = pyro.sample("mu", dist.MultivariateNormal(torch.zeros(2), 5 * torch.eye(2)))
    with pyro.plate("data", N):
        z = pyro.sample("z", dist.Categorical(mix_weights(beta)))
        pyro.sample("obs", dist.MultivariateNormal(mu[z], torch.eye(2)), obs=data)

Sie können Autoguide nicht verwenden, definieren Sie also Ihre eigene Führungsfunktion.

from torch.distributions import constraints
def guide(data):
    kappa = pyro.param('kappa', lambda: dist.Uniform(0, 2).sample([T-1]), constraint=constraints.positive)
    tau = pyro.param('tau', lambda: dist.MultivariateNormal(torch.zeros(2), 3 * torch.eye(2)).sample([T]))
    phi = pyro.param('phi', lambda: dist.Dirichlet(1/T * torch.ones(T)).sample([N]), constraint=constraints.simplex)
    with pyro.plate("beta_plate", T-1):
        q_beta = pyro.sample("beta", dist.Beta(torch.ones(T-1), kappa))
    with pyro.plate("mu_plate", T):
        q_mu = pyro.sample("mu", dist.MultivariateNormal(tau, torch.eye(2)))
    with pyro.plate("data", N):
        z = pyro.sample("z", dist.Categorical(phi))

Führen Sie Variant Bayes aus.

from pyro.optim import Adam
from pyro.infer import SVI, Trace_ELBO
from tqdm import tqdm
optim = Adam({"lr": 0.05})
svi = SVI(model, guide, optim, loss=Trace_ELBO())
losses = []
num_step = 1000
pyro.clear_param_store()
for j in tqdm(range(num_step)):
    loss = svi.step(data)
    losses.append(loss)
plt.plot(losses)
plt.xlabel("step")
plt.ylabel("loss")

image.png

Definieren Sie eine Funktion, um eine Klasse mit einer geringen posterioren Wahrscheinlichkeit zu eliminieren (abzubrechen).

def truncate(alpha, centers, weights):
    threshold = alpha**-1 / 100.
    print(threshold)
    true_centers = centers[weights > threshold]
    true_weights = weights[weights > threshold] / torch.sum(weights[weights > threshold])
    return true_centers, true_weights

Beseitigen Sie die weniger wahrscheinliche Klasse und zeigen Sie das Vorhersageergebnis an.

Bayes_Centers, Bayes_Weights = truncate(alpha, pyro.param("tau").detach(), torch.mean(pyro.param("phi").detach(), dim=0))
plt.scatter(data[:, 0], data[:, 1], color="blue")
plt.scatter(Bayes_Centers[:, 0], Bayes_Centers[:, 1], color="red")

image.png Es wurden vier Klassen anerkannt. Ich denke, das Zentrum ist auch ziemlich genau erfasst. Dies ist ein gutes Beispiel, aber es hat in Abhängigkeit von den Werten von Alpha und T nicht funktioniert.

Andere Anwendungen

Strukturänderungsschätzung

Wenn wir ein lineares Regressionsmodell auf Zeitreihendaten anwenden, betrachten wir ein unendliches lineares Modell nach dem Diricle-Prozess. Durch Clustering für jedes Modell können Zeitreihendaten segmentiert werden. Referenz: https://www.slideshare.net/shotarosano5/in-62843951

HDP-LDA LDA (Potential Diricle Allocation Method) ist unbeaufsichtigtes Lernen und wird in Themenmodellen verwendet. (LDA Pyro-Implementierungsbeispiel) HDP-LDA mit HDP (Hierarchical Diricle Process) kann automatisch die entsprechende Anzahl von Themen ermitteln. Mit einer Python-Bibliothek namens Gensim scheint es einfach zu sein. Der hierarchische Diricre-Prozess orientiert sich am CRF (Chinese Restaurant Franchise), der einen Schritt komplizierter ist als der CRP (Chinese Restaurant Process).

das Ende

Ich dachte, dass nicht parametrische Felder nicht parameterlos sind, sondern dass sie an eine unendliche oder große Anzahl von Parametern denken (es gibt keine Einschränkung für die Anzahl von Parametern). Beachten Sie jedoch, dass bei dieser Implementierung von TSB die Obergrenze für die Anzahl der Cluster festgelegt werden muss. Ich möchte auch Implementieren von CRP ausprobieren, für das keine Obergrenze erforderlich ist.

Recommended Posts

Nicht parametrische Buchten mit Pyro
Einführung in nichtparametrische Felder
Deep Kernel Learning mit Pyro
[Python] Bayesianische Schätzung mit Pyro
[Python] Gemischtes Gaußsches Modell mit Pyro
Textfilterung mit naiven Buchten von sklearn