PRML Kapitel 7 Verwandte Vector Machine Python-Implementierung für Regressionsprobleme

Diesmal habe ich eine verwandte Vektormaschine implementiert. Es ist im Vergleich zur Support-Vektor-Maschine nicht so berühmt, aber es scheint Vorteile zu haben, beispielsweise, dass der Ausgabewert eine Wahrscheinlichkeit ist. Ich denke, dass viele Leute es verwenden werden, wenn es sich um Scikit-Learn handelt (eine Bibliothek, die Methoden des maschinellen Lernens implementiert), aber ich habe es nicht implementiert, weil Microsoft ein Patent hat.

Verwandte Vektormaschine

Kapitel 7 ist "Kernel-Maschinen mit spärlichen Lösungen", aber die Diskussion verwandter Vektor-Maschinen ist im Allgemeinen ohne Verwendung der Kernel-Methode gültig. Parameter wie lineare Regression{\bf w}Vorherige Verteilung vonp({\bf w}|\alpha)=\mathcal{N}({\bf w}|{\bf 0},\alpha^{-1}I)Als ein Superparameter\alphaIch habe das eingestellt

p({\bf w}|{\bf \alpha}) = \prod_i\mathcal{N}(w_i|0,\alpha_i^{-1})

** Führen Sie für jeden Parameter Superparameter ein **. Danach wird der Superparameter $ {\ bf \ alpha} $ auf dieselbe Weise geschätzt wie Kapitel 3 Evidence Approximation. Das geschätzte $ \ alpha $ hat viele Komponenten, die unendlich werden. Dies bedeutet, dass die Varianz des Parameters $ w $ $ \ alpha ^ {-1} $ nahe bei 0 liegt und der Parameter $ w $ eine steile Verteilung mit dem Durchschnitt der ursprünglich festgelegten vorherigen Verteilung von 0 ist. Der Wert des Parameters $ w $ wird spärlich und Features mit hoher Relevanz werden automatisch ausgewählt (automatische Relevanzbestimmung).

Verwandte Vektormaschine für Regressionsprobleme

Die Wahrscheinlichkeitsfunktion für den Gewichtsparameter $ {\ bf w} $, wenn N Trainingsdaten $ \ {x_n, t_n \} _ {n = 1} ^ N $ beobachtet werden, ist

\begin{align}
p({\bf t}|{\bf\Phi},{\bf w},\beta) &= \prod_{n=1}^N p(t_n|\phi(x_n),{\bf w}, \beta)\\
&= \prod_{n=1}^N \mathcal{N}(t_n|{\bf w}^{\rm T}\phi(x_n), \beta^{-1})
\end{align}

$ {\ Bf t} = (t_1, \ dots, t_N) ^ {\ rm T} $ und $ \ phi (\ cdot) $ verwendeten jedoch die folgenden Gaußschen Funktionen, die sich auf Trainingsdatenpunkte konzentrierten. Merkmalsvektor,

\phi(x) =
\begin{bmatrix}
\phi_1(x)\\
\vdots\\
\phi_N(x)
\end{bmatrix}
=
\begin{bmatrix}
a\exp(-b(x - x_1)^2)\\
\vdots\\
a\exp(-b(x-x_N)^2)
\end{bmatrix}、

$ {\ bf \ Phi} $ ist eine Planungsmatrix von $ N \ mal N $, deren Elemente $ \ Phi_ {ni} = \ phi_i (x_n) $ sind. Die hintere Verteilung des Gewichtungsparameters $ {\ bf w} $ ergibt sich aus dem Bayes-Theorem unter Verwendung von $ p ({\ bf w} | {\ bf \ alpha}) $ als vorherige Verteilung.

p({\bf w}|{\bf t},{\bf\Phi},{\bf\alpha},\beta) = \mathcal{N}({\bf w}|{\bf m},{\bf \Sigma})

Der Durchschnitt und die Kovarianz sind jedoch

\begin{align}
{\bf m} &= \beta{\bf\Sigma}{\bf\Phi}^{\rm T}{\bf t}\\
{\bf\Sigma} &= \left({\bf A} + \beta{\bf\Phi}^{\rm T}{\bf\Phi}\right)^{-1}
\end{align}

