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.
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
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).
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.
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.
Auch hier ist der Algorithmus-Teil nur mit numpy codiert.
import matplotlib.pyplot as plt
import numpy as np
#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)
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()
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.
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