Ist es besser als die Rastersuche?

Bild vom Autor aus Canva

Wenn ich merke, dass mein Modell überpasstich denke oft: „Es ist Zeit für eine Regulierung“. Aber wie entscheide ich, welche Regularisierungsmethode ich verwende (L1, L2) und welche Parameter ich wähle? Normalerweise führe ich eine Hyperparameteroptimierung mithilfe einer Rastersuche durch, um die Einstellungen auszuwählen. Was passiert jedoch, wenn die unabhängigen Variablen unterschiedliche Skalen oder unterschiedliche Einflussgrade haben? Kann ich ein Hyperparametergitter mit unterschiedlichen Regularisierungskoeffizienten für jede Variable entwerfen? Ist diese Artwork der Optimierung in hochdimensionalen Räumen möglich? Und gibt es different Möglichkeiten, die Regularisierung zu gestalten? Lassen Sie uns dies anhand eines hypothetischen Beispiels untersuchen.

Mein fiktives Beispiel ist ein Anwendungsfall einer binären Klassifizierung mit drei erklärenden Variablen. Jede dieser Variablen ist kategorial und verfügt über 7 verschiedene Kategorien. Mein reproduzierbarer Anwendungsfall ist dieser Notizbuch. Die Funktion, die den Datensatz generiert, ist die folgende:

import numpy as np
import pandas as pd

def get_classification_dataset():
n_samples = 200
cats = ("a", "b", "c", "d", "e", "f")
X = pd.DataFrame(
knowledge={
"col1": np.random.selection(cats, dimension=n_samples),
"col2": np.random.selection(cats, dimension=n_samples),
"col3": np.random.selection(cats, dimension=n_samples),
}
)
X_preprocessed = pd.get_dummies(X)

theta = np.random.multivariate_normal(
np.zeros(len(cats) * X.form(1)),
np.diag(np.array((1e-1) * len(cats) + (1) * len(cats) + (1e1) * len(cats))),
)

y = pd.Sequence(
knowledge=np.random.binomial(1, expit(np.dot(X_preprocessed.to_numpy(), theta))),
index=X_preprocessed.index,
)
return X_preprocessed, y

Zur Info habe ich bewusst drei verschiedene Werte für die Theta-Kovarianzmatrix ausgewählt, um den Nutzen der Laplace-Approximations-Bayes’schen Optimierungsmethode zu verdeutlichen. Wenn die Werte irgendwie ähnlich wären, wäre das Interesse gering.

Zusammen mit ein einfaches Basismodell, das den beobachteten Mittelwert vorhersagt Für den Trainingsdatensatz (der zu Vergleichszwecken verwendet wird) habe ich mich für den Entwurf eines etwas komplexeren Modells entschieden. Ich habe beschlossen, die drei unabhängigen Variablen einmalig zu kodieren und anzuwenden ein logistisches Regressionsmodell zusätzlich zu dieser grundlegenden Vorverarbeitung. Für die Regularisierung habe ich ein L2-Design gewählt und wollte mithilfe von zwei Techniken den optimalen Regularisierungskoeffizienten finden: Rastersuche Und Laplace-Approximierte Bayes’sche Optimierungwie Sie vielleicht schon erwartet haben. Schließlich habe ich das Modell anhand eines Testdatensatzes anhand von zwei Metriken (willkürlich ausgewählt) bewertet: Log-Verlust und AUC ROC.

Bevor wir die Ergebnisse präsentieren, werfen wir zunächst einen genaueren Blick auf das Bayes’sche Modell und wie wir es optimieren.

Im Bayes’schen Rahmen sind die Parameter keine festen Konstanten mehr, sondern Zufallsvariablen. Anstatt die Wahrscheinlichkeit zur Schätzung dieser unbekannten Parameter zu maximieren, optimieren wir nun die Posteriorverteilung der Zufallsparameter anhand der beobachteten Daten. Dies erfordert, dass wir das Design und die Parameter des Priors oft etwas willkürlich wählen. Es ist jedoch auch möglich, die Parameter des Priors selbst als Zufallsvariablen zu behandeln – wie in Beginnwo sich die Schichten der Unsicherheit immer wieder übereinander stapeln …

