[PYTHON] Algorithmus für maschinelles Lernen (Zusammenfassung und Regularisierung der linearen Regression)

Einführung

Schritt für Schritt zur Theorie, Implementierung in Python und Analyse mit scikit-learn über den Algorithmus, der zuvor in "Klassifikation des maschinellen Lernens" verwendet wurde. Ich werde mit lernen. Ich schreibe es zum persönlichen Lernen, daher möchte ich, dass Sie alle Fehler übersehen.

Dieses Mal werde ich als Zusammenfassung der linearen Regressionsausgabe die lineare Approximation unter Verwendung des Gaußschen Kernels sowie der L1-Regularisierung (Lasso) und der L2-Regularisierung (Ridge) zusammenfassen, die das Übertraining unterdrücken.

Die folgenden Seiten wurden auf diese Zeit verwiesen. Vielen Dank.

Über die Kernel-Approximation

Als ich früher über [Verallgemeinerung der linearen Regression] schrieb (https://qiita.com/hiro88hyo/items/11ef220db50a87545027), schrieb ich, dass "die Basisfunktion alles sein kann". Selbst in der tatsächlichen Regression ist es nicht immer möglich, mit einer geraden Linie zu approximieren, und es ist auch notwendig, eine Knöchelnäherung wie eine polymorphe Funktion oder eine Dreiecksfunktion vorzunehmen.

Betrachten Sie beispielsweise $ y = -xsin (x) + \ epsilon $ mit Rauschen, das zu $ y = -xsin (x) $ hinzugefügt wird.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib inline

fig, ax = plt.subplots()

t = np.linspace(0, 2*np.pi, 100)
y1 = - t * np.sin(t)

n=40
np.random.seed(seed=2020)
x = 2*np.pi * np.random.rand(n)
y2 = - x * np.sin(x) + 0.4 * np.random.normal(loc=0.0, scale=1.0, size=n)

ax.scatter(x, y2, color='blue', label="sample(with noise)")
ax.plot(t, y1, color='green', label="-x * sin(x)")
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=11)

plt.show()
gaussian_regression_1.png

Die blauen Punkte sind Beispiele mit Rauschen, und die durchgezogenen grünen Linien zeigen die erwarteten Funktionen. Das Rauschen wurde mit Zufallszahlen addiert, aber der Startwert der Zufallszahlen wurde festgelegt, so dass jedes Mal das gleiche Ergebnis erzielt wurde.

Diesmal ist die Zielfunktion bekannt, sie muss jedoch aus dem Zustand geschätzt werden, in dem nicht bekannt ist, ob die Stichprobe ein Polynom oder eine andere Funktion ist.

Über den Gaußschen Kernel

Der Gaußsche Kernel ist wie folgt definiert:

k(\boldsymbol{x}, \boldsymbol{x'})=\exp(-\beta||\boldsymbol{x}-\boldsymbol{x'}||^2)

||\boldsymbol{x}-\boldsymbol{x'}||^2Ist der Abstand zwischen den Vektoren,$\sqrt{\sum_{j=1}^{n}(x_j-x'_j)^2} $Es wird auch ausgedrückt als.

Diese Funktion hat die folgende Form und kehrt durch Verschieben oder Ändern der Größe der Mitte dieser Funktion zur Zieldatenzeichenfolge zurück.

ガウスカーネル

Lineare Regression mit dem Gaußschen Kernel

Nun die gewünschte Funktion

