Comment l'IA peut-elle changer le recrutement ? (partie 3)

le 04/11/2021 par Antoine BRES
Tags: Data & AI, Data Science

Dans la deuxième partie de l’article, nous avons vu une façon d’employer l'IA qui a le potentiel d’apporter la flexibilité nécessaire à une détection intelligente de mots-clés.

Dans cette troisième partie, nous allons vous présenter notre implémentation d’une solution de tri par mots-clés grâce à l’IA, ce que nous avons appris, les pistes que nous avons explorées et les challenges que nous avons rencontrés.

Implémentation d'une solution logicielle

Traiter l’information d’une façon qui pallie les lacunes des ATS n’est qu’une partie du problème. Avant d'entraîner un modèle, nous avons besoin de données. Dans notre cas, elles sont contenues dans les CVs. Tels qu’ils nous parviennent, ils sont inexploitables par l’ordinateur.

Il faut donc extraire et transformer cette information.

Extraire l’information

Cette partie n'est pas la plus difficile techniquement parlant. Les CVs sont souvent récupérés au format PDF et il existe des bibliothèques capables d'extraire (parser) le texte des pdf (e.g. Pdfminer.six). C’est ce que nous avions choisi en première approche. Cela permet de récupérer le texte contenu dans le fichier pdf, ici le CV.

Cependant, récupérer uniquement le texte s’est avéré sous-optimal.

Evidemment, avec ces bibliothèques, on ne traite pas les images. Dans la majorité des CVs, celles-ci ne sont pas essentielles. Les cas que nous avons identifiés où les images apportent de l’information pour notre cas d’usage sont :

  • Le logo de l’entreprise, qui prend parfois la place du nom. e.g.

  • La grille de compétence qui renseigne les compétences maîtrisées ainsi que leur degré de maîtrise par le candidat. e.g.

  • Le cas où tout le CV est une image.

Ce qui est moins évident en revanche, c’est que la structure du CV est souvent porteuse d’informations.

Les CVs comportent beaucoup de phrases nominales sans ponctuation. Elles reposent donc énormément sur la structure textuelle du CV pour être compréhensibles. Et même si souvent, leur format est commun (avec un sens de lecture des différentes parties dextroverse de haut en bas) certains sortent du lot. Nous avons vu par exemple un CV avec des sections organisées radialement.

Le résultat est qu’un CV parsé était difficilement compréhensible.

Concrètement, dans un document PDF, la structure est portée par 2 éléments : les objets "bloc de texte" et les caractères d'espaces (whitespace characters, e.g. tabs, space, new line) au sein des blocs de texte. Les bibliothèques de parsing de PDF identifient les blocs de texte et y capturent les caractères contenus.

Ainsi, il y a 2 sources de problèmes. Premièrement, les blocs de textes peuvent être "mal" définis (e.g. des blocs de texte qui se chevauchent pour arriver à une certaine mise en page). Deuxièmement, les caractères d'espace peuvent être mal définis ou mal capturés.

Non seulement les informations portées par la structure sont altérées voire perdues mais parfois le texte est dans le désordre. Or, pour espérer tirer parti des avancés en NLP, il est impératif de conserver l'ordre des mots tels qu'ils apparaissent.

D'autre part, puisqu’on récupère tout le texte contenu dans le pdf, on reste vulnérable aux attaques de keyword stuffing/bombing (attaque qui consiste à ajouter des mots-clés, parfois de façon invisible, pour augmenter ses chances de passer le tri effectué par les ATS).

Voilà pourquoi l'emploi des bibliothèques de parsing de PDF n'est pas idéal dans notre cas.

Pour adresser ces inconvénients liés au simple parsing, nous avons décidé d’utiliser de la reconnaissance optique de caractères (optical character recognition ou OCR).

Cela nécessite de transformer le pdf en image. L’OCR fonctionne en “regardant” les pixels de l’image pour déterminer les zones de textes et leur contenu. On obtient alors le texte tel qu'il nous apparait (à nous humains). On conserve ainsi la structure textuelle du pdf, on est partiellement protégé du keyword stuffing et on peut extraire l'information des images. En revanche, cette solution demande un temps de calcul considérablement plus important que pour le parsing et n'est pas aussi fiable que le parsing. Dans notre cas, ce n’est pas un problème.

Idéalement, nous aurions développé une solution hybride qui se base sur l’OCR, avec une logique de traitement pour les grilles de compétences, et qui corrige le texte obtenu par OCR grâce au CV parsé, mais nous avons choisi de nous contenter de l'OCR car nous extrayons l’information en perdant peu de signal et en étant partiellement protégé contre le bruit (keyword stuffing).

