Caractéristiques des variables : l’amplitude

L’amplitude de la variable a-t-elle de l’importance ?

Les modèles linéaires sont du type y = w x + b, où le coefficient de régression w représente la variation attendue en y pour une variation d’une unité en x (le prédicteur). Ainsi, l’amplitude de w est en partie déterminée par la magnitude des unités utilisées pour x. Si x est une variable de distance, le simple fait de changer l’échelle des kilomètres en mètres entraînera un changement dans la magnitude du coefficient.

En outre, dans les situations où nous estimons le résultat y en envisageant plusieurs prédicteurs x1, x2, …xn, les prédicteurs ayant des plages numériques plus grandes dominent sur ceux ayant des plages numériques plus petites.

La descente de gradient converge plus rapidement lorsque tous les prédicteurs (x1 à xn) se trouvent dans une échelle similaire, donc le fait d’avoir des caractéristiques dans une échelle similaire est utile pour les réseaux neuronaux.

Dans les Support Vector Machines, l’échelle des caractéristiques peut réduire le temps nécessaire pour trouver les vecteurs de soutien.

Enfin, les méthodes utilisant des distances euclidiennes ou des distances en général sont également affectées par la magnitude des caractéristiques, car la distance euclidienne est sensible aux variations de l’ampleur ou des échelles des prédicteurs. C’est pourquoi une mise à l’échelle des caractéristiques est nécessaire pour les méthodes qui utilisent des calculs de distance comme le voisinage le plus proche (KNN) et le regroupement des moyennes k.

En résumé :

L’amplitude est importante parce que :

  • Le coefficient de régression est directement influencé par l’échelle de la variable
  • Les variables ayant une plus grande amplitude / plage de valeurs dominent sur celles ayant une plus petite amplitude / plage de valeurs
  • La descente de la pente converge plus rapidement lorsque les caractéristiques sont à des échelles similaires
  • La mise à l’échelle des fonctionnalités permet de réduire le temps nécessaire pour trouver des vecteurs de soutien aux MVC
  • Les distances euclidiennes sont sensibles à la magnitude des caractéristiques.

Les modèles d’apprentissage machine affectés par l’amplitude sont :

  • Régression linéaire et logistique
  • Réseaux de neurones
  • SVM
  • KNN
  • K-means clustering
  • Analyse discriminante linéaire (LDA)
  • Analyse en composantes principales (ACP)

Les modèles d’apprentissage machine insensibles à la magnitude des caractéristiques sont ceux basés sur les arbres :

  • Arbres de classification et de régression
  • Forêts au hasard
  • Arbres renforcés par des gradients
import pandas as pd
import numpy as np

# importation de modèles de ML
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.neural_network import MLPClassifier
from sklearn.neighbors import KNeighborsClassifier

# Scale des variables
from sklearn.preprocessing import MinMaxScaler

# tPour évaluer les perf

from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split

Charger les données avec des variables numériques uniquement

data = pd.read_csv('../exportfeature.csv',parse_dates=['date'],infer_datetime_format=True,dayfirst=True,sep=";",encoding='ANSI')[[
                          'allocation', 'nAllocation', 'iCote','nbPartants','nbPartants.1','place'
                      ]]

data.head()
# examinons les valeurs de ces variables
# pour avoir une idée de l'amplitude des caractéristiques

data.describe()
        allocation	nAllocation	iCote	nbPartants	nbPartants.1	place
count	20504.000000	2.050400e+04	16990.000000	20504.000000	20504.000000	20504.000000
mean	27733.059544	4.192120e+04	12.531313	13.775995	13.587495	0.546869
std	    32133.374636	1.585988e+05	21.629818	2.759987	2.782522	0.497811
min	    1.000000	6.000000e+02	1.000000	4.000000	2.000000	0.000000
25%	    16000.000000	1.500000e+04	3.000000	12.000000	12.000000	0.000000
50%	    21000.000000	2.100000e+04	5.000000	14.000000	14.000000	1.000000
75%	    32000.000000	3.600000e+04	12.000000	16.000000	16.000000	1.000000
max	    1000000.000000	6.000000e+06	425.000000	18.000000	18.000000	1.000000

On peut voir que l’allocation varie entre 1 et 1000000, le nombre de partants entre 2 et 18 et la place entre 0 et 1. Les variables ont donc une amplitude différente.

# calculons maintenant la plage de valeur

for col in ['allocation', 'nAllocation', 'iCote','nbPartants','nbPartants.1']:
    print(col, 'range: ', data[col].max() - data[col].min())
allocation range:  999999.0
nAllocation range:  5999400
iCote range:  424.0
nbPartants range:  14
nbPartants.1 range:  16