f({\bf x})=\sum_{i=1}^{N} \alpha k({\bf x}^{(i)}, {\bf x}')

Und. Der Beispielwert sei $ \ hat {y} $

\hat{y} =
\left(\begin{matrix}
k({\bf x}^{(1)}, {\bf x}) & k({\bf x}^{(2)}, {\bf x}) & \cdots & k({\bf x}^{(N)}, {\bf x})
\end{matrix}\right)
\left(\begin{matrix}
\alpha_0 \\
\alpha_1 \\
\vdots \\
\alpha_N
\end{matrix}\right)

Nächster,

{\bf y} = 
\left(\begin{matrix}
y^{(1)} \\
y^{(2)} \\
\vdots \\
y^{(N)}
\end{matrix}\right)
,\;
K=\left(\begin{matrix}
k({\bf x}^{(1)}, {\bf x}^{(1)}) & k({\bf x}^{(2)}, {\bf x}^{(1)}) & \cdots & k({\bf x}^{(N)}, {\bf x}^{(1)}) \\
k({\bf x}^{(1)}, {\bf x}^{(2)}) & k({\bf x}^{(2)}, {\bf x}^{(2)}) & & \vdots \\
\vdots & & \ddots & \vdots \\
k({\bf x}^{(1)}, {\bf x}^{(N)}) & \cdots & \cdots & k({\bf x}^{(N)}, {\bf x}^{(N)})
\end{matrix}\right) 
,\;
{\bf \alpha}
=
\left(\begin{matrix}
\alpha^{(1)} \\
\alpha^{(2)} \\
\vdots \\
\alpha^{(N)}
\end{matrix}\right)

Es wird so entwickelt (es tut mir leid für diese seltsame Kopie). Hier heißt $ K $ ** Gramm Matrix **. Der quadratische Fehler $ L $ zwischen $ f ({\ bf x}) $ und $ \ hat {y} $ ist

L=({\bf y}- K {\bf \alpha})^{\mathrm{T}}({\bf y}- K {\bf \alpha})

Und lösen Sie dies für $$ alpha , $ {\ bf \ alpha} = (K ^ {\ mathrm {T}} K) ^ {-1} K ^ {\ mathrm {T}} {\ bf y} = K ^ {-1} {\ bf y} $$. Mit anderen Worten, wenn die inverse Matrix der Grammmatrix berechnet werden kann, ist es möglich, $ \ alpha $ zu erhalten. Wenn die Anzahl der beobachteten Proben zu groß ist, ist es schwierig, diese inverse Matrix zu erhalten, daher muss eine andere Methode ausgewählt werden.

Implementierung in Python

Ich habe die KernelRegression-Klasse mit der obigen Formel implementiert.

class KernelRegression: #Keine Regularisierung
  def __init__(self, beta=1):
    self.alpha = np.array([])
    self.beta = beta

  def _kernel(self, xi, xj):
    return np.exp(- self.beta * np.sum((xi - xj)**2))

  def gram_matrix(self, X):
    N = X.shape[0]
    K = np.zeros((N, N))
    for i in range(N):
      for j in range(N):
        K[i][j] = self._kernel(X[i], X[j])
        K[j][i] = K[i][j]

    return K

  def fit(self, X, Y):
    K = self.gram_matrix(X)
    self.alpha = np.linalg.inv(K)@Y

  def predict(self, X, x):
    Y = 0
    for i in range(len(X)):
      Y += self.alpha[i] * self._kernel(X[i], x)
    return Y

Machen wir eine Annäherung an die erste Stichprobe.

model = KernelRegression(beta=20)
model.fit(x, y2)

xp = np.linspace(0, 2*np.pi, 100)
yp = np.zeros(len(xp))

for i in range(len(xp)):
  yp[i] = model.predict(x, xp[i])


fig, ax = plt.subplots()

plt.ylim(-3,6)
ax.plot(xp, yp, color='purple', label="estimate curve")
ax.scatter(x, y2, color='blue', label="sample(with noise)")
ax.plot(t, y1, color='green', label="-x*sin(x)")
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=11)

plt.show()
gaussian_regression_2.png

Es scheint, dass es über die gegebene Probe geht, aber es ist chaotisch. Es ist völlig anders als die grüne Kurve.

Über Überanpassung

Wie oben gezeigt, wird die Tatsache, dass das Lernergebnis den Lehrerdaten entspricht, aber weit von der Realität entfernt ist, als ** Überanpassung ** bezeichnet. Ist es einem Mathe-Test ähnlich, den Sie lösen können, wenn Sie das gleiche Problem wie ein Lehrbuch haben, aber Sie können es nicht lösen, sobald Sie es ein wenig arrangiert haben?

Übertrainierte Modelle werden auch als schlecht ** Generalisierungsleistung ** bezeichnet. Die Vorhersagegenauigkeit ist gering. Um dies zu verhindern, brauchen wir das Konzept der ** Regularisierung **.

Regulierung

