Constitution des datasets

Pour faire tourner des modèles de AI/ML nous avons besoin de constituer le ou les datasets nécessaires, dans un format exploitable dans Python.
Le travail préparatoire sur les données est un point essentiel, nécessitant du temps (même en ayant déjà constitué une base de données avant) et ne devant pas être négligé pour pouvoir ensuite travailler sur des données fiables et pertinentes, et produire des résultats de qualité.
Nous présentons ici les difficultés rencontrées et la façon dont elles ont été traitées:

1/ Les données disponibles sont assez nombreuses et hétéroclites, provenant de tables différentes dans notre base, on a du mal à s’y retrouver.
=> Pour y voir clair nous créons tout d’abord un fichier excel pour lister les données (ou plutôt, les métadonnées) présentes, leur source, leur format.
On travaillera sur ce fichier pour bien maîtriser les données et le périmètre qu’on se fixe dans le dataset, avant de travailler sur les données elles-mêmes.

2/ Certaines données sont vides ou non disponibles
=> On réduit le périmètre de courses sur des dates où on a un maximum de données (possible car on a beaucoup de courses dans la base)

  • Si des données restent vides on peut laisser la valeur Vide
    Pour les données quantitatives, si on a moins de 5% de données vides, on pourra remplacer la valeur vide par la médiane
  • Si cela pose un problème dans les traitements alors il faudra réduire encore le périmètre de courses, ou bien tout simplement supprimer la donnée/le feature. Dans un premier temps on peut ne pas inclure les données posant problème (ex le terrain, la moitié des lignes ont une valeur vide) pour essayer déjà d’obtenir un code et des résultats avec un jeu de donnée «propre», avant de complexifier
  • C’est cette 2ème option qui sera retenue ici.

3/ Certaines données ne sont pas exploitables telles quelles
=> On analyse chaque donnée disponible, on regarde sa pertinence et son exploitabilité

  • Si on peut la transformer en donnée pertinente et exploitable on effectue les transformations nécessaires
  • Exemple : l’heure est transformée en classes: matinée (jusque 14h)/début aprem (14h-16h)/fin aprem (16h-18h)/soirée (après 18h)

  • Sinon on met la donnée de côté

4/ Les données ne sont pas les mêmes suivant la discipline (trot attelé ou plat notamment)
=> On crée 3 datasets :

  • 1 pour le plat
  • 1 pour le trot attelé
  • 1 global (plat, trot attelé, et autres disciplines)

Il s’agit ici d’un choix, pris pour plus de simplicité – on travaille successivement sur des datasets moins lourds en lignes (X) et plus réduits en colonnes/features (y) – et basé sur l’expérience pratique des courses, où on sait que les comportements sont différents suivant la discipline. On pressent donc qu’on va avoir des modèles différents à apprendre suivant la discipline.

5/ Les chevaux doivent tous être ramenés à des caractéristiques communes, indépendantes de la course dans laquelle ils courent, afin qu’on puisse effectuer l’analyse sur l’ensemble des chevaux de la même façon, en les analysant tous ensemble, et non au sein d’une course.

=> Les données reliant les chevaux entre eux au sein d’une course doivent donc être retraitées pour être normalisées:

  • id_course (l’identifiant de la course) doit être supprimé
  • Les pronostics ne doivent pas être gardés tels quels mais doivent être convertis en une donnée de pronostic. Pour cela nous devons transformer cette donnée, il y a plusieurs possibilités comme:
    • attribuer une variable catégorielle (classe): 1 s’il est pronostiqué en place 1, 2 en place 2 etc.. et 0 si non pronostiqué
    • attribuer une variable numérique: note sur 1 dépendant du nombre de chevaux de la course (incluant les non partants car ceux-ci ne sont pas connus au moment du prono). Exemple:
      note_prono= (nb chevaux – place prono +1)/nb chevaux
      Avec note=0 si cheval non pronostiqué
      On a ainsi note_prono = 1 si cheval pronostiqué 1er et ensuite la note décroit avec la place pronostiquée

    C’est cette 2ème option (donnée numérique) que nous utiliserons ici.

  • Les cotes (ou plus exactement les rapports) ne doivent pas être traitées seulement en valeurs absolues mais aussi en valeurs relatives, car elles dépendent des cotes des chevaux de la course et du nombre de chevaux. Les cotes en valeur absolue restent cependant intéressantes à conserver pour l’évaluation des gains et l’appréciation des caractéristiques d’une course par rapport aux autres.
    Nous ajoutons donc dans le dataset la cote relative arrondie, définie par :
    c=( Cote – Min Cotes) / (Max cotes – Min cotes) avec un arrondi à 0,2 le plus proche
    où:

    • Max cotes est la cote maximale de la course, sur l’ensemble des chevaux
    • Min cotes est la cote minimale de la course, sur l’ensemble des chevaux

    Ainsi lorsque cote=Min cotes, la cote relative est de 0.
    Lorsque cote=Max cotes, la cote relative est de 1.

En termes pratiques pour réaliser ces opérations, on part de notre base contenant les données brutes initiales, puis on utilise des requêtes pour transformer les données, et enfin générer les fichiers csv pour chaque dataset nécessaire et que l’on chargera dans Python via Pandas.