Normaliser ses Données – Comment faire en 2 minutes

Normaliser ses données en 2 minutes, aussi bien pour un DataFrame qu’un Numpy Array. C’est le défi de cet article !

La normalisation c’est changer l’échelle des valeurs de notre dataset pour les standardiser.

Au lieu d’avoir une colonne de données allant de 8 à 1800 et une autre allant de -37 à 90, on normalise le tout pour les faire aller de 0 à 1.

Mais pourquoi normaliser ?

En normalisant chacune de nos colonnes de manière à ce qu’elles aient la même distribution, on aide notre modèle de Machine Learning lors de son apprentissage. Effectivement cela permet au modèle de pouvoir analyser chacune de nos colonnes en utilisant la même approche.

Ainsi le modèle n’a pas à adapter ses canaux d’entrées à différentes échelles mais bien à une seule.

En langage mathématique : la normalisation aide à optimiser la fonction de perte et à la faire converger plus rapidement.

Cela en fait une technique utilisée aussi bien pour le Machine Learning que pour le Deep Learning.

Plus le nombre de colonnes du dataset est grand, plus la normalisation est longue à réaliser manuellement.

Heureusement pour nous, Scikit-Learn nous permet de réaliser cette tâche de manière automatique.

C’est ce qu’on voit tout de suite !

Data

Pour ce tutoriel on va reprendre le dataset sur la qualité de vin.

On l’avait utilisé dans cet article détaillé pour apprendre le Machine Learning.

L’objectif est de prédire la qualité de vins à partir de ses features (acidité, taux d’alcool, pH, etc). Tu peux télécharger le dataset depuis cet adresse Github.

Une fois chargé dans ton environnement de travail, ouvre-le avec la librairie Pandas :

import pandas as pd

df = pd.read_csv("winequality-white.csv", sep=";")
df.head(3)

On sépare le label (le niveau de qualité du vin) des features (caractéristiques qui nous aideront à prédire le label) :

df_features = df.drop(columns='quality')
df_label = df['quality']

Et on va pouvoir commencer la normalisation.

Comme expliqué précédemment, la normalisation c’est changer l’échelle de valeurs des colonnes de notre dataset.

Mais qu’est-ce qui définit cette échelle ?

Prenons la colonne fixed acidity, l’échelle est premièrement déterminée par la valeur minimum et maximum.

Le minimum et le maximum sont les valeurs entre lesquels toutes les autres oscillent.

Ensuite on a la moyenne : la somme de ces données divisée par leur nombre total.

Et l’écart-type (appelé Standard Deviation en anglais) qui mesure à quel point les valeurs du dataset sont éloignées de la moyenne. Plus la valeur de l’écart-type est élevée, plus les valeurs sont distantes de la moyenne.

Affichons ces mesures pour la colonne fixed acidity.

print(f'Min : ',df_features['fixed acidity'].min(),', Max :', df_features['fixed acidity'].max())
print(f'Mean : ',round(df_features['fixed acidity'].mean(),2),', Standard Deviation :', round(df_features['fixed acidity'].std(),2))

Sortie :
Min : 3.8 , Max : 14.2
Mean : 6.85 , Standard Deviation : 0.84

D’autres mesures existent pour mesurer l’échelle d’un jeu de données mais celle-ci sont les principales.

La normalisation c’est modifier ces mesures (tout en préservant l’information), grâce à des fonctions mathématiques, pour les inclure dans l’échelle de notre choix.

Normalisation entre 0 et 1

L’une des normalisation les plus basiques est la normalisation de 0 à 1.

On modifie nos données pour qu’elles soient compris dans l’intervalle [0, 1].

Le minimum sera 0 et le maximum sera 1.

Pour cela on initialise MinMaxScaler() du package preprocessing de sklearn :

from sklearn import preprocessing

transformer = preprocessing.MinMaxScaler().fit(df_features[['fixed acidity']])

Ensuite on utilise la fonction transform() sur notre colonne fixed acidity pour la normaliser :

X_transformed = transformer.transform(df_features[['fixed acidity']])

Vous pouvez afficher X_transformed et voir que les valeurs ont été transformé. Elles ont subit une normalisation.

Cela ne dégrade pas ou peu nos données.

Effectivement, la normalisation modifie la valeur des données mais le fait tout en préservant l’information concernant la distance entre chaque point.

Par ailleurs il suffit d’utiliser la fonction inverse_transform() pour repasser aux valeurs précédentes.


CRÉER TON APPLICATION IA !


Reçois tes 5 JOURS De Formation GRATUITE Pour Apprendre À Créer Ton APPLICATION d’INTELLIGENCE ARTIFICIELLE !


Tous les fondamentaux de la création d’Application IA : les approches, les outils et techniques, les librairies et framework, et bien d'autres !

Découvres étape par étape la création d’application de Deep Learning (tu apprendras même à trouver des idées d’appli !).

En bonus, tu recevras notre Guide Ultime du Deep Learning !


Attention, la transformation convertit vos DataFrame en Numpy Array. Pour avoir un DataFrame au lieu d’un Numpy Array, utilisez après l’opération de normalisation : df = pd.DataFrame(X_transformed, columns = ['fixed acidity', 'volatile acidity', 'citric acid', 'residual sugar', 'chlorides', 'free sulfur dioxide', 'total sulfur dioxide', 'density', 'pH', 'sulphates', 'alcohol']).