In dieser Studie habe ich das folgende Modell gewählt:

Ich habe logischerweise ein Bernouilli-Modell für Y_i | gewählt θ, eine zentrierte Normale, die einer L2-Regularisierung für θ | entspricht Σ und schließlich habe ich für Σ_i^{-1} ein Gamma-Modell gewählt. Ich habe mich dafür entschieden, die Präzisionsmatrix anstelle der Kovarianzmatrix zu modellieren, wie es in der Literatur traditionell üblich ist, wie im Scikit-Be taught-Benutzerhandbuch für die Bayes’sche lineare Regression (2).

Zusätzlich zu diesem geschriebenen Modell habe ich angenommen, dass Y_i und Y_j bedingt (von θ) unabhängig sind, ebenso wie Y_i und Σ.

Wahrscheinlichkeit

Gemäß dem Modell lässt sich die Wahrscheinlichkeit folglich wie folgt schreiben:

Zur Optimierung müssen wir quick alle Terme auswerten, mit Ausnahme von P(Y=y). Die Terme in den Zählern können mit dem gewählten Modell ausgewertet werden. Der verbleibende Time period im Nenner kann jedoch nicht. Hier ist die Laplace-Näherung kommt ins Spiel.

Laplace-Näherung

Um den ersten Time period des Nenners auszuwerten, können wir die Laplace-Näherung nutzen. Wir approximieren die Verteilung von θ | Y, Σ durch:

wobei θ* die Mode der Mode ist, ist die Dichteverteilung von θ | Y, Σ.

Auch wenn wir die Dichtefunktion nicht kennen, können wir den Hesse-Teil dank der folgenden Zerlegung berechnen:

Wir müssen nur die ersten beiden Terme des Zählers kennen, um den Hesse-Wert auszuwerten, was wir tun.

Für diejenigen, die an weiteren Erklärungen interessiert sind, empfehle ich Teil 4.4, „The Laplace Approximation“, aus „Sample Recognition and Machine Studying“ von Christopher M. Bishop (1). Es hat mir sehr geholfen, die Annäherung zu verstehen.

Laplace-Annäherungswahrscheinlichkeit

Schließlich ist die Laplace-geschätzte Optimierungswahrscheinlichkeit:

Sobald wir die Dichtefunktion von θ | approximieren Y, Σ, wir könnten endlich die Wahrscheinlichkeit bei jedem beliebigen θ auswerten, wenn die Näherung überall genau wäre. Der Einfachheit halber und weil die Näherung nur in der Nähe des Modus genau ist, bewerten wir die angenäherte Wahrscheinlichkeit bei θ*.

Nachfolgend finden Sie eine Funktion, die diesen Verlust für ein gegebenes (skalares) σ²=1/p auswertet (zusätzlich zu den gegebenen beobachteten Werten X und y und den Entwurfswerten α und β).

import numpy as np
from scipy.stats import gamma

from module.bayesian_model import BayesianLogisticRegression

def loss(p, X, y, alpha, beta):
# computation of the loss for given values:
# - 1/sigma² (named p for precision right here)
# - X: matrix of options
# - y: vector of observations
# - alpha: prior Gamma distribution alpha parameter over 1/sigma²
# - beta: prior Gamma distribution beta parameter over 1/sigma²

n_feat = X.form(1)
m_vec = np.array((0) * n_feat)
p_vec = np.array(p * n_feat)

# computation of theta*
res = reduce(
BayesianLogisticRegression()._loss,
np.array((0) * n_feat),
args=(X, y, m_vec, p_vec),
methodology="BFGS",
jac=BayesianLogisticRegression()._jac,
)
theta_star = res.x

# computation the Hessian for the Laplace approximation
H = BayesianLogisticRegression()._hess(theta_star, X, y, m_vec, p_vec)