-> La gamme de valeurs que chaque variable peut prendre est très différente.
# Créons un ensemble de formation et de tests
# l'ensemble de données  contient des informations manquantes
# donc pour cette démo, je vais les remplir avec des 0

X_train, X_test, y_train, y_test = train_test_split(
    data[['allocation', 'nAllocation', 'iCote','nbPartants','nbPartants.1']].fillna(0),
    data.place,
    test_size=0.3,
    random_state=0)

X_train.shape, X_test.shape

Mise à l’échelle

 

Pour cette démonstration, j’échelonnerai les variables entre 0 et 1, en utilisant le MinMaxScaler de scikit-learn. Pour en savoir plus sur cette mise à l’échelle, visitez le site web de Scikit-Learn website

La transformation est donnée par :

X_rescaling = X – X.min() / (X.max – X.min()

Et pour ramener les éléments redimensionnés à leur taille d’origine :

X = X_rescalé * (max – min) + min

Il y aura une section consacrée à la mise à l’échelle plus tard, où j’expliquerai plus en détail cette technique et d’autres techniques de mise à l’échelle.

Pour l’instant, poursuivons la démonstration.

# Mise à l'échelle entre 0 et 1.

scaler = MinMaxScaler()

# Mise en forme des données
scaler.fit(X_train)

# Mise à l'échelle des données
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)

#Jetons un coup d'oeil à l'ensemble des données de formation à l'échelle

print('Moyenne: ', X_train_scaled.mean(axis=0))
print('Standard Deviation: ', X_train_scaled.std(axis=0))
print('Valeur Minimum: ', X_train_scaled.min(axis=0))
print('Valeur Maximum: ', X_train_scaled.max(axis=0))
Moyenne:  [0.02783696 0.00715709 0.02415929 0.69871297 0.72454623]
Standard Deviation:  [0.030785   0.02933548 0.04728302 0.19726816 0.17431502]
Valeur Minimum:  [0. 0. 0. 0. 0.]
Valeur Maximum:  [1. 1. 1. 1. 1.]

Maintenant, la valeur maximale pour toutes les caractéristiques est de 1, et la valeur minimale est de zéro, comme prévu. Elles se situent donc dans une échelle plus proche.

 

Regression Logistique

Evaluons l’effet de la mise à l’échelle des varibles dans une régression logistique.

# création du modele avec les données de base


logit = LogisticRegression(
    random_state=44,
    C=1000,  
    solver='lbfgs')

# entrainement
logit.fit(X_train, y_train)

# Evaluation de la performance
print('Données d''entrainement')
pred = logit.predict_proba(X_train)
print('Logistic Regression roc-auc: {}'.format(
    roc_auc_score(y_train, pred[:, 1])))
print('Données de test')
pred = logit.predict_proba(X_test)
print('Logistic Regression roc-auc: {}'.format(
    roc_auc_score(y_test, pred[:, 1])))
Données d'entrainement
Logistic Regression roc-auc: 0.5030546422412567
Données de test
Logistic Regression roc-auc: 0.49464471672730204
# création du modele avec les données mises à l'échelle
logit = LogisticRegression(
    random_state=44,
    C=1000,  # c big to avoid regularization
    solver='lbfgs')

# entrainement
logit.fit(X_train_scaled, y_train)

# Evaluation de la performance
print('Données d''entrainement')
pred = logit.predict_proba(X_train_scaled)
print('Logistic Regression roc-auc: {}'.format(
    roc_auc_score(y_train, pred[:, 1])))
print('Données de test')
pred = logit.predict_proba(X_test_scaled)
print('Logistic Regression roc-auc: {}'.format(
    roc_auc_score(y_test, pred[:, 1])))
Données d'entrainement
Logistic Regression roc-auc: 0.575703811199905
Données de test
Logistic Regression roc-auc: 0.5667547891964408

Nous observons que la performance de la régression logistique a changé lorsque nous avons utilisé les ensembles de données avec les variables mises à l’échelle (comparer les valeurs roc-auc pour le train et l’ensemble de test pour les modèles avec et sans mise à l’échelle des variables).

Toutefois, en examinant les coefficients, nous constatons une grande différence dans les valeurs. Cela s’explique par le fait que l’ampleur de la variable a eu une incidence sur les coefficients. Après la mise à l’échelle, les trois variables ont relativement le même effet (coefficient) sur la survie, alors qu’avant la mise à l’échelle, nous serions enclins à penser que c’est la PClass qui est à l’origine du résultat de survie.

 

Support Vector Machines

# création du modele avec les données de base


SVM_model = SVC(random_state=44, probability=True, gamma='auto')

#  Entrainement
SVM_model.fit(X_train, y_train)

