Daten auf eine Normalverteilung abbilden#

Dieses Beispiel demonstriert die Verwendung von Box-Cox- und Yeo-Johnson-Transformationen durch PowerTransformer, um Daten aus verschiedenen Verteilungen auf eine Normalverteilung abzubilden.

Die Potenztransformation ist nützlich als Transformation in Modellierungsproblemen, bei denen Homoskedastizität und Normalität erwünscht sind. Im Folgenden finden Sie Beispiele für Box-Cox und Yeo-Johnson, die auf sechs verschiedene Wahrscheinlichkeitsverteilungen angewendet werden: Lognormal, Chi-Quadrat, Weibull, Gauß, Gleichverteilung und Bimodal.

Beachten Sie, dass die Transformationen die Daten erfolgreich auf eine Normalverteilung abbilden, wenn sie auf bestimmte Datensätze angewendet werden, aber bei anderen unwirksam sind. Dies unterstreicht die Bedeutung der Visualisierung der Daten vor und nach der Transformation.

Beachten Sie auch, dass Box-Cox zwar bei lognormalen und Chi-Quadrat-Verteilungen besser zu funktionieren scheint als Yeo-Johnson, aber bedenken Sie, dass Box-Cox keine Eingaben mit negativen Werten unterstützt.

Zum Vergleich fügen wir auch die Ausgabe von QuantileTransformer hinzu. Diese kann jede beliebige Verteilung in eine Gaußsche Verteilung erzwingen, vorausgesetzt, es gibt genügend Trainingsstichproben (Tausende). Da es sich um eine nicht-parametrische Methode handelt, ist sie schwieriger zu interpretieren als die parametrischen Methoden (Box-Cox und Yeo-Johnson).

Bei „kleinen“ Datensätzen (weniger als einige hundert Punkte) neigt der Quantiltransformator zur Überanpassung. Die Verwendung der Potenztransformation wird dann empfohlen.

Lognormal, Chi-squared, Weibull, After Box-Cox $\lambda$ = -0.0, After Box-Cox $\lambda$ = 0.27, After Box-Cox $\lambda$ = 12.59, After Yeo-Johnson $\lambda$ = -0.83, After Yeo-Johnson $\lambda$ = -0.12, After Yeo-Johnson $\lambda$ = 24.53, After Quantile transform, After Quantile transform, After Quantile transform, Gaussian, Uniform, Bimodal, After Box-Cox $\lambda$ = 0.54, After Box-Cox $\lambda$ = 0.63, After Box-Cox $\lambda$ = 1.69, After Yeo-Johnson $\lambda$ = 0.54, After Yeo-Johnson $\lambda$ = 0.42, After Yeo-Johnson $\lambda$ = 1.7, After Quantile transform, After Quantile transform, After Quantile transform
# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

import matplotlib.pyplot as plt
import numpy as np

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PowerTransformer, QuantileTransformer

N_SAMPLES = 1000
FONT_SIZE = 6
BINS = 30


rng = np.random.RandomState(304)
bc = PowerTransformer(method="box-cox")
yj = PowerTransformer(method="yeo-johnson")
# n_quantiles is set to the training set size rather than the default value
# to avoid a warning being raised by this example
qt = QuantileTransformer(
    n_quantiles=500, output_distribution="normal", random_state=rng
)
size = (N_SAMPLES, 1)


# lognormal distribution
X_lognormal = rng.lognormal(size=size)

# chi-squared distribution
df = 3
X_chisq = rng.chisquare(df=df, size=size)

# weibull distribution
a = 50
X_weibull = rng.weibull(a=a, size=size)

# gaussian distribution
loc = 100
X_gaussian = rng.normal(loc=loc, size=size)

# uniform distribution
X_uniform = rng.uniform(low=0, high=1, size=size)

# bimodal distribution
loc_a, loc_b = 100, 105
X_a, X_b = rng.normal(loc=loc_a, size=size), rng.normal(loc=loc_b, size=size)
X_bimodal = np.concatenate([X_a, X_b], axis=0)


# create plots
distributions = [
    ("Lognormal", X_lognormal),
    ("Chi-squared", X_chisq),
    ("Weibull", X_weibull),
    ("Gaussian", X_gaussian),
    ("Uniform", X_uniform),
    ("Bimodal", X_bimodal),
]

colors = ["#D81B60", "#0188FF", "#FFC107", "#B7A2FF", "#000000", "#2EC5AC"]

fig, axes = plt.subplots(nrows=8, ncols=3, figsize=plt.figaspect(2))
axes = axes.flatten()
axes_idxs = [
    (0, 3, 6, 9),
    (1, 4, 7, 10),
    (2, 5, 8, 11),
    (12, 15, 18, 21),
    (13, 16, 19, 22),
    (14, 17, 20, 23),
]
axes_list = [(axes[i], axes[j], axes[k], axes[l]) for (i, j, k, l) in axes_idxs]


for distribution, color, axes in zip(distributions, colors, axes_list):
    name, X = distribution
    X_train, X_test = train_test_split(X, test_size=0.5)

    # perform power transforms and quantile transform
    X_trans_bc = bc.fit(X_train).transform(X_test)
    lmbda_bc = round(bc.lambdas_[0], 2)
    X_trans_yj = yj.fit(X_train).transform(X_test)
    lmbda_yj = round(yj.lambdas_[0], 2)
    X_trans_qt = qt.fit(X_train).transform(X_test)

    ax_original, ax_bc, ax_yj, ax_qt = axes

    ax_original.hist(X_train, color=color, bins=BINS)
    ax_original.set_title(name, fontsize=FONT_SIZE)
    ax_original.tick_params(axis="both", which="major", labelsize=FONT_SIZE)

    for ax, X_trans, meth_name, lmbda in zip(
        (ax_bc, ax_yj, ax_qt),
        (X_trans_bc, X_trans_yj, X_trans_qt),
        ("Box-Cox", "Yeo-Johnson", "Quantile transform"),
        (lmbda_bc, lmbda_yj, None),
    ):
        ax.hist(X_trans, color=color, bins=BINS)
        title = "After {}".format(meth_name)
        if lmbda is not None:
            title += "\n$\\lambda$ = {}".format(lmbda)
        ax.set_title(title, fontsize=FONT_SIZE)
        ax.tick_params(axis="both", which="major", labelsize=FONT_SIZE)
        ax.set_xlim([-3.5, 3.5])


plt.tight_layout()
plt.show()

Gesamtlaufzeit des Skripts: (0 Minuten 1,893 Sekunden)

Verwandte Beispiele

Vergleich der Auswirkungen verschiedener Skalierer auf Daten mit Ausreißern

Vergleich der Auswirkungen verschiedener Skalierer auf Daten mit Ausreißern

Frühes Stoppen in Gradient Boosting

Frühes Stoppen in Gradient Boosting

Skalierung des Regularisierungsparameters für SVCs

Skalierung des Regularisierungsparameters für SVCs

Die Johnson-Lindenstrauss-Schranke für Einbettung mit zufälligen Projektionen

Die Johnson-Lindenstrauss-Schranke für Einbettung mit zufälligen Projektionen

Galerie generiert von Sphinx-Gallery