Que faisons-nous de la variable après discrétisation ? Devons-nous les utiliser lcomme variable numérique ? ou devons-nous utiliser les intervalles comme variable catégorielle ?
La réponse est : vous pouvez faire l’un ou l’autre.
Si vous construisez des algorithmes basés sur des arbres de décision et que les résultats de la discrétisation sont des entiers (chaque entier se référant à un bac), alors vous pouvez les utiliser directement, car les arbres de décision détecteront des relations non linéaires entre la variable discrétisée et la cible.
Si vous construisez plutôt des modèles linéaires, les casiers n’auront pas nécessairement une relation linéaire avec la cible. Dans ce cas, il peut être utile d’améliorer les performances du modèle en traitant les casiers comme des catégories et en les soumettant à un codage à chaud, ou à des codages guidés par la cible comme le codage de la moyenne, le poids de la preuve ou le codage ordinal guidé par la cible.
Dans cette démo
Nous effectuerons une discrétisation à fréquence égale suivie d’un encodage guidé par la cible
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from feature_engine.discretisers import EqualFrequencyDiscretiser
from feature_engine.categorical_encoders import OrdinalCategoricalEncoder
data = pd.read_csv('../exportfeature.csv',usecols=['place', 'allocation', 'nAllocation', 'nbPartants'],sep=";",encoding='ANSI')
data.head()
place allocation nbPartants nAllocation
0 1 90000.0 17 95000
1 1 70000.0 18 58000
2 0 44000.0 12 37000
3 1 40000.0 11 38000
4 0 40000.0 16 34000
# Création d enotre jeu de test et d'entrainement
X_train, X_test, y_train, y_test = train_test_split(
data[['allocation', 'nAllocation', 'nbPartants']],
data['place'],
test_size=0.3,
random_state=0)
X_train.shape, X_test.shape
((14352, 3), (6152, 3))
# Explorons la distribution
data[['allocation', 'nAllocation', 'nbPartants']].hist(bins=30, figsize=(8,4))
plt.show()
Discrétisation à fréquence égale avec Feature-Engine
disc = EqualFrequencyDiscretiser(
q=10, variables=['allocation', 'nAllocation', 'nbPartants'], return_object=True)
#
disc.fit(X_train)
train_t = disc.transform(X_train)
test_t = disc.transform(X_test)
train_t.dtypes
allocation object
nAllocation object
nbPartants object
dtype: object
train_t.head()
allocation nAllocation nbPartants
2540 6 5 6
19008 6 5 7
7624 7 7 8
2575 6 2 3
852 0 5 6
# explorons si une relation linéaire existe
# avec la cible :
pd.concat([train_t, y_train], axis=1).groupby('allocation')['place'].mean().plot()
pd.concat([train_t, y_train], axis=1).groupby('nAllocation')['place'].mean().plot()
plt.ylabel('mean of survived')
pd.concat([train_t, y_train], axis=1).groupby('nbPartants')['place'].mean().plot()
plt.ylabel('mean of survived')
Avec le nombre de partants on peut voir que plus le nombre augmente plus la probabilité d’être à l’arrivée diminue. Par contre pour les allocations se sont les extrêmes qui augmentent les probabilité d’être à l’arrivée
Codage ordinal avec Feature-Engine
enc = OrdinalCategoricalEncoder(encoding_method = 'ordered')
enc.fit(train_t, y_train)
train_t = enc.transform(train_t)
test_t = enc.transform(test_t)
enc.encoder_dict_
{'allocation': {4: 0, 5: 1, 2: 2, 7: 3, 3: 4, 6: 5, 8: 6, 0: 7, 1: 8, 9: 9},
'nAllocation': {4: 0, 3: 1, 2: 2, 7: 3, 5: 4, 1: 5, 6: 6, 8: 7, 0: 8, 9: 9},
'nbPartants': {8: 0, 6: 1, 5: 2, 4: 3, 3: 4, 7: 5, 2: 6, 1: 7, 0: 8}}
pd.concat([train_t, y_train], axis=1).groupby('allocation')['place'].mean().plot()
pd.concat([train_t, y_train], axis=1).groupby('nAllocation')['place'].mean().plot()
plt.ylabel('Allocation')
pd.concat([train_t, y_train], axis=1).groupby('nbPartants')['place'].mean().plot()
plt.ylabel('mean of survived')
Nous avons maintenant obtenu une relation monotone entre les variables et la cible.
Je télécharge mon guide gratuit
Thank you!
You have successfully joined our subscriber list.
Vous recevrez votre guide par email sans aucun engagement de votre part.