Les valeurs d’une variable catégorielle sont sélectionnées à partir d’un groupe de catégories, également appelées labels. Par exemple, dans la variable sexe, les catégories ou labels sont masculins et féminins, alors que dans la variable Ville, les labels peuvent être Montpellier, Le Lude, Grenoble, etc.
Les différentes variables catégorielles contiennent un nombre différent d’étiquettes ou de catégories. La variable “Sexe” ne contient que deux étiquettes, mais une variable comme “ville” ou “code postal” peut contenir un très grand nombre d’étiquettes différentes.
Le nombre d’étiquettes différentes dans une variable catégorielle est connu sous le nom de cardinalité. Un nombre élevé d’étiquettes dans une variable est connu sous le nom de cardinalité élevée.
La présence de plusieurs étiquettes dans une variable catégorielle pose-t-elle un problème ?
Une cardinalité élevée peut poser les problèmes suivants :
Les variables ayant trop d’étiquettes ont tendance à dominer celles qui n’en ont que quelques unes, en particulier dans les algorithmes basés sur l’arbre.
Un grand nombre d’étiquettes dans une variable peut introduire du bruit avec peu ou pas d’information, ce qui rend les modèles d’apprentissage machine enclins à se surajuster.
Certaines étiquettes peuvent n’être présentes que dans l’ensemble des données de formation, mais pas dans l’ensemble de test, ce qui fait que les algorithmes d’apprentissage automatique peuvent être trop adaptés à l’ensemble de formation.
Au contraire, certaines étiquettes peuvent n’apparaître que dans l’ensemble de test, laissant ainsi les algorithmes d’apprentissage automatique incapables d’effectuer un calcul sur la nouvelle observation (invisible).
En particulier, les méthodes arborescentes peuvent être biaisées vers des variables avec beaucoup d’étiquettes (variables à haute cardinalité). Ainsi, leurs performances peuvent être affectées par une cardinalité élevée.
Je montrerai ci-dessous l’effet de la haute cardinalité des variables sur les performances de différents algorithmes d’apprentissage machine, et comment une solution rapide pour réduire le nombre d’étiquettes, sans aucune sorte d’aperçu des données, contribue déjà à améliorer les performances.
Dans cette démo :
Nous ferons :
- Apprendre à quantifier la cardinalité
- Voir des exemples de variables à cardinalité élevée et faible
- Comprendre l’effet de la cardinalité lors de la préparation des trains et des jeux d’essai
- Visualiser l’effet de la cardinalité sur les performances du modèle d’apprentissage machine
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# to build machine learning models
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
# to evaluate the models
from sklearn.metrics import roc_auc_score
# to separate data into train and test
from sklearn.model_selection import train_test_split
data = pd.read_csv('../exportfeature.csv',parse_dates=['date'],infer_datetime_format=True,dayfirst=True,sep=";",encoding='ANSI')
data.head()
id place rapport date M1 M2 M3 M4 allocation Hippodrome nbPartants idHippodrome nDistance nAllocation idFerrure idJockey nbPartants.1 rPoids idOeillere iCote
0 56005 1 1.3 2016-01-01 3a 3m Da 3a 90000.0 Vincennes 17 Vincennes 2100 95000 0 18 17 0 0 12.0
1 98833 1 2.2 2016-01-01 3a 9Da 5a 4a 70000.0 Vincennes 18 Vincennes 2700 58000 1 30 18 0 0 12.0
2 98834 0 0.0 2016-01-01 1a Da Da 1a 44000.0 Vincennes 12 Vincennes 2850 37000 0 53 10 0 0 9.0
3 98835 1 1.5 2016-01-01 Da 7a 4a 2a 40000.0 Vincennes 11 Vincennes 2200 38000 2 143 13 0 0 4.0
4 98836 0 0.0 2016-01-01 1a 7a 10a 11a 40000.0 Vincennes 16 Vincennes 2700 34000 0 50 17 0 0 8.0
Les variables catégorielles de cet ensemble de données sont hippodrome, idHippodrome, idJockey,idFerrure, idOeillere
Notez que M1 à M4 contiennent à la fois des lettres et des chiffres, ils peuvent donc être traités comme des variables mixtes. Pour cette démonstration, je les traiterai comme des variables catégorielles.
# inspectons la cardinalité, voici le nombre
# Nombre d'étiquettes différentes, pour les différentes variables catégorielles
print('Nombre de catégorie de la variable Hippodrome: {}'.format(
len(data.Hippodrome.unique())))
print('Nombre de catégorie de la variable idHippodrome: {}'.format(
len(data.idHippodrome.unique())))
print('Nombre de catégorie de la variable idJockey: {}'.format(
len(data.idHippodrome.unique())))
print('Nombre de catégorie de la variable idFerrure: {}'.format(
len(data.idFerrure.unique())))
print('Nombre de catégorie de la variable idOeillere: {}'.format(
len(data.idOeillere.unique())))
print('Nombre de catégorie de la variable M1: {}'.format(
len(data.M1.unique())))
print('Nombre de catégorie de la variable M2: {}'.format(
len(data.M2.unique())))
print('Nombre de catégorie de la variable M3: {}'.format(
len(data.M3.unique())))
print('Nombre de catégorie de la variable M4: {}'.format(
len(data.M4.unique())))
print('Taille de notre dataframe: {}'.format(len(data)))
Nombre de catégorie de la variable Hippodrome: 199
Nombre de catégorie de la variable idHippodrome: 303
Nombre de catégorie de la variable idJockey: 303
Nombre de catégorie de la variable idFerrure: 4
Nombre de catégorie de la variable idOeillere: 1
Nombre de catégorie de la variable M1: 67
Nombre de catégorie de la variable M2: 71
Nombre de catégorie de la variable M3: 72
Nombre de catégorie de la variable M4: 70
Taille d enotre dataframe: 20504
Alors que la variable idFerreur ne contient que 4 catégories, toutes les variables, comme prévu, contiennent un grand nombre d’étiquettes différentes (haute cardinalité). On peut remarquer aussi que la variable idOeillere ne comporte qu’une seule cardinalité. Cela indique qu’il y a tjs la même valeur dans la colonne. On pourra donc à l’avenir la supprimer
Pour démontrer l’effet de la haute cardinalité sur les performances de l’entrainement, des tests , je vais travailler avec la variable M1. Je vais créer une nouvelle variable avec une cardinalité réduite.
# explorons les valeurs / catégories de M1
# nous savons, grâce à la cellule précédente, qu'il y a 67 valeurs
# différentes , donc la variable
# est hautement cardinal
data.M1.unique()
array(['3a', '1a', 'Da', '8a', '2a', '9a', '4a', '5a', '10a', 'Aa', 'Dm',
'13a', '7a', '6m', '11a', '6a', '2Da', '0a', '1Disqa', '10m', '3m',
'3Da', '14a', '5m', '4Dista', '1m', '1Dista', '2Dm', '4Da', '15a',
'1Da', '10Dista', '3Dista', '5Da', '4m', '6Da', '12a', '0m', '2m',
'7Da', '8m', '2Dista', 'Rpa', '9m', '7m', '4Disqa', 'Dista',
'7Dista', '4Distm', '2Dpga', '6Dista', '5Dista', '1Dpga', '1Dm',
'Am', 'Ta', '16a', '17a', '8Dista', '2Disqa', 'Dpga', '12m', '3Dm',
'11m', '3Dpga', '9Da', '8Dm'], dtype=object)
Réduisons maintenant la cardinalité de la variable. Comment ? Au lieu d’utiliser toute la valeur de la cabine, je vais supprimer la dernière lettre
Justification : la dernière lettre indique la spécialité de la dernière course. Le reste indique la position à l’arrivé
data['M1_reduite'] = data['M1'].astype(str).str[0:-1]
data[['M1', 'M1_reduite']].head()
M1 M1_reduite
0 3a 3
1 3a 3
2 1a 1
3 Da D
4 1a 1
print('Nombre de catégorie de la variable M1: {}'.format(
len(data.M1.unique())))
print('Nombre de catégorie de la variable M1 réduite: {}'.format(
len(data.M1_reduite.unique())))
Nombre de catégorie de la variable M1: 67
Nombre de catégorie de la variable M1 réduite: 48
Nous avons réduit les différents label de 67 à 48. C’est pas mal mais on peut encore mieux faire. On peut changer les catégories des chevaux disqualifié ou pour le moins tout ceux qui ne sont pas dans le classement de l’arrivée.
def uniquement_place(M1_reduite):
position=M1_reduite
if len(position)>2:
position="NP"
return position
data['M1_reduite']=data['M1_reduite'].apply(uniquement_place)
pd.set_option('display.max_rows', None)
data[['M1', 'M1_reduite']].head(150)
M1 M1_reduite
0 3a 3
1 3a 3
2 1a 1
3 Da D
4 1a 1
5 8a 8
6 2a 2
7 9a 9
8 1a 1
9 4a 4
10 Da D
11 5a 5
12 9a 9
13 2a 2
14 1a 1
15 1a 1
16 4a 4
17 1a 1
18 Da D
19 Da D
20 1a 1
21 10a 10
22 2a 2
23 1a 1
24 2a 2
25 Da D
26 2a 2
27 1a 1
28 3a 3
29 1a 1
30 2a 2
31 Da D
32 Aa A
33 1a 1
34 Da D
35 5a 5
36 3a 3
37 1a 1
38 1a 1
39 2a 2
40 2a 2
41 1a 1
42 Da D
43 Dm D
44 8a 8
45 Da D
46 5a 5
47 1a 1
48 1a 1
49 1a 1
50 2a 2
51 1a 1
52 Da D
53 13a 13
54 2a 2
55 4a 4
56 1a 1
57 3a 3
58 7a 7
59 2a 2
60 6m 6
61 4a 4
62 1a 1
63 1a 1
64 11a 11
65 1a 1
66 1a 1
67 6a 6
68 3a 3
69 1a 1
70 3a 3
71 2Da 2D
72 2a 2
73 3a 3
74 Da D
75 2a 2
76 1a 1
77 1a 1
78 1a 1
79 3a 3
80 0a 0
81 4a 4
82 Da D
83 Da D
84 1a 1
85 Da D
86 1a 1
87 6a 6
88 1a 1
89 Da D
90 2a 2
91 1Disqa NP
92 3a 3
93 1a 1
94 1a 1
95 1a 1
96 1a 1
97 2a 2
98 10a 10
99 1a 1
100 1a 1
101 4a 4
102 7a 7
103 4a 4
104 Da D
105 1a 1
106 1a 1
107 1a 1
108 3a 3
109 2a 2
110 3a 3
111 2a 2
112 1a 1
113 Da D
114 1a 1
115 10a 10
116 1a 1
117 5a 5
118 5a 5
119 2a 2
120 1a 1
121 2a 2
122 1a 1
123 1a 1
124 3a 3
125 1a 1
126 1a 1
127 2a 2
128 2a 2
129 9a 9
130 0a 0
131 1a 1
132 1a 1
133 1a 1
134 2a 2
135 1a 1
136 2a 2
137 2a 2
138 5a 5
139 1a 1
140 2a 2
141 1a 1
142 1a 1
143 3a 3
144 3a 3
145 1a 1
146 1a 1
147 8a 8
148 10m 10
149 Da D
print('Nombre de catégorie de la variable M1 réduite: {}'.format(
len(data.M1_reduite.unique())))
Nombre de catégorie de la variable M1 réduite: 32
# Séparons-nous en un ensemble de formation et de tests
# afin de construire des modèles d'apprentissage machine
use_cols = ['M1', 'M1_reduite', 'nbPartants']
# this functions comes from scikit-learn
X_train, X_test, y_train, y_test = train_test_split(
data[use_cols],
data['place'],
test_size=0.3,
random_state=0)
X_train.shape, X_test.shape
((14352, 3), (6152, 3))
Une cardinalité élevée entraîne une répartition inégale des catégories dans les ensembles d’entrainement et de test
Lorsqu’une variable est très cardinale, il arrive souvent que certaines catégories ne soient présentes que sur le jeu d’entraînement, ou seulement sur le jeu de test. Si elles ne sont présentes que dans l’ensemble de formation, elles peuvent conduire à un surajustement. Si elles ne sont présentes que sur le banc d’essai, l’algorithme d’apprentissage automatique ne saura pas comment les traiter, car il ne les a pas vues pendant la formation.
# Découvrons les étiquettes présentes uniquement dans l'ensemble d'entrainement
unique_to_train_set = [
x for x in X_train.M1.unique() if x not in X_test.M1.unique()
]
len(unique_to_train_set)
Il y a 14 categories de M1 présente dans l’ensemble d’entrainement et pas dans celui de test
# Découvrons les étiquettes présentes uniquement dans l'ensemble de test
unique_to_test_set = [
x for x in X_test.M1.unique() if x not in X_train.M1.unique()
]
len(unique_to_test_set)
4
Les variables à forte cardinalité ont tendance à avoir des valeurs (c’est-à-dire des catégories) présentes dans l’ensemble de formation, qui ne sont pas présentes dans l’ensemble de test, et vice versa. Cela entraîne des problèmes au moment de la formation (en raison d’un surajustement) et de la notation des nouvelles données (comment le modèle doit-il traiter les catégories non vues ?).
Ce problème est presque surmonté par la réduction de la cardinalité de la variable. Voir ci-dessous.
# Découvrons les étiquettes présentes uniquement dans l'ensemble de formation
# pour M1 à cardinalité réduite
unique_to_train_set = [
x for x in X_train['M1_reduite'].unique()
if x not in X_test['M1_reduite'].unique()
]
len(unique_to_train_set)
-> 2
# Découvrons les étiquettes présentes uniquement dans l'ensemble de test
# pour M1 à cardinalité réduite
unique_to_test_set = [
x for x in X_test['M1_reduite'].unique()
if x not in X_train['M1_reduite'].unique()
]
len(unique_to_test_set)
-> 2
Observez comment, en réduisant la cardinalité, il n’y a plus que deux étiquettes dans l’ensemble d’entrainement qui ne sont pas présente dans l’ensemble de test.
Effet de la cardinalité sur les performances du modèle d’apprentissage machine
Afin d’évaluer l’effet des variables catégorielles dans les modèles d’apprentissage machine, je vais rapidement remplacer les catégories par des nombres. Voir ci-dessous.
# Réorganisons M1 en chiffres afin de pouvoir l'utiliser pour former les modèles ML
# Je remplacerai chaque M1 par un numéro
# pour démontrer rapidement l'effet de
# étiquettes sur les algorithmes d'apprentissage machine
##############
# Note : ce n'est ni le seul ni le meilleur
# comment encoder les variables catégorielles en chiffres
# nous verrons plus loin d'autres techniques
##############
M1_dict = {k: i for i, k in enumerate(X_train.M1.unique(), 0)}
M1_dict
{'5a': 0,
'1a': 1,
'7a': 2,
'2a': 3,
'6a': 4,
'4a': 5,
'10a': 6,
'3a': 7,
'0a': 8,
'Da': 9,
'Dm': 10,
'8a': 11,
'9m': 12,
'9a': 13,
'12a': 14,
'3Dista': 15,
'3Da': 16,
'11a': 17,
'2Da': 18,
'1m': 19,
'4Da': 20,
'3m': 21,
'11m': 22,
'Aa': 23,
'6Dista': 24,
'1Dista': 25,
'14a': 26,
'5m': 27,
'13a': 28,
'17a': 29,
'15a': 30,
'1Da': 31,
'6m': 32,
'4m': 33,
'2m': 34,
'0m': 35,
'2Dpga': 36,
'5Da': 37,
'2Dista': 38,
'8Dista': 39,
'12m': 40,
'2Dm': 41,
'7m': 42,
'Am': 43,
'5Dista': 44,
'Dista': 45,
'10m': 46,
'2Disqa': 47,
'6Da': 48,
'7Dista': 49,
'1Dm': 50,
'1Disqa': 51,
'3Dpga': 52,
'4Dista': 53,
'Ta': 54,
'3Dm': 55,
'4Distm': 56,
'10Dista': 57,
'8m': 58,
'1Dpga': 59,
'7Da': 60,
'16a': 61,
'Rpa': 62}
# remplacer les étiquettes, en utilisant le dic créé ci-dessus
X_train.loc[:, 'M1_mapped'] = X_train.loc[:, 'M1'].map(M1_dict)
X_test.loc[:, 'M1_mapped'] = X_test.loc[:, 'M1'].map(M1_dict)
X_train[['M1_mapped', 'M1']].head(10)
M1_mapped M1
2540 0 5a
19008 1 1a
7624 2 7a
2575 3 2a
852 4 6a
4855 1 1a
8154 1 1a
18928 1 1a
18286 4 6a
15712 5 4a
# Maintenant, je vais remplacer les lettres dans la variable réduite de M1
# avec la même procédure
# créer un dictionnaire de remplacement
M1_dict = {k: i for i, k in enumerate(X_train['M1_reduite'].unique(), 0)}
# On remplace les étiquettes par le dict
X_train.loc[:, 'M1_reduite'] = X_train.loc[:, 'M1_reduite'].map(
M1_dict)
X_test.loc[:, 'M1_reduite'] = X_test.loc[:, 'M1_reduite'].map(M1_dict)
X_train[['M1_reduite', 'M1']].head(20)
M1_reduite M1
2540 0 5a
19008 1 1a
7624 2 7a
2575 3 2a
852 4 6a
4855 1 1a
8154 1 1a
18928 1 1a
18286 4 6a
15712 5 4a
4842 6 10a
18034 3 2a
1215 1 1a
14732 1 1a
17160 1 1a
6969 3 2a
8964 1 1a
4446 1 1a
3669 3 2a
7129 1 1a
# vérifier s'il y a des valeurs manquantes dans ces variables
X_train[['M1_mapped', 'M1_reduite', 'nbPartants']].isnull().sum()
M1_mapped 4
M1_reduite 2
nbPartants 0
dtype: int64
Dans l’ensemble de test, il y a maintenant 4 valeurs manquantes pour la variable hautement cardinale. Ces valeurs ont été introduites lors de l’encodage des catégories en chiffres.
Comment ?
De nombreuses catégories n’existent que dans la série de tests. Ainsi, lorsque nous avons créé notre dictionnaire d’encodage en utilisant uniquement la série de trains, nous n’avons pas généré de nombre pour remplacer les étiquettes présentes uniquement dans la série de tests. Par conséquent, elles ont été encodées en tant que NaN. Nous verrons dans les prochains cahiers comment résoudre ce problème. Pour l’instant, je vais remplir ces valeurs manquantes avec 0.
# vérifions le nombre de catégories différentes dans les variables codées
len(X_train.M1_mapped.unique()), len(X_train.M1_reduite.unique())
(63, 30)
De ce qui précède, nous constatons immédiatement que sur les 67 cabines originales de l’ensemble de données, seules 63 sont présentes dans l’ensemble de formation.
Allons de l’avant et évaluons l’effet des étiquettes dans les algorithmes d’apprentissage machine.
Random Forests
# modèle construit sur des données à haute cardinalité pour M1
# appeler le modèle
rf = RandomForestClassifier(n_estimators=200, random_state=39)
# Entrainement du modèle
rf.fit(X_train[['M1_mapped', 'nbPartants']], y_train)
# création des prédictions
pred_train = rf.predict_proba(X_train[['M1_mapped', 'nbPartants']])
pred_test = rf.predict_proba(X_test[['M1_mapped', 'nbPartants']].fillna(0))
print('Entrainement')
print('Random Forests roc-auc: {}'.format(roc_auc_score(y_train, pred_train[:,1])))
print('Test')
print('Random Forests roc-auc: {}'.format(roc_auc_score(y_test, pred_test[:,1])))
Entrainement
Random Forests roc-auc: 0.6126443489995196
Test
Random Forests roc-auc: 0.5703193792960399
Nous observons que les performances des Random Forests sur le banc d’entraînement sont tout à fait supérieures à celles du banc d’essai. Cela indique que le modèle est sur entrainé, ce qui signifie qu’il fait un excellent travail de prédiction du résultat sur l’ensemble de données sur lequel il a été formé, mais qu’il n’a pas la puissance nécessaire pour généraliser la prédiction sur de nouvelles données.
# modèle construit sur des données à faible cardinalité pour M1
# appeler le modèle
rf = RandomForestClassifier(n_estimators=200, random_state=39)
# Entrainement du modèle
rf.fit(X_train[['M1_reduite', 'nbPartants']], y_train)
# création des prédictions
pred_train = rf.predict_proba(X_train[['M1_reduite', 'nbPartants']])
pred_test = rf.predict_proba(X_test[['M1_reduite', 'nbPartants']].fillna(0))
print('Entrainement')
print('Random Forests roc-auc: {}'.format(roc_auc_score(y_train, pred_train[:,1])))
print('Test')
print('Random Forests roc-auc: {}'.format(roc_auc_score(y_test, pred_test[:,1])))
Entrainement
Random Forests roc-auc: 0.6049508585145702
Test
Random Forests roc-auc: 0.5693662589533326
Nous pouvons maintenant constater que les Random Forests ne sont plus trop adaptées à l’entraînement. En outre, le modèle est bien meilleur pour généraliser les prédictions (comparer le roc-auc de ce modèle sur l’ensemble de test et le roc-auc du modèle ci-dessus également sur l’ensemble de test : 0,57 contre 0,61).
Je voudrais souligner que nous pouvons probablement surmonter l’effet de la cardinalité élevée en ajustant les hyperparamètres des forêts aléatoires. Cela dépasse le cadre de ce cours. Ici, je veux vous montrer qu’avec un même modèle, avec des hyperparamètres identiques, une cardinalité élevée peut entraîner un surajustement du modèle.
AdaBoost
# modèle construit sur des données à haute cardinalité pour M1
# appeler le modèle
ada = AdaBoostClassifier(n_estimators=200, random_state=44)
# Entrainement du modèle
ada.fit(X_train[['M1_mapped', 'nbPartants']], y_train)
# création des prédictions
pred_train = ada.predict_proba(X_train[['M1_mapped', 'nbPartants']])
pred_test = ada.predict_proba(X_test[['M1_mapped', 'nbPartants']].fillna(0))
print('Entrainement')
print('AdaBoost roc-auc: {}'.format(roc_auc_score(y_train, pred_train[:,1])))
print('Test')
print('AdaBoost roc-auc: {}'.format(roc_auc_score(y_test, pred_test[:,1])))
Entrainement
AdaBoost roc-auc: 0.5895832815827019
Test
AdaBoost roc-auc: 0.5842923634665107
# modèle construit sur des données à haute cardinalité pour M1 réduite
# appeler le modèle
ada = AdaBoostClassifier(n_estimators=200, random_state=44)
# Entrainement du modèle
ada.fit(X_train[['M1_reduite', 'nbPartants']], y_train)
# création des prédictions
pred_train = ada.predict_proba(X_train[['M1_reduite', 'nbPartants']])
pred_test = ada.predict_proba(X_test[['M1_reduite', 'nbPartants']].fillna(0))
print('Entrainement')
print('AdaBoost roc-auc: {}'.format(roc_auc_score(y_train, pred_train[:,1])))
print('Test')
print('AdaBoost roc-auc: {}'.format(roc_auc_score(y_test, pred_test[:,1])))
Entrainement
AdaBoost roc-auc: 0.5870471218982631
Test
AdaBoost roc-auc: 0.5819099091989577
Entre les deux modèles on ne voit pas de différences flagrantes
Logistic Regression
# modèle construit sur des données à haute cardinalité pour M1
# appeler le modèle
logit = LogisticRegression(random_state=44, solver='lbfgs')
# Entrainement du modèle
logit.fit(X_train[['M1_mapped', 'nbPartants']], y_train)
# création des prédictions
pred_train = logit.predict_proba(X_train[['M1_mapped', 'nbPartants']])
pred_test = logit.predict_proba(X_test[['M1_mapped', 'nbPartants']].fillna(0))
print('Entrainement')
print('Logistic Regression roc-auc: {}'.format(roc_auc_score(y_train, pred_train[:,1])))
print('Test')
print('Logistic Regression roc-auc: {}'.format(roc_auc_score(y_test, pred_test[:,1])))
Entrainement
Logistic Regression roc-auc: 0.5743783714148762
Test
Logistic Regression roc-auc: 0.5680422348285903
# modèle construit sur des données à haute cardinalité pour M1
# appeler le modèle
logit = LogisticRegression(random_state=44, solver='lbfgs')
# Entrainement du modèle
logit.fit(X_train[['M1_reduite', 'nbPartants']], y_train)
# création des prédictions
pred_train = logit.predict_proba(X_train[['M1_reduite', 'nbPartants']])
pred_test = logit.predict_proba(X_test[['M1_reduite', 'nbPartants']].fillna(0))
print('Entrainement')
print('Logistic Regression roc-auc: {}'.format(roc_auc_score(y_train, pred_train[:,1])))
print('Test')
print('Logistic Regression roc-auc: {}'.format(roc_auc_score(y_test, pred_test[:,1])))
Entrainement
Logistic Regression roc-auc: 0.5755345915325598
Test
Logistic Regression roc-auc: 0.5716232479248637
On peut voir une légère amélioration sur le test
Gradient Boosted Classifier
# modèle construit sur des données à haute cardinalité pour M1
# appeler le modèle
gbc = GradientBoostingClassifier(n_estimators=300, random_state=44)
# Entrainement du modèle
gbc.fit(X_train[['M1_mapped', 'nbPartants']], y_train)
# création des prédictions
pred_train = gbc.predict_proba(X_train[['M1_mapped', 'nbPartants']])
pred_test = gbc.predict_proba(X_test[['M1_mapped', 'nbPartants']].fillna(0))
print('Entrainement')
print('Gradient Boosted roc-auc: {}'.format(roc_auc_score(y_train, pred_train[:,1])))
print('Test')
print('Gradient Boosted roc-auc: {}'.format(roc_auc_score(y_test, pred_test[:,1])))
Entrainement
Gradient Boosted roc-auc: 0.6026729948840729
Test
Gradient Boosted roc-auc: 0.5809900080995234
# modèle construit sur des données à haute cardinalité pour M1
# appeler le modèle
gbc = GradientBoostingClassifier(n_estimators=300, random_state=44)
# Entrainement du modèle
gbc.fit(X_train[['M1_reduite', 'nbPartants']], y_train)
# création des prédictions
pred_train = gbc.predict_proba(X_train[['M1_reduite', 'nbPartants']])
pred_test = gbc.predict_proba(X_test[['M1_reduite', 'nbPartants']].fillna(0))
print('Entrainement')
print('Gradient Boosted roc-auc: {}'.format(roc_auc_score(y_train, pred_train[:,1])))
print('Test')
print('Gradient Boosted roc-auc: {}'.format(roc_auc_score(y_test, pred_test[:,1])))
Entrainement
Gradient Boosted roc-auc: 0.598521098859783
Test
Gradient Boosted roc-auc: 0.5764933062958197
Les arbres Gradient Boosted sont en effet trop adaptés à l’ensemble de formation dans les cas où la variable M1 a beaucoup d’étiquettes. C’était prévisible, car les méthodes d’arborescence ont tendance à être biaisées en faveur de variables comportant de nombreuses catégories.
D’une manière générale, vous vous rendrez compte que travailler sur des vrais données de turf, est toujours assez frustrant par rapport à des données plus usuelles. En effet, on a une part d’incertitude beaucoup plus importante que sur d’autres jeux de données.
Après c’est aussi ce qui fait l’interêt de travailler sur de tels jeux de données.
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.