Erwartungsregression: eine Alternative zur Quantilregression?
Als Data-Science-Praktiker ist Ihnen vielleicht der Begriff „ Quantilregression “ bekannt. Wenn ja, sollten Sie wahrscheinlich wissen, dass die Quantilverlustfunktion als Verallgemeinerung des mittleren absoluten Fehlers betrachtet werden kann . Während der MAE zur Schätzung der bedingten zentralen Tendenz verwendet wird , dient der Quantilverlust dazu, einige andere Eigenschaften der Zielvariablenverteilung zu beschreiben.
In diesem Artikel möchte ich ein etwas weniger bekanntes Ziel namens Erwartungsverlust vorstellen , das eine verallgemeinerte Form des mittleren quadratischen Fehlers ist .
MAE gegen MSE
Lassen Sie uns zunächst die Beziehung zwischen den hier verwendeten Begriffen zusammenfassen.
Es ist auch gut zu erwähnen, dass:
- Die Minimierung des MSE führt zur Vorhersage des Mittelwerts, während wir für den MAE den Median erhalten
- MSE und RMSE (Root Mean Squared Error) sollten zum gleichen Optimum führen .
- Die SSE (Summe der quadratischen Fehler, verwendet in OLS) und MSE haben ihre Minima an den gleichen Punkten. Dasselbe können wir über die Beziehung zwischen dem oben erwähnten LAD und MAE sagen. Siehe Wikipedia-Artikel über die MAE und dieses Buchkapitel über lineare Regression .
- Die „wahre“ L2-Norm geht davon aus, dass wir die Quadratwurzel verwenden – tatsächlich wird sie oft weggelassen, was ziemlich verwirrend sein kann.
- Der Quantilverlust wird auch als Flipperverlust bezeichnet .
- L1-basierte Verluste, dh Quantilverlust und MAE, sind am Ursprung nicht differenzierbar.
Nehmen wir an, wir lösen ein Regressionsproblem, das den Preis einer Immobilie (eines Hauses oder einer Wohnung) basierend auf ihrer Größe vorhersagen soll. Wir erstellen eine wiederverwendbare Funktion, um einen Spielzeugdatensatz zu generieren. Sie können diese Funktion nach Belieben modifizieren und selbst ausprobieren.
import pandas as pd
import numpy as np
import scipy
from typing import Tuple, List
import seaborn as sns
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = [15, 10]
def generate_offers(area_range: Tuple[int, int] = (20, 300),
loc: float = 6000,
scale: float = 3000,
samples: int = 2000):
# Generate range of possible areas
area_range = np.arange(area_range[0], area_range[1])
# Generate probabilities of occurrence for different areas
prob = scipy.stats.skewnorm.pdf(area_range,
a = -.5,
loc = np.mean(area_range),
scale = np.std(area_range))
prob = prob / prob.sum()
samples = np.random.choice(area_range, samples, p=prob)
# Generate prices per unit
# We could also use lognormal distribution, but this way is more intuitive
# from my point of view
prices = scipy.stats.skewnorm.rvs(-.5, loc=loc, scale=scale, size=len(samples))
size = (prices < 3000).sum()
prices[prices < 3000] = 3000 + np.random.normal(0, 500, size)
prices[prices < 1000] = 1000
data = pd.DataFrame({
'area': samples,
'price': samples * prices
})
return data
data = generate_offers()
sns.scatterplot(data=data, x='area', y='price')
plt.show()
The generated dataset
Lassen Sie uns versuchen, eine Antwort mit drei Arten von linearen Modellen vorzubereiten:
- LinearRegression — Minimierung der Summe quadrierter Fehler
- LADRegression — Minimierung der Summe der absoluten Abweichung
- QuatileRegression — Verallgemeinerung von LADRegression
from sklearn.linear_model import LinearRegression
from sklego.linear_model import LADRegression, QuantileRegression
models = {
'ols_regression': LinearRegression(),
'lad_regression': LADRegression(),
'quantile_regression_20': QuantileRegression(quantile=.2),
'quantile_regression_90': QuantileRegression(quantile=.9)
}
def linear_models(data: pd.DataFrame,
models: dict,
features: List[str],
target: List[str],
save: str = None):
# Models
for model_name, model in models.items():
models[model_name].fit(data[features], data[target])
# Forecasts
space = np.linspace(data[features].min(), data[features].max()).reshape(-1, 1)
pred = {'area': space.ravel()}
for model_name, model in models.items():
pred[model_name] = model.predict(space).ravel()
pred = pd.DataFrame(pred)
pred = pred.melt(features[0])
sns.scatterplot(data=data, x=features[0], y=target[0], alpha=.7)
sns.lineplot(data=pred, x=features[0], y='value', hue='variable', linewidth = 2)
plt.legend(loc=2, prop={'size': 30})
if save:
plt.savefig(save)
else:
plt.show()
OLS vs LAD vs quantile regression
MAE und Quantilverlust
Der mittlere absolute Fehler ist definiert als:
Um ihn in den Quantilverlust umzuwandeln, müssen wir eine spezifische, asymmetrische Fehlergewichtung hinzufügen. Kurz gesagt, der Quantilverlust kann mit der folgenden Gleichung dargestellt werden, wobei τ für eine reelle Zahl zwischen 0 und 1 steht, die einem bestimmten Quantil entspricht.
Seien Sie hier vorsichtig: Für die Quantil- und Erwartungswertschätzungen verwende ich das Y-Hut- Symbol, das ich nur als vorhergesagten Wert meine, während es üblicherweise mit der Schätzung des Zielvariablendurchschnitts identifiziert wird.
Warum ist der absolute Wert verschwunden? Tatsächlich war dies nicht der Fall, sondern wurde durch Multiplizieren mit einem negativen Wert ersetzt. Um den Zusammenhang zwischen dem MAE und dem Quantilverlust explizit aufzuzeigen, können wir ihn wie folgt umformulieren:
Lassen Sie es uns jetzt aufschlüsseln und ins Detail gehen. Angenommen, wir haben eine Untergruppe aus unserem Immobiliendatensatz, wenn Fläche = 100 ist. Wenn wir versuchen, den Wert des konditionalen 90-Quantils zu schätzen, bedeutet dies ungefähr Folgendes:
- Die Preise von 90 % der Immobilien mit Fläche = 100 liegen unter dem wahren 90-Quantil. Die Differenzen zwischen diesen Zielwerten und den 90-Quantil-Schätzungen werden mit einer Gewichtung von 0,1 bestraft.
- Die Preise von 10 % der Immobilien mit Fläche = 100 sind größer oder gleich dem wahren Quantil 90. Die Differenzen zwischen diesen Zielwerten und den 90-Quantil-Schätzungen werden mit einem Gewicht von 0,9 bestraft.
MSE und Erwartungsverlust
Um MSE zu berechnen, müssen wir den Absolutwert des Fehlers durch sein Quadrat ersetzen.
Wenn wir die zweite Gleichung aus dem vorherigen Abschnitt verwenden und den Absolutwert durch das Quadrat ersetzen, erhalten wir die Gleichung für die Erwartungsverlustfunktion. Wir verwenden τ, das gleiche Symbol, das wir im vorherigen Abschnitt verwendet haben, um das Erwartungsniveau auszuwählen, das wir schätzen werden.
Erwartete Regression von Grund auf neu
Schließlich werden wir versuchen, ein lineares Modell zu konstruieren, das die Erwartungsverlustfunktion optimiert. In dem nachstehenden Ausdruck wird x verwendet, um den Merkmalsvektor für die i-te Beobachtung zu bezeichnen, erweitert um eine zusätzliche Spalte mit Eins. Somit reicht es aus, Skalarprodukt mit dem β- Vektor zu bilden: Als letzter zusätzlicher Parameter ist der Schnittpunkt bereits enthalten.
Als nächstes berechnen wir die erste partielle Ableitung der Fehlerfunktion in Bezug auf β . Die stückweise Fehlerfunktion kann auch ausgedrückt werden als:
Mit dieser Version erhalten wir nach einigen einfachen Transformationen die gewünschte Ableitung der Fehlerfunktion .
In der „endgültigen“ Ableitung verwenden wir Matrix und Vektoren anstelle von Vektoren und Skalaren für die Merkmale bzw. das Ziel. Wir fügen auch eine Division durch die Anzahl der Beobachtungen hinzu, um den Mittelwert zu berücksichtigen. Wir wollen trotzdem an der zu Beginn gewählten Konvention festhalten, also werden wir das Modell als sklearn -ähnliche Klasse schreiben. Die Ableitung, die wir im vorherigen Schritt berechnet haben, ist ein notwendiges Argument für die Minimierungsfunktion von scipy .
from scipy.optimize import minimize
class ExpectileRegression:
"""Expectile regression with linear model"""
def __init__(self, expectile: float =.5, **kwargs):
assert 0 < expectile < 1, \
f"e parameter must be stricly 0 < e < 1, but it equals: {expectile}"
self.expectile = expectile
super().__init__(**kwargs)
def fit(self, X, y):
if type(X) is pd.DataFrame:
X = X.values
if type(y) in [pd.DataFrame, pd.Series]:
y = y.values
# Adding column of ones
n = X.shape[0]
X = np.hstack([X, np.ones(shape=(n, 1))])
self.beta = np.random.rand(X.shape[1])
def expectile_loss(beta, *args):
y_hat = X @ beta
errors = y.reshape(-1, 1) - y_hat.reshape(-1, 1)
return (
np.where(
errors < 0, 1 - self.expectile , self.expectile
) * errors ** 2
).mean()
def expectile_grad(beta, *args):
y_hat = X @ beta
errors = y.reshape(-1, 1) - y_hat.reshape(-1, 1)
return (
-2 * X.T @ (
np.where(
errors < 0, 1 - self.expectile , self.expectile
) * errors
)
) / X.shape[0]
# Optimization
res = minimize(
fun = expectile_loss,
x0 = self.beta,
args = None,
method = 'SLSQP' ,
jac = expectile_grad
)
self.beta = res.x
return self
def predict(self, X):
n = X.shape[0]
X_ = np.hstack([X, np.ones(shape=(n, 1))])
return X_ @ self.beta
models = {
'ols_regression': LinearRegression(),
'expectile_regression_90' : ExpectileRegression(expectile=.9),
'expectile_regression_80' : ExpectileRegression(expectile=.8),
'expectile_regression_50' : ExpectileRegression(expectile=.5),
'expectile_regression_20' : ExpectileRegression(expectile=.2),
'expectile_regression_10' : ExpectileRegression(expectile=.1)
}
linear_models(
data = data,
models = models,
features = ['area'],
target = ['price']
)
models = {
'expectile_regression_90' : ExpectileRegression(expectile=.9),
'expectile_regression_10' : ExpectileRegression(expectile=.1),
'quantile_regression_90': QuantileRegression(quantile=.9),
'quantile_regression_10': QuantileRegression(quantile=.1),
}
linear_models(
data = data,
models = models,
features = ['area'],
target = ['price']
)
- Das Erwartungswert ist eine Verallgemeinerung des Mittelwerts und der Erwartungsverlust ist eine Verallgemeinerung des mittleren quadratischen Fehlers.
- Expectile hat keine einfache, intuitive Interpretation im Kontext der Wahrscheinlichkeits-/kumulativen Dichtefunktion. Weitere Einzelheiten finden Sie im Artikel Interpreting Expectiles .
- Quantil- und Erwartungsregressionen
- Quantil-, M-Quantil- und Erwartungsregression
- Erwartungs- und Quantilregression – David und Goliath?
- Dolmetschen von Erwartungen
- Das MLE von Aigner, Amemiya und Poirier ist nicht das Expectile MLE
- Distributional Reinforcement Learning in the Brain: Trends in Neurosciences (Beispiel für die Verwendung von Erwartungswerten)
- scipy.stats.expectile
- XGBoostLSS und andere Pakete von Alexander März (erwartete Regression mit GBMs)

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