Pour l’ordinateur, cette information reste néanmoins brute : les mots ne sont qu’une suite de caractères dénuée de sens. Il nous faut maintenant la transformer pour qu'il soit capable de l’exploiter automatiquement.

Transformer et enrichir l’information

Détecter les mots-clés

Nous allons reprendre l’idée de base des systèmes actuels : la détection de mots-clés.

On peut procéder de cette manière pour déterminer si la candidature est intéressante. Il est donc raisonnable de penser qu’ils contiennent suffisamment d’informations pour effectuer un premier tri. Nous cherchons bien sûr à faire mieux que ce qui existe en explorant 3 approches pour constituer une liste de mots-clés à partir des données.

Le but est d’être plus exhaustif et moins enclin à refuser de bonnes candidatures que les systèmes actuels.

1 - Grâce à des statistiques sur le corpus de candidatures

Nous avons expérimenté sur le corpus de candidatures dont nous disposons afin de constituer automatiquement une liste de mots-clés pertinents pour chaque poste.

Mots-clés identifiés pour le poste de Product Owner, basés sur les candidatures reçues à Octo.

Mots-clés identifiés pour le poste de Data Geek, basés sur les candidatures reçues à Octo.

On obtient des résultats intéressants à première vue qui nous font dire que cette approche pourrait permettre d’identifier automatiquement les mots-clés pertinents à un poste.

Nous avons employé une technique bien connue lorsqu'on travaille sur des textes en data-science : le TF-IDF. Cela permet de faire ressortir les termes qui sont caractéristiques d'un document par rapport au reste du corpus. Comme nous souhaitons obtenir les mots-clés pertinents à une annonce, il faut que chaque document représente une annonce. Nous avons donc mis bout-à-bout tous les CVs liés à une annonce pour aboutir à un document par annonce. Le corpus ainsi créé permet de remonter les termes caractéristiques des candidatures pour une annonce.

Cette approche offre l’avantage de diversifier les sources sur lesquelles on se base lorsqu’on établit une telle liste. Grâce au volume de candidatures, elle a plus de chances d’être exhaustive.

2 - Grâce à la reconnaissance d'entités nommées

Une autre façon de détecter des mots-clés peut être de faire de la reconnaissance d'entités nommées (Name Entity Recognition ou NER).

Le NER sert à identifier des mots ou groupes de mots représentant des personnes, des organisations ou des entreprises, des lieux ou encore des quantités, des distances, des valeurs, des dates, etc. La tâche semble appropriée dans notre cas car nos mots-clés sont souvent des noms de technologies. On peut donc s’attendre à ce qu’un NER entraîné puisse identifier des noms de technologies qu’il n’a jamais vu avant.

Malheureusement, nos essais se sont avérés décevants.

Outre le coût important en temps et en ressources nécessaire pour annoter les données, le problème vient probablement de la structure textuelle des CVs. Le NER de spaCy se sert principalement des mots proches du mot cible pour inférer le type d’entité auquel il appartient. Or nous avons constaté que les noms de technologies sont souvent agglomérés dans une liste sans que les mots adjacents ne renseignent beaucoup sur le mot cible.

Exemple d’une liste où les noms de technologies sont agglomérés.

3 - Autre approche

Il existe peut-être un site thématique qui couvre tout ou une partie des mots-clés qui vous intéresse.

Grâce à un scraping (poli et courtois) du site, vous pouvez profiter d’une source de données utiles d’autant plus si elle est mise à jour régulièrement (e.g. un forum) ou que les mots-clés sont utilisés pour la structure du site.

Dans le cas des technologies, on peut surveiller les sites tels que stackoverflow ou stackshare qui proposent des informations structurées sur les technologies.

Exploiter l'information : le tri des candidatures

Il s’agit de déterminer le degré de pertinence de la candidature.

Une fois les informations extraites du CV et transformées de façon à pouvoir être traitées par l’ordinateur, on peut se poser la question : "Qu’est ce qui fait qu’une candidature est pertinente ?" C’est une question à laquelle il est difficile de répondre de manière explicite. Cependant on sait qu’il est possible d’y répondre car c’est ce que font les recruteurs. C’est dans ces cas là qu’il est intéressant d'entraîner un algorithme d’apprentissage automatique.

Un algorithme d’apprentissage automatique détermine par inférence quelles règles permettent de passer des paramètres d'entrées au résultat attendu.

Concrètement, nos paramètres d’entrées sont les attentes par rapport au poste proposé ainsi que les candidatures, et le résultat attendu est le degré de pertinence de la candidature.