On peut maintenant afficher les mesures pour confirmer que la normalisation à eu lieu :

print(f'Min : ',round(X_transformed.min(),2),', Max :', round(X_transformed.max(),2))
print(f'Mean : ',round(X_transformed.mean(),2),', Standard Deviation :', round(X_transformed.std(),2))

Sortie :
Min : 0.0 , Max : 1.0
Mean : 0.29 , Standard Deviation : 0.08

Normalisation entre -1 et 1

Une autre normalisation usuelle est la normalisation de -1 à 1.

On reprend la même fonction que précédemment MinMaxScaler() mais, ici, on lui indique l’attribut feature_range qui détermine l’intervalle de normalisation : (-1, 1)

from sklearn import preprocessing

transformer2 = preprocessing.MinMaxScaler(feature_range=(-1, 1)).fit(df_features[['fixed acidity']])

On applique la transformation :

X_transformed2 = transformer2.transform(df_features[['fixed acidity']])

Et on affiche les mesures :

print(f'Min : ',round(X_transformed2.min(),2),', Max :', round(X_transformed2.max(),2))
print(f'Mean : ',round(X_transformed2.mean(),2),', Standard Deviation :', round(X_transformed2.std(),2))

Sortie :
Min : -1.0 , Max : 1.0
Mean : -0.41 , Standard Deviation : 0.16

À noter que la fonction peut être utiliser pour tout type d’intervalle (-10, 10), (-100, 100), etc.

Obtenir une Distribution Normale (Loi Normale)

Passons à une normalisation plus prisée des experts.

La normalisation en Loi Normale, aussi appelé standardisation, consiste à modifier l’échelle d’un jeu de données de telle sorte à obtenir :

  • Un écart-type de 1
  • Une moyenne de 0

La standardisation est idéal lorsque l’on a des outliers, des données inhabituellement éloignées de la moyenne.

Effectivement dans les précédentes normalisations, on a imposé une limite à nos données : entre 0 et 1 par exemple.

Avec la standardisation, il n’y a pas de limite, uniquement le prérequis d’avoir une moyenne de 0 et un écart-type de 1.

Ainsi, lorsque le jeu de données possède des outliers, il est préférable d’utiliser la standardisation. La non-limitation offerte pas la standardisation nous permet de préserver l’information sur la distance inabituelle des outliers.

Pour standardiser on utilise StandardScaler :

from sklearn import preprocessing

transformer = preprocessing.StandardScaler().fit(df_features[['fixed acidity']])

On applique la transformation :

X_transformed3 = transformer.transform(df_features[['fixed acidity']])

Et on affiche les mesures :

print(f'Min : ',round(X_transformed3.min(),2),', Max :', round(X_transformed3.max(),2))
print(f'Mean : ',round(X_transformed3.mean(),2),', Standard Deviation :', round(X_transformed3.std(),2))

Sortie :
Min : -3.62 , Max : 15.03
Mean : 0.0 , Standard Deviation : 1.0

La Puissance de la Normalisation

La normalisation c’est bien de savoir l’utiliser mais est-ce que ça marche ?

Dans notre article détaillé pour apprendre le Machine Learning on explorait plusieurs modèles pour déterminer le plus performants.

Résultat : le meilleur modèle était le Decision Tree avec une précision de 60%.

Un score satisfaisant au vue de la corrélation entre nos features et le label mais…

… peut-on améliorer ce score avec la normalisation ?

C’est ce que je vous propose de voir ! 🔥

On initialise ici la standardisation sur l’ensemble de nos features :

from sklearn import preprocessing

transformer = preprocessing.StandardScaler().fit(df_features)

On applique la transformation :

df_features_transformed = transformer.transform(df_features)

Maintenant on peut séparer nos données pour l’entraînement et le test :

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(df_features, df_label, test_size=0.20)

Entraînons maintenant notre fameux Decision Tree :

from sklearn import tree

decisionTree = tree.DecisionTreeClassifier()
decisionTree.fit(X_train, y_train)

Et calculons sa précision :

decisionTree.score(X_test, y_test)

Sortie:

0.626

Une précision de 62.6% !

Avec la normalisation on a réussit à augmenter les performances du modèle de 2.6%.

Cela peut sembler peu aux yeux d’un débutant, mais les experts savent que augmenter la précision d’un modèle de, ne serait-ce que, 1% est déjà énorme.

Et vous, quel score la normalisation vous a permis d’atteindre ?

Les méthodes pour améliorer un modèle de Machine Learning sont nombreuses. Après la normalisation, on peut citer :

À bientôt dans un prochain article !

Et si vous souhaitez rester informé n’hésitez pas à vous abonnez à notre newsletter 😉


CRÉER TON APPLICATION IA !


Reçois tes 5 JOURS De Formation GRATUITE Pour Apprendre À Créer Ton APPLICATION d’INTELLIGENCE ARTIFICIELLE !


Tous les fondamentaux de la création d’Application IA : les approches, les outils et techniques, les librairies et framework, et bien d'autres !

Découvres étape par étape la création d’application de Deep Learning (tu apprendras même à trouver des idées d’appli !).

En bonus, tu recevras notre Guide Ultime du Deep Learning !


Tom Keldenich
Tom Keldenich

Data Engineer & passionné d'Intelligence Artificielle !

Fondateur du site Inside Machine Learning

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.