Im obigen Beispiel ist der Parameter $ \ bf {\ alpha} $ extrem groß geworden, was zu einer heftigen Kurve führt, durch die die Punkte einer bestimmten Probe gezwungen werden. Danach scheint dies häufig der Fall zu sein, wenn die Anzahl der Daten extrem gering ist oder viele Variablen vorhanden sind.

Um dies zu verhindern, kann bei der Berechnung von $ \ alpha $ der Bereich von $ \ alpha $ begrenzt werden, indem dem quadratischen Fehler der Kernel-Regression ein ** Regularisierungsterm ** hinzugefügt wird. Die L1-Regularisierung (Lasso) und die L2-Regularisierung (Ridge) sind im maschinellen Lernen bekannt. Das Mischen der beiden wird als Elastic Net-Regularisierung bezeichnet.

L2-Regularisierung

Beginnen Sie mit L2 anstelle von L1. Vorhin\alphaDer quadratische Fehler zwischen der Zielfunktion und der Probe, wennLIch sagte,\lambda||{\bf \alpha}||_2^2Hinzugefügt

L=({\bf y}- K {\bf \alpha})^{\mathrm{T}}({\bf y}- K {\bf \alpha})+\lambda||{\bf \alpha}||_2^2

Optimieren. Je größer $ \ lambda $ ist, desto eingeschränkter ist $ \ alpha $, was zu einer fügsameren (?) Kurve führt. Wenn dies teilweise durch $ \ alpha $ differenziert und auf 0 gesetzt und für $ \ alpha $ gelöst wird,

{\bf \alpha} = (K+\lambda I_N)^{-1}{\bf y}

Es wird sein. Dies ist leicht zu ändern, da Sie lediglich die Einheitsmatrix zur Grammmatrix hinzufügen und die inverse Matrix berechnen müssen.

Implementierung in Python

Ich habe den Teil der KernelRegression-Klasse geändert, der nach $ \ alpha $ fragt. Der Rest ist fast der gleiche.

class KernelRegression: #L2-Regularisierung
  def __init__(self, beta=1, lam=0.5):
    self.alpha = np.array([])
    self.beta = beta
    self.lam = lam

  def _kernel(self, xi, xj):
    return np.exp(- self.beta * np.sum((xi - xj)**2))

  def gram_matrix(self, X):
    N = X.shape[0]
    K = np.zeros((N, N))
    for i in range(N):
      for j in range(N):
        K[i][j] = self._kernel(X[i], X[j])
        K[j][i] = K[i][j]

    return K

  def fit(self, X, Y):
    K = self.gram_matrix(X)
    self.alpha = np.linalg.inv(K + self.lam * np.eye(X.shape[0]))@Y

  def predict(self, X, x):
    Y = 0
    for i in range(len(X)):
      Y += self.alpha[i] * self._kernel(X[i], x)
    return Y

Versuchen Sie, mit derselben Stichprobe zu approximieren, als ob sie nicht reguliert wäre. Die Werte von $ \ beta $ und $ \ lambda $ wurden entsprechend festgelegt.

model = KernelRegression(beta=0.3, lam=0.1)
model.fit(x, y2)

xp = np.linspace(0, 2*np.pi, 100)
yp = np.zeros(len(xp))

for i in range(len(xp)):
  yp[i] = model.predict(x, xp[i])


fig, ax = plt.subplots()

plt.ylim(-3,6)
ax.plot(xp, yp, color='purple', label="estimate curve")
ax.scatter(x, y2, color='blue', label="sample(with noise)")
ax.plot(t, y1, color='green', label="-x*sin(x)")
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=11)

plt.show()
gaussian_regression_3.png

Diesmal war es eine perfekte Übereinstimmung. Tatsächlich ändert sich die Form außerhalb des angezeigten Bereichs, aber Sie können sehen, dass eine ziemlich enge Approximationskurve in einem bestimmten Bereich gezeichnet werden kann.

$ \ Beta $ und $ \ lambda $ heißen ** Hyperparameter **, und Sie müssen sie tatsächlich optimieren, indem Sie sie nach und nach ändern, um den Wert der Verlustfunktion zu minimieren.

L1-Regularisierung

In der L2-Regularisierung als Regularisierungsbegriff$\lambda ||{\bf \alpha}||^2_{2} Wurde hinzugefügt, aber in L2 Regularisierung als Regularisierungsbegriff\lambda||{\bf \alpha}||_1$Hinzufügen.

Das Finden einer Lösung ist etwas kompliziert, da der Regularisierungsterm bei der L1-Regularisierung nicht unterschieden werden kann. Es scheint, dass Scikit-Learn durch eine Methode namens Coordinate Descent implementiert wird, aber ich verstehe es noch nicht, daher möchte ich Scikit-Learn in diesem Artikel gehorsam verwenden.

Die L1-Regularisierung kann einen signifikanten Teil des Parameters $ \ alpha $ auf 0 reduzieren (eine spärliche Lösung erhalten) und hilft, unerwünschte Parameter zu entfernen.

Implementierung in Python

Ich werde es gehorsam mit scicit-learn umsetzen.

from sklearn.metrics.pairwise import rbf_kernel
from sklearn.linear_model import Lasso

kx = rbf_kernel(x.reshape(-1,1), x.reshape(-1,1))
KX = rbf_kernel(xp.reshape(-1,1), x.reshape(-1,1))

clf = Lasso(alpha=0.01, max_iter=10000)
clf.fit(kx, y2)

yp = clf.predict(KX)

fig, ax = plt.subplots()
plt.ylim(-3,6)
ax.plot(xp, yp, color='purple', label="estimate curve")
ax.scatter(x, y2, color='blue', label="sample(with noise)")
ax.plot(t, y1, color='green', label="-x*sin(x)")
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=11)

plt.show()

print("coef: ", clf.coef_)

coef:  [-0.          0.          0.         -0.         -0.79703436 -0.
 -0.         -0.          0.         -0.         -0.          3.35731837
  0.         -0.         -0.77644607  0.         -0.          0.
 -0.         -0.19590705  0.         -0.          0.         -0.
  0.          0.         -0.         -0.         -0.          0.
 -0.          0.         -0.         -0.          0.          0.58052561
  0.3688375   0.         -0.          1.75380012]
gaussian_regression_4.png

Dies ist auch der ursprünglichen Funktion sehr ähnlich. Sie können auch sehen, dass ein wesentlicher Teil des Parameters (coef) 0 ist.

Elasticnet Sowohl die L1-Regularisierung als auch die L2-Regularisierung fügen der Verlustfunktion einen Regularisierungsterm hinzu, aber jeder kann unabhängig betrachtet werden, und Sie können entscheiden, welche und wie viel übernommen werden soll, was als ** ElasticNet ** bezeichnet wird. Ich werde. Tatsächlich definierte die Scikit-Learn-Implementierung die ElasticNet-Parameter als Lasso und Ridge.

Zusammenfassung

Bei der linearen Regression kann jede Funktion als Basisfunktion ausgewählt werden. Da der Gaußsche Kernel (nicht beschränkt auf) einen hohen Freiheitsgrad aufweist und dazu neigt, überlernt zu werden, ist es möglich, ein Regressionsmodell mit höherer Generalisierungsleistung zu erstellen, indem Einschränkungen durch L1-Regularisierung oder L2-Regularisierung hinzugefügt werden.

Ich habe die Regressionsserie mehrmals zusammengefasst, aber um Ihnen zu helfen, den Inhalt der Regression im [Scikit-Learn-Spickzettel] zu verstehen (https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html) Ist es nicht?

Tsukkomi ist willkommen, weil ich es angemessen zusammengefasst habe.

Recommended Posts