# loss
loss = 0
## first two phrases: the log loss and the regularization time period
loss += baysian_model._loss(theta_star, X, y, m_vec, p_vec)
## third time period: prior distribution over sigma, written p right here
out -= gamma.logpdf(p, a = alpha, scale = 1 / beta)
## fourth time period: Laplace approximated final time period
out += 0.5 * np.linalg.slogdet(H)(1) - 0.5 * n_feat * np.log(2 * np.pi)

return out

In meinem Anwendungsfall habe ich mich für die Optimierung mittels entschieden Adam-Optimierer, welcher Code daraus übernommen wurde Repo.

def adam(
enjoyable,
x0,
jac,
args=(),
learning_rate=0.001,
beta1=0.9,
beta2=0.999,
eps=1e-8,
startiter=0,
maxiter=1000,
callback=None,
**kwargs
):
"""``scipy.optimize.reduce`` suitable implementation of ADAM -
(http://arxiv.org/pdf/1412.6980.pdf).
Tailored from ``autograd/misc/optimizers.py``.
"""
x = x0
m = np.zeros_like(x)
v = np.zeros_like(x)

for i in vary(startiter, startiter + maxiter):
g = jac(x, *args)

if callback and callback(x):
break

m = (1 - beta1) * g + beta1 * m # first second estimate.
v = (1 - beta2) * (g**2) + beta2 * v # second second estimate.
mhat = m / (1 - beta1**(i + 1)) # bias correction.
vhat = v / (1 - beta2**(i + 1))
x = x - learning_rate * mhat / (np.sqrt(vhat) + eps)

i += 1
return OptimizeResult(x=x, enjoyable=enjoyable(x, *args), jac=g, nit=i, nfev=i, success=True)

Für diese Optimierung benötigen wir die Ableitung des vorherigen Verlusts. Da wir keine analytische Kind haben können, habe ich mich entschieden, eine numerische Näherung der Ableitung zu verwenden.

Sobald das Modell anhand des Trainingsdatensatzes trainiert wurde, müssen Vorhersagen zum Bewertungsdatensatz getroffen werden, um dessen Leistung zu bewerten und verschiedene Modelle zu vergleichen. Es ist jedoch nicht möglich, die tatsächliche Verteilung eines neuen Punktes direkt zu berechnen, da die Berechnung schwierig ist.

Es ist möglich, die Ergebnisse anzunähern mit:

angesichts:

Ich habe einen nicht aussagekräftigen Prior der Präzisions-Zufallsvariablen vorgezogen. Das naive Modell schneidet mit einem logarithmischen Verlust von 0,60 und einem AUC-ROC von 0,50 schlecht ab. Das zweite Modell schneidet mit einem Log-Verlust von 0,44 und einem AUC-ROC von 0,83 besser ab, beides bei Hyperoptimierung mit Rastersuche und Bayes’scher Optimierung. Dies weist darauf hin, dass das logistische Regressionsmodell, das die abhängigen Variablen berücksichtigt, dem naiven Modell überlegen ist. Allerdings bietet die Verwendung der Bayes’schen Optimierung gegenüber der Rastersuche keinen Vorteil, daher werde ich vorerst mit der Rastersuche fortfahren. Danke fürs Lesen.

… Aber warte, denke ich. Warum werden meine Parameter mit demselben Koeffizienten reguliert? Sollte mein Prior nicht von den zugrunde liegenden abhängigen Variablen abhängen? Möglicherweise könnten die Parameter für die erste abhängige Variable höhere Werte annehmen, während die für die zweite abhängige Variable mit ihrem geringeren Einfluss näher bei Null liegen sollten. Lassen Sie uns diese neuen Dimensionen erkunden.

Bisher haben wir zwei Techniken betrachtet, die Rastersuche und die Bayes’sche Optimierung. Wir können dieselben Techniken in höheren Dimensionen anwenden.

Die Berücksichtigung neuer Dimensionen könnte die Anzahl der Knoten meines Gitters dramatisch erhöhen. Aus diesem Grund ist die Bayes’sche Optimierung in höheren Dimensionen sinnvoll, um die besten Regularisierungskoeffizienten zu erhalten. Im betrachteten Anwendungsfall habe ich angenommen, dass es drei Regularisierungsparameter gibt, einen für jede unabhängige Variable. Nachdem ich eine einzelne Variable codiert hatte, ging ich davon aus, dass die generierten neuen Variablen alle denselben Regularisierungsparameter hatten. Daher beträgt die Gesamtzahl der Regularisierungsparameter 3, auch wenn mehr als 3 Spalten als Eingaben für die logistische Regression vorhanden sind.