Die Matrix $ {\ bf A} $ ist eine diagonale Matrix mit Elementen $ A_ {ii} = \ alpha_i $.

Basierend auf der bisherigen Diskussion wird die wahrscheinlichste Schätzung der Superparameter $ {\ bf \ alpha}, \ beta $ durchgeführt. Die logarithmische Beweisfunktion ist $ {\ bf C} = \ beta ^ {-1} {\ bf I} + {\ bf \ Phi} {\ bf A} ^ {-1} {\ bf \ Phi} ^ {\ Als rm T} $

\begin{align}
\ln p({\bf t}|{\bf\Phi},{\bf\alpha},\beta) &= \ln\mathcal{N}({\bf t}|{\bf 0},{\bf C})\\
&= -{1\over2}\left\{N\ln(2\pi) + \ln|{\bf C}| + {\bf t}^{\rm T}{\bf C}^{-1}{\bf t}\right\}
\end{align}

Wird sein. Dies wird für $ {\ bf \ alpha}, \ beta $ unterschieden, um die Superparameter-Aktualisierungsgleichung zu erhalten. Als $ \ gamma_i = 1- \ alpha_i \ Sigma_ {ii} $

\begin{align}
\alpha_i^{new} &= {\gamma_i\over m_i^2}\\
\beta^{new} &= {N - \sum_i\gamma_i\over||{\bf t} - {\bf\Phi}{\bf m}||^2}
\end{align}

Berechnen Sie unter Verwendung der auf diese Weise erhaltenen neuen Superparameter $ {\ bf \ alpha} ^ {new}, \ beta ^ {new} $ die hintere Verteilung des Gewichtsparameters $ {\ bf w} $ erneut und dann super Wiederholen Sie die Aktualisierung der Parameter.

Verwandte Vektor

Dieses Mal verwenden wir eine Gaußsche Funktion, die auf den Trainingsdatenpunkten für den Merkmalsvektor zentriert ist, sodass der Wert des Parameters $ w $ angibt, wie viel die Trainingsdaten zur Vorhersage beitragen. ** Wenn die relevante Relevanzbestimmung von der zugehörigen Vektormaschine verwendet wird, werden viele Parameter $ w $ zu 0, und die den anderen Parametern entsprechenden Trainingsdaten werden als zugehöriger Vektor bezeichnet **. Bei der Berechnung der Vorhersageverteilung sollte die Verwendung nur der Merkmale, die den zugehörigen Vektoren entsprechen, das Vorhersageergebnis nicht wesentlich ändern.

Implementierung

Bibliothek

Auch hier ist der Algorithmus-Teil nur mit numpy codiert.

import matplotlib.pyplot as plt
import numpy as np

Verwandte Vektorregression

#Eine Klasse, die eine verwandte Vektorregression durchführt
class RelevanceVectorRegression(object):
    #Super Parameter Initialisierung
    def __init__(self, alpha=1., beta=1.):
        self.alpha = alpha
        self.beta = beta

    #Berechnung von Merkmalsvektoren mit dem Gaußschen Kernel
    def _kernel(self, x, y):
        return np.exp(-10 * (x - y) ** 2)

    #Super Parameter Alpha,Beta-Schätzung
    def fit(self, x, t, iter_max=1000):
        self.x = x
        self.t = t
        N = len(x)

        #Planungsmatrix
        Phi = self._kernel(*np.meshgrid(x, x))
        self.alphas = np.zeros(N) + self.alpha
        for _ in xrange(iter_max):
            params = np.hstack([self.alphas, self.beta])

            #Kovarianz-PRML-Gleichung für die posteriore Verteilung des Gewichtsparameters w(7.83)
            self.precision = np.diag(self.alphas) + self.beta * Phi.T.dot(Phi)
            self.covariance = np.linalg.inv(self.precision)

            #Durchschnittliche PRML-Gleichung für die posteriore Verteilung des Gewichtsparameters w(7.82)
            self.mean = self.beta * self.covariance.dot(Phi.T).dot(t)

            #Parametergültigkeit PRML-Ausdruck(7.89)
            gamma = 1 - self.alphas * np.diag(self.covariance)

            #Super Parameter Update PRML Ausdruck(7.87)
            self.alphas = gamma / np.square(self.mean)

            #10, so dass 0% nicht auftritt^10 Alpha über 10^Auf 10 setzen
            self.alphas = np.clip(self.alphas, 0, 1e10)

            #Super Parameter Update PRML Ausdruck(7.88)
            self.beta = (N - np.sum(gamma)) / np.sum((t - Phi.dot(self.mean)) ** 2)

            #Wenn der Umfang der Parameteraktualisierung gering ist, endet sie
            if np.allclose(params, np.hstack([self.alphas, self.beta])):
                break
        else:
            #Gibt die folgende Anweisung aus, wenn sie auch nach der angegebenen Aktualisierung nicht beendet wird
            print "paramters may not have converged"

    #Berechnen Sie die posteriore Vorhersageverteilung für Eingabe x
    def predict_dist(self, x):
        K = self._kernel(*np.meshgrid(x, self.x, indexing='ij'))

        #Mittlere PRML-Formel für die posteriore Vorhersageverteilung(7.90)
        mean = K.dot(self.mean)

        #Dispersions-PRML-Formel der posterioren Vorhersageverteilung(7.91)
        var = 1 / self.beta + np.sum(K.dot(self.covariance) * K, axis=1)

        #Gibt den Mittelwert und die Standardabweichung der posterioren Vorhersageverteilung zurück
        return mean, np.sqrt(var)