# évaluation de la performance
print('Données d''entrainement')
pred = SVM_model.predict_proba(X_train)
print('SVM roc-auc: {}'.format(roc_auc_score(y_train, pred[:, 1])))
print('Données de test')
pred = SVM_model.predict_proba(X_test)
print('SVM roc-auc: {}'.format(roc_auc_score(y_test, pred[:, 1])))

Données dentrainement
SVM roc-auc: 0.979215699165593
Données de test
SVM roc-auc: 0.5154215138057149
# création du modele avec les données mises à l'échelle

SVM_model = SVC(random_state=44, probability=True, gamma='auto')

#  Entrainement
SVM_model.fit(X_train_scaled, y_train)

# évaluation de la performance
print('Données d''entrainement')
pred = SVM_model.predict_proba(X_train_scaled)
print('SVM roc-auc: {}'.format(roc_auc_score(y_train, pred[:, 1])))
print('Données de test')
pred = SVM_model.predict_proba(X_test_scaled)
print('SVM roc-auc: {}'.format(roc_auc_score(y_test, pred[:, 1])))

Données dentrainement
SVM roc-auc: 0.5744963138792492
Données de test
SVM roc-auc: 0.567371078143071

La mise à l’échelle des variables a amélioré les performances de la machine à vecteurs de support. On peut voir que le modèle avec les données mises à l’échelle est beaucoup fiable que le premier. Au niveau de la différence entre les résultats de l’entrainement et de test.

 

K-Nearest Neighbours

# création du modele avec les données de base
KNN = KNeighborsClassifier(n_neighbors=5)

# entrainement
KNN.fit(X_train, y_train)

# évaluation de la performance
print('Données d''entrainement')
pred = KNN.predict_proba(X_train)
print('KNN roc-auc: {}'.format(roc_auc_score(y_train, pred[:,1])))
print('Données de test')
pred = KNN.predict_proba(X_test)
print('KNN roc-auc: {}'.format(roc_auc_score(y_test, pred[:,1])))

Données d'entrainement
KNN roc-auc: 0.7637437596574514
Données de test
KNN roc-auc: 0.5265399891970808
# création du modele avec les données mises à l'échelle
KNN = KNeighborsClassifier(n_neighbors=5)

# entrainement
KNN.fit(X_train_scaled, y_train)

# évaluation de la performance
print('Données d''entrainement')
pred = KNN.predict_proba(X_train_scaled)
print('KNN roc-auc: {}'.format(roc_auc_score(y_train, pred[:,1])))
print('Données de test')
pred = KNN.predict_proba(X_test_scaled)
print('KNN roc-auc: {}'.format(roc_auc_score(y_test, pred[:,1])))

Données d'entrainement
KNN roc-auc: 0.7594339572742086
Données de test
KNN roc-auc: 0.5288804261874279

Nous observons pour KNN que la mise à l’échelle des caractéristiques n’a pas amélioré les performances du modèle.

 

Random Forests

# création du modele avec les données de base
rf = RandomForestClassifier(n_estimators=200, random_state=39)

# entrainement
rf.fit(X_train, y_train)

# évaluation de la performance
print('Données d''entrainement')
pred = rf.predict_proba(X_train)
print('Random Forests roc-auc: {}'.format(roc_auc_score(y_train, pred[:, 1])))
print('Données de test')
pred = rf.predict_proba(X_test)
print('Random Forests roc-auc: {}'.format(roc_auc_score(y_test, pred[:, 1])))

Données d'entrainement
Random Forests roc-auc: 0.9988841257847125
Données de test
Random Forests roc-auc: 0.5464188002787643
# création du modele avec les données mises à l'échelle
rf = RandomForestClassifier(n_estimators=200, random_state=39)

# entrainement
rf.fit(X_train_scaled, y_train)

# évaluation de la performance
print('Données d''entrainement')
pred = rf.predict_proba(X_train_scaled)
print('Random Forests roc-auc: {}'.format(roc_auc_score(y_train, pred[:,1])))
print('Données de test')
pred = rf.predict_proba(X_test_scaled)
print('Random Forests roc-auc: {}'.format(roc_auc_score(y_test, pred[:,1])))

Données d'entrainement
Random Forests roc-auc: 0.9988834009493697
Données de test
Random Forests roc-auc: 0.5465474115384349

Comme prévu, Random Forests ne montre aucun changement de performance, qu’il soit formé sur un ensemble de données avec des variables à l’échelle ou non. Ce modèle, en particulier, est trop adapté à l’ensemble de formation. Nous devons donc faire des efforts pour supprimer ce sur-ajustement. Cela dépasse la portée de cette démonstration.

Si vous voulez découvrir comment fonctionne la librairie pandas ou bien l’environnement Jupyter, n’hésitez pas à consulter les cours ci-dessous.

GCH anime

Je télécharge mon guide gratuit

Vous recevrez votre guide par email sans aucun engagement de votre part.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.