diff --git a/readme.md b/readme.md index 92b2899cf164e772808a1066a11500283142f67c..420011815bf883ae57ac2f80d5fdee836dfb6850 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -% Programmation séquentielle - K-Means +% K-Means # But @@ -29,7 +29,7 @@ Ces valeurs seront des entiers dans un premier temps mais il est simple d'étendre les définitions aux types à virgule flottante. -## Méthodes des k-moyennes +## Présentation de l'algorithme La méthode k-moyennes (k-means en anglais) est un algorithme qui permet de partitionner un ensemble de "points". @@ -52,12 +52,15 @@ Il faut simplement s'assurer qu'ils ne soient pas trop proches les uns des autre L'assignation des points à leurs _clusters_ se déroule de la manière suivante: -Pour chaque point, il faut: +0. Pour chaque point, il faut: 1. Calculer la distance entre le point et les _centroïdes_. 2. Prendre le centroïde qui correspond à la distance trouvée la plus petite. 3. Assigner le point au _cluster_ du _centroïde_ ainsi trouvé. -4. Calculer le nouveau centre de gravité du _cluster_. +4. Calculer le nouveau centre de gravité (_centroïde_) du _cluster_. +5. Si la position d'au moins un _centroïde_ a changé durant le parcours + de l'ensemble des points, réitérer cette suite d'opérations + depuis l'étape 0. ## Calcul de similarité @@ -78,21 +81,29 @@ Inversément, une petite valeur de retour indiquera qu'ils sont proches. Voici quelques exemples de fonctions de calcul de similarité. -#### Distance Euclidienne +#### Distance Euclidienne \newline -La distance euclidienne entre deux points $x$ et $y$ est définie par: +La distance euclidienne entre deux points est définie par: -$$d(a, b) = \sqrt{\sum_{i = 1}^{n}(a_i - b_i)^2}$$ +$$d_e(a, b) = \sqrt{\sum_{i = 1}^{n}(a_i - b_i)^2}$$ -#### Distance de Manhattan +#### Distance de Manhattan \newline -La distance de Manhattan ($D_m$) entre un point $x$ et $y$ correspond à : +La distance de Manhattan entre deux points est donnée par la formule suivante: -$$d(a, b) = \sum_{i = 1}^{n}|a_i - b_i|$$ +$$d_m(a, b) = \sum_{i = 1}^{n}|a_i - b_i|$$ -#### Distance circulaire +#### Distance de Chebyshev \newline + +On calcule la distance de Chebyshev ainsi: + +$$ d_c(a, b) = max( |a_1-b_1| , ... , |a_n-b_n| ) $$ + +En d'autres termes, on sélectionne la position à laquelle les coefficients +des deux vecteurs sont les plus éloignés et cette différence +(en valeur absolue) est la distance de Chebyshev. # Implémentation @@ -153,35 +164,66 @@ Les formats d'entrée et de sortie ont été choisis pour être à l'utilisateur. -## Déroulement de l'algorithme - -Une fois nos données correctement chargées, il faudra appliquer l'algorithme des k-moyennes à ces dernières : +## Déroulement de l'execution du programme -0. Déterminer le $k$. -1. Placer $k$ _centroïdes_ aléatoirement, appartenant chacun à un _cluster_. -2. Déterminer les points appartenant à chaque _cluster_ selon leur distance avec les _centroïdes_. -3. Une fois tous les points (ré)assignés à un _cluster_, calculer la nouvelle position des _centroïdes_ (il s'agira du nouveau centre du _cluster_ suite à la modification des points). -4. Recommencer à partir de l'étape 2 si la position d'au moins 1 _centroïde_ a été modifiée. +- appel de la commande avec éventuellement le passage des + fichiers d'entrée et de sortie en argument +- initialisation du nombre de dimentions de notre univers +- allocation de la mémoire pour les K groupes +- chargement des données d'entrée en mémoire + (possibilité d'intervertir ce point avec le précédent) +- application de l'algorithme k-means +- écriture des résultats formatés dans le fichier de sortie + (ou de la sortie standard, selon les arguments passés au programme) ## Fonctions à implémenter -Votre programme doit implémenter les fonctions suivantes : -- Définir _k_ centroïde aléatoirement -- Calculer la distance entre le centre d'un centroïde et d'un point -- Calculer la nouvelle position d'un centroïde (à partir de la moyenne des points) -- Lire un fichier contenant des points -- Déterminer les points appartenant aux _clusters_ -- Déterminer le K optimal (Elbow optimal, silhouette method, ...) +Il faut absolument implémenter les fonctionalités suivantes: +- gestion des arguments en ligne de commande +- lecture et écriture de fichiers formatés +- initialisation aléatoire et/ou intelligente des centroïdes +- au moins trois fonctions de calcul de similarité / "distance" entre deux points +- calcul du centre de gravité (_centroïde_) d'une partition +- les étapes de l'algorithme k-means -## Vérification du travail réalisé -Afin de s'assurer que votre algorithme a été correctement implémenté vous devez mettre en place des fichiers de tests. +## Travail suppémentaire possible + +### Affichage en temps réel + +Au lieu d'afficher uniquement le résultat final, il s'agirait +d'afficher chaque étape effectuée afin de pouvoir observer +l'algorithme en action. + +### Déterminer le nombre de clusters optimal -Étant donné que nous utilisons un algorithme non supervisé, il est difficile de vérifier si le résultat obtenu est "correct". Néanmoins, si nous appliquons notre algorithme sur des données dont on connaît le résultat attendu, alors il est possible de s'assurer que notre implémentation est correcte. +Faire des recherches sur les méthodes permettant d'optimiser +le nombre de clusters et les implémenter. +Si l'utilisation de cette fonctionalité est le souhait de l'utilisateur, +un seul caractère non-numérique est utilisé en lieu du nombre +de clusters souhaité. +De légères modifications du format sont envisageables pour autant +qu'elles soient justifiées. -Le fichier _data_for_tests.txt_ contient une dizaine de points directement assignés à un _cluster_. Vous devez vous assurer que votre implémentation des k-moyennes vous donne un résultat identique aux données de test. +### Interface graphique + +On peut imaginer créer une interface graphique permettant de visualiser +le résultat dans une fenêtre graphique. +Pour cela, une option serait de mettre à profit la librairie gfx +utilisée pendant les labos de physique. + + +## Vérification du travail réalisé + +Il serait bon de mettre en place des tests unitaires pour les +fonctions implémentées. + +On implémente un algorithme non supervisé. +Il est donc difficile de vérifier si le résultat obtenu est "correct". +Néanmoins, un point placé dans le mauvais groupe est facile à identifier +par comparaisons de distances aux centroïdes. # Travail à rendre @@ -191,17 +233,14 @@ Le fichier _data_for_tests.txt_ contient une dizaine de points directement assig - démonstration du programme -# Travail suppémentaire possible - - -## Affichage en temps réel +# Références -Au lieu d'afficher directement le résultat final de votre implémentation de l'algorithme des k-moyennes, vous devez afficher chaque étape effectuée afin que l'on puisse constater comment l'assignation des points aux _clusters_ est effectuée. +https://www.editions-eni.fr/livre/le-machine-learning-avec-python-de-la-theorie-a-la-pratique-9782409031816/extrait-du-livre.pdf +https://towardsdatascience.com/k-means-clustering-algorithm-applications-evaluation-methods-and-drawbacks-aa03e644b48a -## Implémentation avec vecteurs à $n$ dimensions +https://towardsmachinelearning.org/k-means/ -Étendre l'implémentation pour pouvoir utiliser des vecteurs -à $n$ dimensions avec $n$ passé en paramètre au début de la procédure. +https://vitalflux.com/elbow-method-silhouette-score-which-better/ -Afin de pouvoir visualiser les résultats, vous devrez également implémenter l'algorithme PCA pour la visualisation de vecteurs à plus de 2 dimensions. +Figure 1 : https://stats.stackexchange.com/questions/146339/what-does-cluster-size-mean-in-context-of-k-means