Paramètre d'entrée n˚1 : l'annonce

Nous n'en avons pas vraiment parlé jusque-là mais le traitement de l'annonce est étroitement lié au traitement de la candidature.

L'annonce liste les informations que le candidat doit satisfaire pour postuler. Pour ne pas se retrouver à comparer des pommes et des oranges, les annonces doivent être traitées de façon à extraire une liste de mots-clés similaires. Parmi les mots-clés, nous avons sélectionné les technologies (langages de programmation, logiciels, plateformes de services, etc.). Les offres choisies pour expérimenter étant de nature technique, les technologies peuvent servir de proxy aux compétences.

Seulement, les informations spécifiques à l’offre d’emploi n’étaient pas souvent présentes dans les annonces de manières explicites. Nous avons d’abord demandé à des recruteurs de définir une liste de mots-clés sur certaines annonces, puis nous avons cherché une façon d’automatiser en appliquant un TF-IDF (voir plus haut).

Paramètre d'entrée n˚2 : la candidature

Chaque candidature est traitée comme une checklist : chaque case est une compétence attendue par l'annonce qui est cochée si la candidature en fait mention.

Compétence attendue 1Compétence attendue 2Compétence attendue 3
Candidature101

En termes techniques, la candidature est représentée par un encodage en n-hot des compétences présentes dans la candidature par rapport aux compétences attendues.

Cet encodage est simple mais pas idéal.

Le fait d'utiliser des 1 et des 0 de la sorte suppose 3 choses. Premièrement, l'absence de valeur intermédiaire ne permet pas de refléter le degré de maîtrise de la compétence. Deuxièmement, les compétences sont indépendantes et incomparables (i.e. orthogonales). Troisièmement, elles valent toutes autant les unes que les autres. Or, dans la réalité, ce n’est pas le cas : une compétence peut être plus ou moins bien maîtrisée, certaines compétences sont plus ou moins éloignées d’autres compétences, et pour un poste donné, certaines compétences sont plus importantes que d’autres.

Nous verrons plus bas comment nous avons tenté d'adresser ce point.

Sortie : Le degré de pertinence

Pour établir la pertinence "avérée" d'une candidature, nous avons choisi de regarder si le candidat a passé au moins un entretien.

Il paraît raisonnable de penser que si le candidat valait la peine de passer un entretien alors sa candidature était pertinente. Ça nous impose de travailler avec la variable binaire répondant à la question : “le candidat a-t-il passé un entretien ?”. Nous avons donc entraîné un modèle de classification à prédire notre variable binaire.

Cependant, cette variable binaire ne nous intéresse pas vraiment. Nous voulons proposer une vue ordonnée des candidatures aux recruteurs.

Afin d’obtenir un classement, nous avons utilisé les probabilités du modèle (que nous aurions calibrées si nous avions eu suffisamment de données) comme score.

Cela reflète la confiance du modèle en sa prédiction. C'est à dire, à quel point le modèle est sûr que le candidat va passer un entretien. C'est un raccourci mais il y a des chances que le degré de pertinence d'une candidature soit proche de la confiance du modèle en le fait que cette dernière justifie un entretien.

Résultats

Les résultats que nous avons obtenus sont équivoques.

En effet, nous n'avons pas pu reproduire les résultats historiques. Certaines candidatures qui avaient conduit à un entretien n'étaient jamais sélectionnées. Et inversement, d'autres étaient placées devant celles qui avaient conduit à un entretien.

Cependant, l'ordre proposé nous paraissait correct au vue des candidatures. Nous l'avons donc évalué en demandant l'avis des recruteurs. Et comme nous, ils ont validé l'ordre proposé par l'algorithme.

Alors comment expliquer que nous ne pouvons pas reproduire les résultats historiques ?

Nous avons émis 3 hypothèses. La première est que l’information fournie à l'algorithme est simplement insuffisante. La seconde est que notre façon d'encoder des compétences limite les performances de l'algorithme pour les raisons évoquées plus haut. La troisième est que notre volume de données n'était pas suffisant, ou que la reproductibilité des choix des recruteurs soit trop faible pour l’algorithme.

C'est pour adresser les 2 premiers cas de figures que nous avons intégré les embeddings dont nous vous avons parlé dans la partie précédente.

D’abord ils rendent la détection de mots-clés plus résiliante. Les embeddings nous permettent de savoir quels sont les termes proches sémantiquement des mots-clés que l'on cherche. Nous choisissons de considérer les termes proches d’une compétence attendue comme indiquant la présence de ladite compétence. En ratissant plus large, nous pensons mieux capturer l'information.

Ensuite, en tirant partie des distances établies entre les compétences par l’embedding. En remplaçant l’encodage n-hot par la somme des vecteurs associés aux compétences présentes. L'algorithme ne traite alors plus une liste de compétences indépendantes et incomparables mais un vecteur représentant le profil technique du candidat.

Malheureusement, aucune de ces approches n'a permis d’obtenir de résultats significativement meilleurs.

Quant à la dernière hypothèse, elle aurait pu être vérifiée, dans l'idéal en amont du projet, en s’assurant d’un consensus relatif des recruteurs sur les candidatures (mesures intra et inter recruteurs). Ce qui est intéressant, c'est qu'à OCTO, on a un intérêt pour les candidats atypiques. Il est donc tout à fait possible que les candidatures choisies par un recruteur ne correspondent pas nécessairement à celles qu'aurait choisies un autre recruteur.

Si vous avez bien suivi, vous devez vous dire que, puisque le but est de proposer un ordre reflétant la pertinence, ces résultats sont encourageants et vous auriez raison.

Mais entre-temps, l'outil interne de recrutement Twig a pivoté pour s'orienter vers le sourcing.

Il ne s'agit plus de proposer un classement qui peut être relatif. Puisque l'activité de sourcing se passe sur LinkedIn, notre objectif est de fournir un score qui s'afficherait à côté de chaque profil. Ce score correspond à l'adéquation avec un poste pour lequel OCTO cherche à pourvoir. Ce score ne peut plus être issu la position dans une liste puisque ladite liste n'existe plus.

Et là l'algorithme n'est absolument pas performant.

Un profil correspondant bien à un poste pouvait avoir un score de 30/100 comme 80/100. Cela dépendait du poste et il s'est avéré impossible de le savoir sans avoir évalué un panel de profils. Et, bien que nous ayons vérifié les mots-clés proposés automatiquement semblaient pertinents, le fait est que si la liste de mots-clés associée au poste est trop grande, le score absolu est dilué.

Pour répondre à la nouvelle exigence métier, nous avons tenté de normaliser le score d'un profil en nous basant sur d'autres profils.

Le problème est que le score ne vaut pas grand chose tant qu'un certain nombre de profils n'a pas été évalué. L'accumulation des profils se fait au fil de l'eau, ce qui n'est pas idéal d'un point de vue utilisateur. Et ce nombre est difficile à déterminer d'autant que cela dépend de la qualité des profils. Là où les candidatures reçues assuraient que les profils étaient plus ou moins adaptés à un poste donné, nous devions désormais nous baser sur l'intitulé de poste pour identifier les profils permettant de normaliser le score.

En fin de compte, notre modélisation du problème ne s'est pas avérée satisfaisante pour répondre aux besoins métiers.

Alternative

Nous n’étions cependant pas obligés de poursuivre dans la même veine que les ATS.

Nous avons fait ce choix parce que nous avions identifié une limitation spécifique des ATS et une piste permettant d’y répondre. Cependant, certains des plus gros succès de l’IA viennent d’une approche où l’IA prend le problème dans sa globalité. C’est d’ailleurs ce que JobTeaser a fait. Leur approche vectorise les annonces et les candidatures dans le même espace vectoriel grâce à un réseau de neurones. Cette représentation vectorielle des documents leur permet d’identifier les candidatures les plus proches d’une annonce (le plus proche de notre cas d’usage) mais aussi de recommander des annonces à un candidat sur base de son CV.

Cela requiert un volume de données conséquent, possible pour JobTeaser et autres jobboards mais plus difficiles pour les autres.

Conclusion

Cette troisième partie était l’occasion de vous partager nos expérimentations et notre approche pour améliorer le tri par mots-clés grâce à l’IA.

Nous avons vu que la structure du texte que l’on trouve dans les CVs est porteuse d’information et leur rédaction particulière rend difficile l’application de modèles de NLP. A partir d'une liste de mots-clés générée automatiquement, nous avons pu ordonner les candidatures de façon à refléter leur pertinence par rapport à l’annonce. Cependant, le métier ayant changé le cas d'usage, un classement relatif n'était plus satisfaisant. Il fallait établir un score intrinsèque au profil pour un poste donné. Exploiter le score produit par l'algorithme s'est révélé impossible et établir un panel de profil pour jauger celui qui nous intéresse n'était pas pratique. En conséquence, le projet s'est arrêté.

Dans une quatrième partie, nous allons présenter les stratégies à mettre en place pour limiter les biais et plus généralement les considérations autour de l’implémentation d'une IA éthique.