Data preprocessing : Feature Scaling avec Python

By | 12 octobre 2017
0 Flares Twitter 0 LinkedIn 0 Reddit 0 Google+ 0 Filament.io 0 Flares ×

Les données sont au centre des algorithmes de Machine Learning. Par conséquent, préparer au mieux ces données, permettra d’avoir de meilleures performances.

La plupart du temps, en machine Learning, les Data Set proviennent avec des ordres de grandeurs différents. Cette différence d’échelle peut conduire à des performances moindres. Pour palier à cela, des traitements préparatoires sur les données existent. Notamment le Feature Scaling qui comprend la Standardisation et la Normalisation.

Voyons de plus prêt ces notions.

C’est parti !

data preprocessing data science

Data preprocessing

Nécessité de faire du Data preprocessing

Quand les données d’un Data Set sont dans des ordres de grandeurs différents, certains algorithmes de Machine Learning mettent plus de temps à trouver un modèle prédictif optimal.

Trouver un modèle prédictif optimal, revient souvent à minimiser une fonction de coût (en utilisant Gradient Descent par exemple). Ce dernier va itérativement, trouver un vecteur de poids (weights) \Theta, qui minimise la fonction de coût.

Supposons qu’on ait à prédire le prix d’une maison en fonction de sa superficie et le nombre de chambres qu’elle contient.  La feature nombre de chambres sera largement inférieure à la superficie de l’appartement (ex : 40 M² pour 2 pièces).

Pour une régression multivariée, vu qu’on a pour cet exemple deux features (X_{1} : la superficie et X_{2} : le nombre de chambres), on aura à trouver trois constantes \theta_ {0}, \theta_{1}, et \theta_{2}.

Tel que :

    \[h(X) = \theta_{0} x_{0} + \theta_{1} x_{1} + \theta_{2} x_{2} \]

Note : x_{0} vaut toujours 1. Il s’agit d’une astuce mathématique pour simplifier le calcul matriciel de h(X)Pour plus d’informations, voir l’article sur comment sont représentées les features en Machine Learning

Lors des itérations du gradient Descent pour calculer les meilleurs \theta pour h(X), certaines d’entre elles se mettront plus rapidement à jour par rapport à d’autres. Cela en fonction de l’ordre de grandeur des différentes features. Cette différence de “rapidité” de mise à jour des \theta, conduira à ce que Gradient Descent mette plus de temps pour converger et par conséquent trouver le modèle optimal.

contour plot feature scaling

Illustration inspirée du cours d’Andrew NG

Le contour plot ci-dessus est typique de deux features ayant une grandeur d’échelle différentes. On remarque que les contours (lignes bleues) sont assez entassées. Les flèches rouges illustrent comment Gradient Descent peine (avec des “zig-zag”) à trouver le “centre” du contour plot qui est le vecteur \Theta optimal.

On remarque également, avec les flêches rouges, que le Gradient Descent, met plus d’itérations pour trouver le centre du “contour plot” qui est le meilleur couple de \theta_0 et \theta_1.

standardisation contour plot

Illustration inspirée du cours d’Andrew NG

En appliquant la normalisation, on souhaite obtenir une valeur de features ayant le même ordre de grandeur (on y vient dans la suite de l’article). La première conséquence à cela est d’avoir un contour plot plus régulier (et moins entassé). Généralement, dans cette situation, Gradient Descent trouve plus rapidement le minimum de la fonction de coût. Et par conséquent la fonction de prédiction optimale.

Les algorithmes concernés par le Data processing

Le Feature Scaling  est une bonne pratique, pour ne pas dire obligatoire, lors de la modélisation avec du Machine Learning.

Les algorithmes pour lesquels le feature scaling s’avère nécessaire, sont ceux pour lesquels il faudra

  • Calculer un vecteur de poids (weights) theta
  • Calculer des distances pour déduire le degrée de similarité de deux items
  • Certains algorithmes de Clustering

Plus concrétement, voici une liste d’algorithmes non exhaustive pour lesquels il faudra procéder au Feature Scaling :

  • Logistic Regression
  • Regression Analysis (polynomial, multivariate regression…)
  • Support Vector Machines (SVM)
  • K-Nearest Neighbors (KNN)
  • K-Means (clustering…)
  • Principal Component Analysis (PCA)

Les différentes techniques de Feature Scaling

La Normalisation

Min-Max Scaling peut- être appliqué quand les données varient dans des échelles différentes. A l’issue de cette transformation, les features seront comprises dans un intervalle fixe [0,1]. Le but d’avoir un tel intervalle restreint est de réduire l’espace de variation des valeurs d’une feature et par conséquent réduire l’effet des outliers.

La normalisation peut- être effectuée par la technique du Min-Max Scaling. La transformation se fait grâce à la formule suivante :

    \[X_{normalise} = \frac{X - X_{min}}{X_{max} - X_{min}}\]

Avec :

  • X_{min} : la plus petite valeur observée pour la feature X
  • X_{min} : la plus grande valeur observée pour la feature X
  • X : La valeur de la feature qu’on cherche à normaliser