Algorithmus für maschinelles Lernen (Zusammenfassung und Regularisierung der linearen Regression)
Algorithmus für maschinelles Lernen (Verallgemeinerung der linearen Regression)
Maschinelles Lernen: Überwacht - Lineare Regression
Algorithmus für maschinelles Lernen (logistische Regression)
Anfänger des maschinellen Lernens versuchen eine lineare Regression
Algorithmus für maschinelles Lernen (multiple Regressionsanalyse)
Algorithmus für maschinelles Lernen (Einzelregressionsanalyse)
<Kurs> Maschinelles Lernen Kapitel 1: Lineares Regressionsmodell
Zusammenfassung der Klassifizierung und Implementierung von Algorithmen für maschinelles Lernen
Zusammenfassung des Lernprogramms für maschinelles Lernen
Maschinelles Lernen ⑤ AdaBoost-Zusammenfassung
Logistische Regression beim maschinellen Lernen
EV3 x Python Maschinelles Lernen Teil 2 Lineare Regression
Python Scikit-learn Lineare Regressionsanalyse Nichtlineare einfache Regressionsanalyse Maschinelles Lernen
Verstehe maschinelles Lernen ~ Ridge Regression ~.
Zusammenfassung der Artikel zum maschinellen Lernen (selbst verfasst)
Coursera Machine Learning Challenge in Python: ex1 (lineare Regression)
Algorithmus für maschinelles Lernen (einfaches Perzeptron)
Überwachtes maschinelles Lernen (Klassifikation / Regression)
Algorithmus für maschinelles Lernen (Support Vector Machine)
Maschinelles Lernen ④ K-nächster Nachbar Zusammenfassung
Stapelvorlage für maschinelles Lernen (Rückgabe)
Python Machine Learning Programming Kapitel 2 Klassifizierungsprobleme - Zusammenfassung des Trainingsalgorithmus für maschinelles Lernen
<Kurs> Maschinelles Lernen Kapitel 6: Algorithmus 2 (k-Mittel)
Algorithmus für maschinelles Lernen (Unterstützung von Vektor-Maschinenanwendungen)
Maschinelles Lernen ① SVM-Zusammenfassung (Support Vector Machine)
Maschinelles Lernen ③ Zusammenfassung des Entscheidungsbaums
Klassifikation und Regression beim maschinellen Lernen
Algorithmus für maschinelles Lernen (Gradientenabstiegsmethode)
Maschinelles Lernen: Überwacht - Lineare Diskriminanzanalyse
[Maschinelles Lernen] Verstehen der linearen einfachen Regression sowohl aus Scikit-Lernen als auch aus Mathematik
Maschinelles Lernen
Lineare Regression
[Maschinelles Lernen] Verstehen der linearen multiplen Regression sowohl aus Scikit-Lernen als auch aus Mathematik
<Subjekt> Maschinelles Lernen Kapitel 3: Logistisches Regressionsmodell
scikit-learn Verwendung der Zusammenfassung (maschinelles Lernen)
Maschinelles Lernen mit Python (2) Einfache Regressionsanalyse
"Python Machine Learning Programming" - Zusammenfassung (Jupyter)
Algorithmus für maschinelles Lernen (Implementierung einer Klassifizierung mit mehreren Klassen)
<Kurs> Maschinelles Lernen Kapitel 2: Nichtlineares Regressionsmodell
Aktienkursprognose mit maschinellem Lernen (Return Edition)
[Maschinelles Lernen] Regressionsanalyse mit Scicit Learn
(Maschinelles Lernen) Ich habe versucht, die Bayes'sche lineare Regression bei der Implementierung sorgfältig zu verstehen
Gaußscher EM-Algorithmus mit gemischtem Modell [statistisches maschinelles Lernen]
Wörterbuch-Lernalgorithmus
Zusammenfassung der beim maschinellen Lernen verwendeten Bewertungsfunktionen
[Memo] Maschinelles Lernen
Klassifikation des maschinellen Lernens
Beispiel für maschinelles Lernen
Zusammenfassung der runden Lesesitzungen der professionellen Serie für maschinelles Lernen
Coursera-Herausforderungen beim maschinellen Lernen in Python: ex2 (Logistic Return)
Site-Zusammenfassung zum Erlernen des maschinellen Lernens mit englischen Videos
Zusammenfassung des grundlegenden Ablaufs des maschinellen Lernens mit Python
Sprechen Sie mit Cython über die Verbesserung des Engpasses bei Algorithmen für maschinelles Lernen
Maschinelles Lernen Über Overlearning
Maschinelles Lernen: Betreut --AdaBoost
Maschinelles Lernen unterstützt Vektormaschine
Maschinelles Lernen studieren ~ matplotlib ~
Memo zum Kurs für maschinelles Lernen