Introduction
Ce laboratoire montre comment utiliser les transformations Box-Cox et Yeo-Johnson via PowerTransformer pour mapper des données issues de diverses distributions vers une distribution normale.
Conseils sur la machine virtuelle
Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter Notebook pour pratiquer.
Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations du carnet Jupyter Notebook.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez votre feedback après la session, et nous résoudrons rapidement le problème pour vous.
Importation des bibliothèques
Tout d'abord, nous devons importer les bibliothèques nécessaires : numpy, matplotlib, PowerTransformer, QuantileTransformer et train_test_split.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PowerTransformer
from sklearn.preprocessing import QuantileTransformer
from sklearn.model_selection import train_test_split
Définition des constantes
Nous allons définir les constantes pour le nombre d'échantillons, la taille de police et le nombre de classes.
N_SAMPLES = 1000
FONT_SIZE = 6
BINS = 30
Création de distributions aléatoires
Nous allons générer six distributions de probabilité différentes : Lognormale, Khi-carré, Weibull, Gaussienne, Uniforme et Bimodale.
rng = np.random.RandomState(304)
bc = PowerTransformer(method="box-cox")
yj = PowerTransformer(method="yeo-johnson")
qt = QuantileTransformer(n_quantiles=500, output_distribution="normal", random_state=rng)
size = (N_SAMPLES, 1)
## distribution lognormale
X_lognormal = rng.lognormal(size=size)
## distribution khi-carré
df = 3
X_chisq = rng.chisquare(df=df, size=size)
## distribution weibull
a = 50
X_weibull = rng.weibull(a=a, size=size)
## distribution gaussienne
loc = 100
X_gaussian = rng.normal(loc=loc, size=size)
## distribution uniforme
X_uniform = rng.uniform(low=0, high=1, size=size)
## distribution bimodale
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)
Création de graphiques
Maintenant, nous allons créer des graphiques pour chacune des six distributions, montrant la distribution d'origine et la distribution transformée en utilisant les transformations Box-Cox, Yeo-Johnson et le transformateur quantile.
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)
## effectuer les transformations de puissance et la transformation quantile
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 = "Après {}".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()
Résumé
Dans ce laboratoire, nous avons appris à utiliser PowerTransformer pour mapper des données issues de diverses distributions vers une distribution normale en utilisant les transformations Box-Cox et Yeo-Johnson. Nous avons également appris à utiliser QuantileTransformer pour forcer n'importe quelle distribution arbitraire à devenir une distribution gaussienne. Il est important de visualiser les données avant et après la transformation, car certaines transformations peuvent être inefficaces avec certains ensembles de données.