La Standardisation

La standardisation (aussi appelée Z-Score normalisation  à ne pas confondre avec la normalisation du paragraphe précendent) peut- être appliquée quand les input features répondent à des distributions normales (Distributions Gaussiennes) avec des moyennes et des écart-types différents. Par conséquent, cette transformation aura pour impact d’avoir toutes nos features répondant à la même loi normale X \sim \mathcal{N} (0, \, 1).

La standardisation peut également être appliquée quand les features ont des unités différentes.

La Standardisation est le processus de transformer une feature en une autre qui répondra à la loi normale (Gaussian DistributionX \sim \mathcal{N} (\mu, \, \sigma) avec :

  • \mu = 0  La moyenne de la loi de distribution
  • \sigma = 1 est l’Écart-type (Standard Deviation)

La formule de standardisation d’une feature est la suivante :

    \[z =  \frac{ x - \mu} {\sigma} \]

avec :

  • x la valeur qu’on veut standardiser (input variable)
  • \mu la moyenne (mean) des observations pour cette feature
  • \sigma est l’ecart-type (Standard Deviationdes observations pour cette feature

Pour s’assurer que nos données non transformées répondent à une loi normale, on peut toujours faire un plot pour voir leur répartition.

normal distribution

Exemple de données répondant à une loi normal X \sim \mathcal{N} (3.8, \, 4.3)

Feature Scaling et Scikit Learn

Python et sa librairie Sickit Learn permettent d’appliquer le feature scaling sans avoir à coder les formules par nous même. Les fonctions de feature scaling sont regroupées dans le package preprocessing de Sickit Learn.

Dans cette section, on appliquera la normalisation et la standardisation sur un jeu de données et verront les impacts de ces transformations à l’aide de visualisations graphique.

A propos du jeu de données

Le jeu de données computer Hardware qu’on va utiliser est publié par l’université américaine UCI. C’est un jeu de données qui a été utilisé pour des besoins de recherche notamment en Regression Analysis.

Vous pouvez trouver une description complète de la composition du dataset à cette adresse.

Pour simplifier la lecture des snippets de code, je suivrai la démarche suivante :

  1. Chargement du dataset
  2. Application d’une technique de feature scaling
  3. Affichage de certaines métriques (notamment le min, le max et la moyenne)

Pour les besoins illustratifs, je m’interesserai uniquement aux features MYCT  et MMAX. Elles représentent respectivement :

  • MYCT : Machine Cycle time in nanoseconds
  • MMAX : Maximum Main Memory in Kilobytes

On remarque déjà qu’on a une différence d’unités 🙂

Application de la normalisation

La normalisation peut- être appliquée par le min-max scaling. Python propose pour cela une classe nommée “MinMaxScaler” dans le package preprocessing.

import numpy as np
import matplotlib.pyplot as plt

from sklearn.preprocessing import MinMaxScaler

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/cpu-performance/machine.data'

names= ['constructor','Model','MYCT','MMIN','MMAX','CACH','CHMIN','CHMAX','PRP','ERP']

dataset = pd.read_csv(url, names=names)

# MIN MAX SCALING
minmax_scale = MinMaxScaler().fit(dataset[['MYCT', 'MMAX']])
df_minmax = minmax_scale.transform(dataset[['MYCT', 'MMAX']])

#imprimer un retour à la ligne pour une meilleur clarete de lecture
print('\n********** Normalisation*********\n')

print('Moyenne apres le Min max Scaling :\nMYCT={:.2f}, MMAX={:.2f}'
.format(df_minmax[:,0].mean(), df_minmax[:,1].mean()))

print('\n')

print('Valeur minimale et maximale pour la feature MYCT apres min max scaling: \nMIN={:.2f}, MAX={:.2f}'
.format(df_minmax[:,0].min(), df_minmax[:,0].max()))

print('\n')

print('Valeur minimale et maximale pour la feature MMAX apres min max scaling : \nMIN={:.2f}, MAX={:.2f}'
.format(df_minmax[:,1].min(), df_minmax[:,1].max()))

L’exécution de ce code produit l’affichage suivant :


********** Normalisation*********

Moyenne apres le Min max Scaling :
MYCT=0.13, MMAX=0.18

Valeur minimale et maximale pour la feature MYCT apres min max scaling:
MIN=0.00, MAX=1.00


Valeur minimale et maximale pour la feature MMAX apres min max scaling :
MIN=0.00, MAX=1.00
Affichage des valeurs apres scaling
[[ 0.07282535 0.09284284]
[ 0.00809171 0.4994995 ]
[ 0.00809171 0.4994995 ]
...,
[ 0.07282535 0.12412412]
[ 0.31220499 0.12412412]
[ 0.31220499 0.06156156]]

On remarque bien qu’après la normalisation, l’intervalle des valeurs devient limité entre 0 et 1. Cela est vrai pour les deux features.

Application de la standardisation

Pour appliquer la standardisation, on peut utiliser la classe StandardScaler de Sickit Learn.


********** Normalisation*********</pre>
import numpy as np
import matplotlib.pyplot as plt

from sklearn.preprocessing import MinMaxScaler

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/cpu-performance/machine.data'

names= ['constructor','Model','MYCT','MMIN','MMAX','CACH','CHMIN','CHMAX','PRP','ERP']


dataset = pd.read_csv(url, names=names)

# Z-Score standardisation

std_scaler = MinMaxScaler().fit(dataset[['MYCT', 'MMAX']])
df_std = std_scaler.transform(dataset[['MYCT', 'MMAX']])

print('\n********** Standardisation*********\n')

print('Moyenne et Ecart type apres la standardisation de la feature MYCT :\nMoyenne={:.2f}, Ecart Type={:.2f}'
.format(df_std[:,0].mean(), df_std[:,0].std()))

print('\n')

print('Moyenne et Ecart type apres la standardisation de la feature MYCT :\nMoyenne={:.2f}, Ecart Type={:.2f}'
.format(df_std[:,1].mean(), df_std[:,1].std()))

print('\n')

print('Valeur minimale et maximale pour la feature MYCT apres min max scaling: \nMIN={:.2f}, MAX={:.2f}'
.format(df_std[:,0].min(), df_std[:,0].max()))
print('\n')

print('Valeur minimal et maximal pour la feature MMAX apres min max scaling : \nMIN={:.2f}, MAX={:.2f}'
.format(df_std[:,1].min(), df_std[:,1].max()))

print('Affichage des valeurs apres scaling')
print(df_std)

L’exécution de ce code produit l’affichage suivant :


********** Standardisation*********

Moyenne et Ecart type apres la standardisation de la feature MYCT :
Moyenne=0.13, Ecart Type=0.18


Moyenne et Ecart type apres la standardisation de la feature MYCT :
Moyenne=0.18, Ecart Type=0.18

Valeur minimale et maximale pour la feature MYCT apres min max scaling:
MIN=0.00, MAX=1.00

Valeur minimal et maximal pour la feature MMAX apres min max scaling :
MIN=0.00, MAX=1.00
Affichage des valeurs apres scaling
[[ 0.07282535 0.09284284]
[ 0.00809171 0.4994995 ]
[ 0.00809171 0.4994995 ]
...,
[ 0.07282535 0.12412412]
[ 0.31220499 0.12412412]
[ 0.31220499 0.06156156]]

 

Représentation graphique des données avant et après normalisation

Pour mieux appréhender l’impact des techniques de features scaling sur les données, nous allons dessiner un plot visualisant nos deux features avant et après l’application de la standardisation et la normalisation.

Par souci de simplicité, j’ai regroupé dans une seule fonction l’affichage des trois données (sans transformation, données après normalisation et données après Standardisation).


def plot():
    plt.figure(figsize=(8,6))

    plt.scatter(dataset['MYCT'], dataset['MMAX'],
            color='green', label='donnees sans transformations', alpha=0.5)


    plt.scatter(df_minmax[:,0], df_minmax[:,1],
            color='red', label='min-max scaled [min=0, max=1]', alpha=0.3)
    
    plt.scatter(df_std[:,0], df_std[:,1],
            color='blue', label='Standardisation vers la loi Normal X ~ N(0,1)', alpha=0.3)

    plt.title('Plot des features MYCT et MMAX avant et apres scaling')
    plt.xlabel('MYCT')
    plt.ylabel('MMAX')
    plt.legend(loc='upper right')
    plt.grid()

    plt.tight_layout()

plot()
plt.show()

Ce qui produira la figure suivante :

feature scaling sickit learn

 

Ce jeu de données ne contient pas beaucoup d’observations (rows). Cependant, on voit bien comment les données (points verts) sont “éparpillées” dans tout le schéma. Il s’agit des données sans feature Scaling.

Après application de la Standardisation, on remarque une concentration autour du  point (0,0) des données. Cela parce qu’on a réduit l’écart type des données transformées. Par ailleurs, les données du Min-Max Scaling seront aussi au niveau du point (0,0) mais  “cachées” par le point en bleu.

 

Conclusion

Le Feature Scaling permet de préparer les données quand elles ont des échelles différentes. Faire du Feature Scaling est une bonne pratique et il permettra d’avoir de meilleurs modèles prédictifs.

Parmi les techniques du feature scaling, on retrouve la Standardisation et la Normalisation. Vous savez maintenant comment utiliser Sickit Learn pour normaliser vos features.

Je vous suggère de télécharger le code que vous venez de lire et de l’essayer chez vous. Si vous avez des questions, posez les par un commentaire et je ferai de mon mieux pour y répondre.

Inscrivez-vous à la Newsletter
Rejoignez la communauté Mr mint, le blog Français dédié à la Data Science et recevez des contenus exclusifs et d'autres goodies !
Nous détestons les spams. Votre adresse e-mail ne sera pas vendue ou partagée avec quelqu'un d'autre.
0 Flares Twitter 0 LinkedIn 0 Reddit 0 Google+ 0 Filament.io 0 Flares ×

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *