Introduction
L'utilisation du machine learning s'est largement démocratisé ces derniers années et ses techniques sont de plus en plus répandues, notamment dans les processus de décisions. Aujourd'hui, les modèles les plus performants sont peu interprétables et il y a un manque de vision sur l'apprentissage que l'algorithme fait. Un enjeu important est de comprendre cet apprentissage ainsi que l'influence de chaque covariable discriminante. Par exemple, on a besoin de s'assurer que les règles générées par le modèle de ML sont alignées avec la connaissance métier. Il s'agit également d'une problématique de confiance car les utilisateurs du modèle pourraient demander des informations sur ses prédictions et il en va de la responsabilité du datascientist d'y répondre.
On va présenter rapidement ici un outil d'explicabilité que l'on nomme Accumulated Local Effects plot (ALE) et qui sert à déterminer l'effet individuel et isolé de chaque covariable du modèle sur l'output. L'idée est de regarder comment l'output d'un modèle évolue en faisant varier localement une feature.
Comparée à d'autres techniques qui ont un objectif similaire, cette méthode est :
- plus rapide en terme de calcul
- moins biaisée et plus robuste par rapport aux effets de corrélation
- plus intuitive
Accumulated Local Effects (ALE)
Sans rentrer dans le formalisme mathématique, l'idée des ALE est de décrire l'effet moyen d'une feature sur un modèle de machine learning.
Comme son nom l'indique il s'agit de définir une zone locale pour une certaine valeur que peut prendre une feature. On fait ensuite varier la valeur de cette feature sur la zone locale mais en gardant toutes les autres features constantes. On calcule ensuite les écarts entre les différentes prédictions. Ces écarts représentent les changements que prend le modèle autour de la valeur indiquée. On itère ensuite sur plusieurs valeurs différentes pour ainsi obtenir une image complète de l'effet du changement de cette feature.
Pour le dire autrement, les ALE répondent à la question suivante : Comment est ce que l'output du modèle M change sur une fenêtre autour de la valeur A pour la feature X ?
Si vous n'avez pas peur des maths et que vous souhaitez comprendre davantage cet outil je vous conseille fortement la lecture du chapitre sur les ALE de Interpretable Machine Learning
Dataset
Pour illustrer ce qu'on peut faire avec des ALE on va se donner un tâche simple de classification. Comme une des principales composantes de Gojob est les ressources humaines, on a choisi un jeu de données RH qu'on a récupéré de kaggle.com.
Kaggle est une plateforme en ligne où se retrouve une grande partie de la communauté datascience. Le site accueille des compétitions, des tutoriels, du partage de connaissances, etc.
Le jeu de données choisi représente une liste d'employés dans une entreprise tierce (au format CSV). Pour chaque employé on a plusieurs colonnes de données : Niveau d'études, Performance, Équilibre vie pro-perso, ... On essaiera dans notre classification de prédire si le dit employé décide de rester dans la boîte, ou à contrario, préfère s'en aller.
Classification
On commence simplement avec l'importation des données. Voyons d'abord l'ensemble des colonnes de notre dataset et les types associés:
import pandas as pd
hr_dataset = pd.read_csv('WA_Fn-UseC_-HR-Employee-Attrition.csv')
hr_dataset.info()
Notre dataset contient 35 colonnes avec des colonnes de types différents. Une des
colonnes qui ressort est Attrition
. Cette notion représente si un talent quitte l'entreprise où s'il y reste
travailler. Pour cet exercice on va utiliser un modèle très simple pour prédire cette variable d'attrition.
Pour simplifier l'exercice on va se restreindre à un certain nombre de variables prédictives.
VARIABLES_TO_KEEP = [
"Attrition",
"EmployeeNumber",
"EnvironmentSatisfaction",
"HourlyRate",
"JobInvolvement",
"JobLevel",
"JobSatisfaction",
"MonthlyRate",
"NumCompaniesWorked",
"RelationshipSatisfaction",
"TotalWorkingYears",
"YearsAtCompany",
"YearsInCurrentRole",
]
hr_dataset = hr_dataset.loc[:, VARIABLES_TO_KEEP]
Pour se faire une idée rapide des interactions dans nos données, on affiche une carte de corrélation. Dans un vrai projet on aurait évidemment fait davantage d'exploration. Ce n'est cependant pas le sujet ici.
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
plt.figure(figsize = (20,10))
sns.heatmap(hr_dataset.corr(), cmap="YlGnBu", annot = True)
plt.title('Correlation Heatmap', fontdict={'fontsize':18}, pad=12)
On peut voir que certaines featues ont des interactions assez fortes.
TotalWorkingYears
a une corrélation de 0.78 avecJobLevel
YearsAtCompany
a une corrélation de 0.76 avecYearsInCurrentRole
TotalWorkingYears
a une corrélation de 0.63 avecYearsAtCompany
On pointe une grande attention à ces importantes corrélations. Les fortes corrélations dans un dataset d'entraînement peuvent entraîner plusieurs problèmes. Parmis eux, un problème d'explicabilité: En voulant prédire si un talent reste, comme le nombre d'année de travail est corrélé avec le niveau du poste, on aura du mal à déterminer si l'effet vient de la première ou de la seconde. Ou alors est ce l'effet commun des deux combinées ?
On va entraîner un classifieur XGBoost à prédire si un talent restera :
import xgboost as xgb
X = hr_dataset.drop("Attrition", axis = 1)
y = hr_dataset["Attrition"].map({'Yes' : 1, 'No': 0})
xgb_model = xgb.XGBClassifier()
xgb_model.fit(X, y)
from PyALE import ale
ale_eff = ale(
X=X,
model=xgb_model,
feature=["TotalWorkingYears"],
feature_type="continuous",
include_CI=False,
)
plt.show()
On obtient un graphe où on peut voir en fonction de notre variable TotalWorkingYears
l'influence qu'elle a
sur l'output du modèle. Chaque ligne représente un changement dans la prédiction du modèle autour d'une valeur
par rapport à l'effet moyen prédit.
En particulier, on peut voir que la relation avec la variable target n'est pas très complexe et ne fait pas beaucoup de variation. En effet, on voit plus ou moins une courbe qui descend avec quelques brisures. On peut également remarquer que la valeur la plus haute est au début (pour des valeurs faibles) et chute très rapidement. Notre modèle a donc appris qu'un employé a le plus de chance de quitter l'entreprise au début de son expérience et qu'au contraire plus la personne est expérimentée moins elle est sujette à changer de travail. On remarque également cela à travers un effet décroissant assez lent qui fait sens.
Disclaimer : Évidemment cette analyse ne doit pas servir de règle générale. Elle est réalisée sur un jeu de données extérieur récupéré sur internet. On ne connaît pas son contexte particulier et on ne voudrait pas faire de généralité ici.
Librairies
A Gojob, la plupart de la stack datascience est en python. On a donc utilisé une implémentation python à travers la libraire PyALE. Mais d'autres implémentation des ALE existent, notamment dans la librairie Alibi Explain. Personnellement, je ne saurais en recommander une plutôt que l'autre.
Enfin pour les utilisateurs de R, il est possible d'utiliser les ALE à travers la lib ALEPlot ou encore iml
Conclusion
On a donné une méthode d'explicabilité relativement simple et très efficace. Le fait que la méthode soit robuste aux effets de fortes corrélations lui donne un avantage conséquent. Les ALE constituent un outil important à garder dans sa tool-box de data scientist quand on veut faire de l'explicabilité. Un autre point intéressant qu'on a pas mentionné est le fait qu'elle soit model agnostique (utilisable sur n'importe quelle modèle de ML quelque soit son design et pour à peu près n'importe quelle tâche)
Il existe de nombreux outils d'expliquabilité que l'on pas mentionné et qui valent également le coup. Mon favori étant SHAP mais nécessitant un peu plus de technicité et d'initiation.
Le lecteur intéressé pourra consulter le livre "Interpretable Machine Learning : A Guide for Making Black Box Models Explainable" de Christoph Molnar. [^1] Il m'a été précieux pour la compréhension du problème et des différentes méthodes.