Ganzer Code

relevance_vector_regression.py


import matplotlib.pyplot as plt
import numpy as np


class RelevanceVectorRegression(object):

    def __init__(self, alpha=1., beta=1.):
        self.alpha = alpha
        self.beta = beta

    def _kernel(self, x, y):
        return np.exp(-10 * (x - y) ** 2)

    def fit(self, x, t, iter_max=1000):
        self.x = x
        self.t = t
        N = len(x)
        Phi = self._kernel(*np.meshgrid(x, x))
        self.alphas = np.zeros(N) + self.alpha
        for _ in xrange(iter_max):
            params = np.hstack([self.alphas, self.beta])
            self.precision = np.diag(self.alphas) + self.beta * Phi.T.dot(Phi)
            self.covariance = np.linalg.inv(self.precision)
            self.mean = self.beta * self.covariance.dot(Phi.T).dot(t)
            gamma = 1 - self.alphas * np.diag(self.covariance)
            self.alphas = gamma / np.square(self.mean)
            self.alphas = np.clip(self.alphas, 0, 1e10)
            self.beta = (N - np.sum(gamma)) / np.sum((t - Phi.dot(self.mean)) ** 2)
            if np.allclose(params, np.hstack([self.alphas, self.beta])):
                break
        else:
            print "paramters may not have converged"

    def predict_dist(self, x):
        K = self._kernel(*np.meshgrid(x, self.x, indexing='ij'))
        mean = K.dot(self.mean)
        var = 1 / self.beta + np.sum(K.dot(self.covariance) * K, axis=1)
        return mean, np.sqrt(var)


def create_toy_data(func, low=0., high=1., n=10, std=0.1):
    x = np.random.uniform(low, high, n)
    t = func(x) + np.random.normal(scale=std, size=n)
    return x, t


def main():

    def func(x):
        return np.sin(2 * np.pi * x)

    x, t = create_toy_data(func, n=10)
    plt.scatter(x, t, color="blue", alpha=0.5, label="observation")

    regression = RelevanceVectorRegression()
    regression.fit(x, t)
    relevance_vector = np.abs(regression.mean) > 0.1

    x_test = np.linspace(0, 1, 100)
    plt.scatter(x[relevance_vector], t[relevance_vector], color="green", s=100, marker="D", label="relevance vector")
    plt.plot(x_test, func(x_test), color="blue", label="sin($2\pi x$)")
    y, y_std = regression.predict_dist(x_test)
    plt.plot(x_test, y, color="red", label="predict_mean")
    plt.fill_between(x_test, y - y_std, y + y_std, color="pink", alpha=0.5, label="predict_std")
    plt.legend()
    plt.show()


if __name__ == '__main__':
    main()

Ergebnis

Als Ergebnis des Zurückziehens der blauen und grünen Punkte als Trainingsdaten mit der zugehörigen Vektormaschine ist das Ergebnis wie in der folgenden Abbildung gezeigt (Reproduktion von PRML Abbildung 7.9). Die grünen Punkte werden als verwandte Vektoren dargestellt. result.png

Am Ende

Es scheint, dass es schnellere Vorhersagen treffen kann, während es die gleiche Generalisierungsleistung wie die Support-Vektor-Maschine aufweist. Daher möchte ich diese Gelegenheit nutzen, um nicht nur die Support-Vektor-Maschine, sondern auch die zugehörige Vektor-Maschine zu verwenden. Es ist auch ein schöner Vorteil, die Ausgabe wie Bayes behandeln und die Verteilung bewerten zu können. Es ist jedoch schade, dass die prädiktive Varianz gegen die menschliche Intuition klein wird, wenn keine Trainingsdatenpunkte vorhanden sind. Dieses Mal habe ich das Regressionsproblem mit der zugehörigen Vektormaschine gelöst, aber es kann natürlich mithilfe der logistischen Sigmoid-Funktion auf das Klassifizierungsproblem erweitert werden. Wenn ich eine Chance habe, würde ich das auch gerne umsetzen.

Recommended Posts

PRML Kapitel 7 Verwandte Vector Machine Python-Implementierung für Regressionsprobleme
PRML Kapitel 4 Bayesianische logistische Regression Python-Implementierung
PRML Kapitel 6 Gaussian Return Python-Implementierung
PRML Kapitel 5 Python-Implementierung für neuronale Netze
PRML Kapitel 3 Evidence Ungefähre Python-Implementierung
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 7 Regressionsanalyse
PRML Kapitel 8 Summe der Produkte Algorithmus Python-Implementierung
PRML Kapitel 5 Python-Implementierung eines Netzwerks mit gemischter Dichte
PRML Kapitel 9 Mixed Gaussian Distribution Python-Implementierung
PRML Kapitel 14 Bedingte gemischte Modell-Python-Implementierung
PRML Kapitel 10 Variante Mixed Gaussian Distribution Python-Implementierung
PRML Kapitel 2 Python-Implementierung von Student t-Distribution
PRML Kapitel 1 Bayesian Curve Fitting Python-Implementierung
Implementiert in Python PRML Kapitel 3 Bayesianische lineare Regression
PRML Kapitel 11 Implementierung der Markov-Kette Monte Carlo Python
PRML Kapitel 12 Bayesianische Hauptanalyse Python-Implementierung
Python-Lernnotiz für maschinelles Lernen von Chainer aus Kapitel 2
Python für die Datenanalyse Kapitel 4
Python für die Datenanalyse Kapitel 2
Python für die Datenanalyse Kapitel 3
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 8 Einführung in Numpy
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 10 Einführung in Cupy
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 9 Einführung in das Scikit-Lernen
PRML Kapitel 13 Wahrscheinlichste Schätzung Python-Implementierung des Hidden-Markov-Modells
Erläuterung und Implementierung von PRML Kapitel 4
<Kurs> Maschinelles Lernen Kapitel 7: Support Vector Machine
<Für Anfänger> Python-Bibliothek <Für maschinelles Lernen>
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 13 Training für neuronale Netze ~ Chainer abgeschlossen
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 13 Grundlagen des neuronalen Netzwerks
Python-Lernnotiz für maschinelles Lernen von Chainer bis zum Ende von Kapitel 2
<Subjekt> Maschinelles Lernen Kapitel 3: Logistisches Regressionsmodell
PRML: Kapitel 7 Kernel-Maschine mit spärlicher Lösung
Verstärken Sie Bilder für maschinelles Lernen mit Python
PRML-Implementierung Kapitel 3 Lineares Basisfunktionsmodell
Implementiert in Python PRML Kapitel 7 Nichtlineare SVM
Warum Python für maschinelles Lernen ausgewählt wird
[Shakyo] Begegnung mit Python zum maschinellen Lernen
<Kurs> Maschinelles Lernen Kapitel 1: Lineares Regressionsmodell
[Python] Webanwendungsdesign für maschinelles Lernen
Support Vector Machine (für Anfänger) -Code Edition-
<Kurs> Maschinelles Lernen Kapitel 2: Nichtlineares Regressionsmodell
Eine Einführung in Python für maschinelles Lernen
[Python] Ich habe die Theorie und Implementierung der Support Vector Machine (SVM) ausführlich erklärt.