Mathilde Lafay, 537 406 302
Matiss Langouët, 537 405 246
Jérémy Maille, 537 406 461
Michal Naumiak, 537 393 475
Ce projet vise à étudier le comportement des souris en environnement controlé, à l'aide de méthodes d'apprentissage automatique supervisé. Ce projet est encadré par Vincent Coulombe du laboratoire CERVO. Le travail effectué comprend l'étiquettage des données, leur transformation et consolidation, le développement de deux algorithmes pour l'apprentissage et l'analyse des performances de ceux-ci, ainsi que la réalisation d'une affiche pour la présentation en fin de session.
Vous trouverez dans ce document toutes les informations relatives au projet, notre méthodologie, les données utilisées, leur processus d'extraction et de transformation, le code de nos algorithmes, les scripts d'évaluation de ceux-ci, et plus globalement, une description de toute la structure du code ainsi qu'un guide utilisateur pour l'éxécution de la pipeline complète au besoin et les liens vers les notebooks google colab utilisés pour l'apprentissage.
- Construction d'un jeu de données exploitable (extraction et transformation) après étiquettage manuel des données avec le logiciel BORIS
- Implémentation, tests et comparaisons de plusieurs algorithmes (CNN, RandomForest, LSTM bidirectionnel ...)
- Evaluer les performances avec des métriques standard (accuracy, recall, F1)
- Sauvegarde des modèles et des métadonnées
- Présentation des expérimentations et des résultats au moyen d'une affiche
- Structure du projet
- Données
- Pipeline de prétraitement
- Algorithmes
- CNN
- LSTM
- RandomForest
- Guide utilisateur
Le projet est structuré en 3 grands pôles : les données, le traitement des données, et les algorithmes pour les modèles. Voici l'arbre complet de celui-ci, mais le dossier qui vous intéresse sera certainement src/.
Analyse-comportementale-ML/
├── data/
│ ├── raw/ # MICE dataset non transformé
│ │ ├── actions/
│ │ ├── bboxes/
│ │ ├── keypoints/
│ │ ├── velocities/
│ │ ├── behaviors/ # nos labellisations
│ │ └── visualizations/
│ ├── processed/ # MICE dataset agrégé
│ └── final/ # Transformations adaptées à chaque algo du jeu agrégé
│ ├── algo_1/
│ ├── algo_2/
│ └── algo3/
├── models/
│ ├── model_2_lstm_20251128_004834/
│ │ ├── best_model.pth
│ │ ├── config.json
│ │ └── training_history.json
│ └── model_2_lstm_20251128_005052/
│ ├── best_model.pth
│ ├── config.json
│ └── training_history.json
├── src/
│ ├── __init__.py
│ ├── data/
│ │ ├── __init__.py
│ │ ├── aggregate.py
│ │ ├── extract.py
│ │ ├── load.py
│ │ ├── pipeline.py
│ │ ├── transform_algo1.py
│ │ ├── transform_algo2.py
│ │ ├── transform_algo3.py
│ │ └── utils/
│ │ └── data_sources.yaml
│ ├── models/
│ │ ├── __init__.py
│ │ ├── model_1/ # CNN
│ │ │ ├── model.py
│ │ │ ├── pretraitement.py
│ │ │ ├── test.py
│ │ │ └── README_CNN.md
│ │ ├── model_2/ # LSTM
│ │ │ ├── __init__.py
│ │ │ ├── dataset.py
│ │ │ ├── evaluate_*.md
│ │ │ ├── hierarchical_classifier.py
│ │ │ ├── model.py
│ │ │ ├── prototypical_network.py
│ │ │ ├── temporal_smoothing.py
│ │ │ ├── train_unified.py
│ │ │ ├── train.py
│ │ │ └── README_LSTM.md
│ │ ├── model_3/ # RandomForest
│ │ │ ├── RandomForest.ipynb
│ │ │ └── randomforest.py
│ └── utils/
│ ├── __init__.py
│ ├── config.py
│ ├── seed.py
│ └── skeleton_utils.py
├── requirements.txt
├── setup.py
└── README.md
Les données utilisées pour ce projet sont fournies par le laboratoire CERVO. Nous avons 3 vidéos d'entraînement de 10 min et 1 vidéo de validation de 5 min des 26 sujets (souris) du vivarium. Les sujets sont étiquettés avec leur action [other, running, interacting, rearing, fighting] et leurs déplacements (flèche). En plus des vidéos nous avons des tableaux contenant toutes les informations contenues dans les vidéos telle que la position des souris, les points clés de leur squelette, leur vitesse, leur action, leur identifiant et l'identifiant de l'image.
Nous avons étiquetté avec BORIS ces vidéos pour ajouter le comportement des souris, qui sont le suivi, la fuite, l'approche, ou rien. Avec ces données, on crée un jeu de données de panel exploitable pour nos algorithmes.
Toutes les données fournies par le laboratoire, et les étiquetages sont d'abord aggrégées en une grande table, séparée en train et en test. Chaque données est groupée grâce à la clé ('video_id', 'frame_id', 'instance_id') qui représente chaque souris pour chaque image de chacune des vidéos. Toutes les frames pour toutes les vidéos sont présentes dans le jeu, et ce même si la souris n'existe pas à ce moment (soit car absente de la vidéo, non étiquetée, ou bien encore cachée dans le vivarium et donc non détectée). Dans ce cas, toutes les valeurs des colonnes numériques de la ligne sont marquées à -1.
Pour les étiquetages, un système de score pour chaque comportement, compris entre 0 et 1 est mis en place. Il est indiqué 1 dans la colonne appropriée si le comportement est observé, 0 sinon.
Ce jeu de donnée agrégé constitue la base des jeux de données utilisées pour chaque algorithme développé dans le cadre de ce projet, il est sauvegardé à l'emplacement ./data/processed/*_aggregated.csv (* = [train/test]). Les transformations réalisées pour chaque algorithme seront détaillées dans les sous-parties correspondantes à ceux-ci
Le processus de prétraitement des données est organisé selon l'ordre suivant :
Scripts d'extraction et chargement :
extract.py: Télécharge les données brutes depuis Google Drive selon le mapping défini dansutils/data_sources.yamlload.py: Charge les fichiers CSV bruts et les organise par catégorie (actions, bboxes, keypoints, velocities, behaviors)
Scripts d'agrégation et transformation :
aggregate.py: Fusionne toutes les sources de données sur les clés communes (video_id, frame_id, instance_id) et crée les scores comportementaux selon la logique :-1: souris non étiquetée (absente du fichier behaviors)0: souris étiquetée mais comportement non observé1: comportement observé (entre START et STOP)
transform_algo1.py: Prépare le dataset pour l'algorithme 1transform_algo2.py: Prépare le dataset pour l'algorithme 2transform_algo3.py: Prépare le dataset pour l'algorithme 3pipeline.py: lance l'exécution complète du pipeline de données
Configuration :
utils/data_sources.yaml: Mapping des fichiers Google Drive (ID, nom, URL)
Organisation hiérarchique des données :
raw/: Données brutes téléchargées, organisées par catégorieprocessed/: Données agrégées avec tous les scores comportementauxfinal/: Datasets finaux prêts pour l'entraînement des algorithmes (également sauvegardés sur google drive pour les notebooks colab)
La pipeline de traitement suit ces étapes principales :
1. EXTRACTION (extract.py)
Téléchargement depuis Google Drive
2. CHARGEMENT (load.py)
Lecture des CSV bruts par catégorie
3. AGRÉGATION (aggregate.py)
Fusion + création scores comportementaux
4. TRANSFORMATION (transform_algo1.py, transform_algo2.py, transform_algo3.py)
Sélection colonnes + préparation dataset
5. DONNÉES FINALES
data/final/algo_1/ ou algo_2/ ou algo_3/
Option 1 : Pipeline complète automatique
python src/data/pipeline.pyOption 2 : Étape par étape
# 1. Télécharger les données
python src/data/extract.py
# 2. Agréger les données (train + test)
python src/data/aggregate.py
# 3. Transformer pour algorithme 1
python src/data/transform_algo1.py
# 4. Transformer pour algorithme 2
python src/data/transform_algo2.py
# 5. Transformer pour algorithme 3
python src/data/transform_algo3.pyLe pipeline nettoie automatiquement les instance_id invalides :
- Plage valide : 0-26 (27 souris maximum)
- IDs négatifs ou hors plage : exclus automatiquement
- Doublons sur (video_id, frame_id, instance_id) : supprimés
Cela garantit que seules les souris réelles sont incluses dans les analyses.
Après agrégation, trois colonnes de scores sont créées.
approach_score: Score d'approchefollowing_score: Score de suiviescape_score: Score de fuite
Valeurs possibles :
-1: Souris jamais étiquetée dans le fichier BORIS0: Souris étiquetée mais comportement non observé sur cette frame1: Comportement activement observé (entre START et STOP BORIS)
Cette logique permet de distinguer l'absence de données de l'absence de comportement. La variable de score sera comprise entre 0 et 1 lors de la classification par la machine afin d'établir un score de confiance sur l'étiquetage automatique.
Avant d'entraîner les modèles, on a vérifié les données avec 'tests/inspection.py'
Ce script fournit :
- Nombre total d'observations
- Distribution des classes (comportements)
- Détection du déséquilibre des classes
- Analyse des valeurs manquantes
- Statistiques descriptives des features
Pour analyser le comportement des souris, nous avons testé 3 approches : un CNN, un LSTM bidirectionnel, et un Random Forest. Les explications associées seront données lors de la présentation du 17 décembre.
- model : https://colab.research.google.com/drive/1_M3KPMJFahJkU1G0pRlO65wYq9CJOj9x
- pretraitement : https://colab.research.google.com/drive/1BJeHVVVqm602Y4xqcjTpUx8mhoTvxEzD
- test : https://colab.research.google.com/drive/1o3fbw1fmRiie_2Qs9udw8SeLmyhYYiTu
- code source : "./src/models/model_2"
- Python 3.8+ installé (téléchargeable sur python.org)
- Clonez le dépôt et naviguez dans le dossier
- Lancez le script de setup :
python setup.pyCe script va :
- Créer un environnement virtuel (
venv/) - Installer les dépendances (
requirements.txt) - Créer la structure de dossiers
- Activez l'environnement virtuel :
Windows :
venv\Scripts\activateLinux/Mac :
source venv/bin/activateUne fois l'environnement configuré, lancez la pipeline complète :
python src/data/pipeline.pyOu exécutez étape par étape en lançant les fichiers individuels (décrits ici Exécution de la pipeline)
- Algorithme 1 : https://colab.research.google.com/drive/1Cm-Se4QJcwuGlkuWOG845GN21dBpUlSV?usp=sharing#scrollTo=M0VvgJyzWv7h
- Algorithme 2 : Naviguez vers
src/models/model_2/et suivez les instructions - Algorithme 3 : https://colab.research.google.com/drive/1zz5CwMYQCuFfj-n2QMqjikqAksKzN2PE?usp=sharing
- Mathilde Lafay
- Matiss Langouët
- Jérémy Maille
- Michal Naumiak
contributions égales
Encadrement : Vincent Coulombe (CERVO)
Enseignant : Christian Gagné (IID)
Cours : GIF-4101/7005 - Introduction à l'apprentissage automatique