Ich habe die vorherige Verlustfunktion mit dem folgenden Code aktualisiert:

import numpy as np
from scipy.stats import gamma

from module.bayesian_model import BayesianLogisticRegression

def loss(p, X, y, alpha, beta, X_columns, col_to_p_id):
# computation of the loss for given values:
# - 1/sigma² vector (named p for precision right here)
# - X: matrix of options
# - y: vector of observations
# - alpha: prior Gamma distribution alpha parameter over 1/sigma²
# - beta: prior Gamma distribution beta parameter over 1/sigma²
# - X_columns: listing of names of X columns
# - col_to_p_id: dictionnary mapping a column title to a p index
# as a result of many column names can share the identical p worth

n_feat = X.form(1)
m_vec = np.array((0) * n_feat)
p_list = ()
for col in X_columns:
p_list.append(p(col_to_p_id(col)))
p_vec = np.array(p_list)

# computation of theta*
res = reduce(
BayesianLogisticRegression()._loss,
np.array((0) * n_feat),
args=(X, y, m_vec, p_vec),
methodology="BFGS",
jac=BayesianLogisticRegression()._jac,
)
theta_star = res.x

# computation the Hessian for the Laplace approximation
H = BayesianLogisticRegression()._hess(theta_star, X, y, m_vec, p_vec)

# loss
loss = 0
## first two phrases: the log loss and the regularization time period
loss += baysian_model._loss(theta_star, X, y, m_vec, p_vec)
## third time period: prior distribution over 1/sigma² written p right here
## there's now a sum as p is now a vector
out -= np.sum(gamma.logpdf(p, a = alpha, scale = 1 / beta))
## fourth time period: Laplace approximated final time period
out += 0.5 * np.linalg.slogdet(H)(1) - 0.5 * n_feat * np.log(2 * np.pi)

return out

Bei diesem Ansatz lauten die am Testdatensatz ausgewerteten Metriken wie folgt: 0,39 und 0,88, was besser ist als das ursprüngliche Modell, das mithilfe einer Rastersuche und eines Bayes’schen Ansatzes mit nur einem einzigen Prior für alle unabhängigen Variablen optimiert wurde.

Mit den verschiedenen Methoden in meinem Anwendungsfall erzielte Metriken.

Damit kann der Anwendungsfall reproduziert werden Notizbuch.

Ich habe ein Beispiel erstellt, um die Nützlichkeit der Technik zu veranschaulichen. Allerdings konnte ich keinen geeigneten realen Datensatz finden, um sein Potenzial vollständig zu demonstrieren. Während ich mit einem tatsächlichen Datensatz arbeitete, konnte ich aus der Anwendung dieser Technik keine nennenswerten Vorteile ziehen. Wenn Sie auf eines stoßen, lassen Sie es mich bitte wissen – ich würde mich freuen, eine reale Anwendung dieser Regularisierungsmethode zu sehen.

Zusammenfassend lässt sich sagen, dass die Verwendung der Bayes’schen Optimierung (bei Bedarf mit Laplace-Näherung) zur Bestimmung der besten Regularisierungsparameter eine gute Different zu herkömmlichen Methoden zur Optimierung von Hyperparametern sein kann. Durch die Nutzung probabilistischer Modelle reduziert die Bayes’sche Optimierung nicht nur den Rechenaufwand, sondern erhöht auch die Wahrscheinlichkeit, optimale Regularisierungswerte zu finden, insbesondere in hohen Dimensionen.

  1. Christopher M. Bishop. (2006). Mustererkennung und maschinelles Lernen. Springer.
  2. Bayesian Ridge Regression Scikit-Be taught-Benutzerhandbuch: https://scikit-learn.org/1.5/modules/linear_model.html#bayesian-ridge-regression

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert