diff --git a/readme.md b/readme.md index cd6f9c1cdc6c8f48ec01df0964564b16e6739972..e3be29fbf1dcf1ed025beeaec186152914fe6ce0 100644 --- a/readme.md +++ b/readme.md @@ -1,32 +1,47 @@ % Programmation séquentielle - K-Means # But -- Le but de ce travail pratique est d'implémenter la méthode des k-moyennes pour partitionner des données de façon non supervisée. +Le but de ce travail est d'implémenter la méthode des k-moyennes +pour partitionner des données de façon non supervisée. # Théorie + ## Le partitionnement de données -De façon générale, le partitionnement de données (_clustering_) consiste à grouper des données -en _clusters_ de façon à ce que les éléments d'un même groupe soient proches les -uns des autres ou d'un élément virtuel représentant l'élément "moyen" de la -partition. + +Le partitionnement de données (_clustering_) consiste à grouper des données +en _clusters_ de façon à ce que les éléments d'un même groupe soient similaires les +uns aux autres ou d'un élément virtuel représentant le centre de gravité du +groupe.  +## Type des données + +Chaque point sera un vecteur de valeurs numériques à N dimensions. +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 -La méthode k-moyennes (k-means en anglais) est un algorithme qui permet de partitionner un groupe de données par rapport à une métrique définie. Chaque _cluster_ devra contenir des données homogènes. De plus tous les _cluster_ doivent également être hétérogènes les uns des autres. -Ce processus de regroupement de données s'effectue de manière non supervisée, c'est-à-dire que l'algorithme utilisé s'applique sur des données non étiquetées et sans avoir recours à un retour externe sur ses résultats. +La méthode k-moyennes (k-means en anglais) est un algorithme qui permet +de partitionner un ensemble de "points". +Ce processus de partitionnement s'effectue de manière non supervisée, +c'est-à-dire que l'algorithme est appliqué sur des données non étiquetées +et sans avoir recours à un retour externe sur les résultats. -## Initialisation des clusters -Avant de pouvoir appliquer l'algorithme des k-moyennes, il faut déterminer le nombre de _clusters_ souhaité ($k$) ainsi que la position de leur _centroïde_ (point représentant le centre de chaque _cluster_). +### Initialisation des clusters -Dans un premier temps la valeur de $k$ peut être choisie arbitrairement, mais il faudra par la suite déterminer la valeur la plus optimale (nous y reviendrons plus tard). +Une fois qu'on a défini le nombre de clusters souhaité (arbitrairement), +il s'agit de choisir les _centroïdes_ +(points représentant les centres de gravité de chaque _cluster_) initiaux. +Ces derniers peuvent être choisis en faisant recours à un degré variable +d'aléatoire, selon les résultats souhaités. +Il faut simplement s'assurer qu'ils ne soient pas trop proches les uns des autres. -La position des _centroïdes_ sera déterminée aléatoirement mais il faut s'assurer qu'ils ne soient pas trop proches les uns des autres afin d'avoir des _clusters_ cohérents. Vous devrez déterminer une distance $\delta$ minimale séparant chaque _centroïde_ entre eux. +### Etapes -## Calcul de la distance -Vous travaillerez avec des points à 2 dimensions contenant des coordonnées sous la forme de nombres à virgule flotante. Ainsi vous devrez les assigner à des _clusters_ par rapport à la distance séparent les points. En effet, chaque point devra appartenir au _cluster_ dont son _centroïde_ est le plus proche. +Ainsi vous devrez les assigner à des _clusters_ par rapport à la distance séparent les points. +En effet, chaque point devra appartenir au _cluster_ dont son _centroïde_ est le plus proche. Afin de quantifier la proximité de deux éléments entre eux, nous avons @@ -37,8 +52,6 @@ de Manhattan ou une distance euclidienne et prend en argument deux vecteurs él $$d(x,y)$$ -Une grande valeur de retour indiquera que $x$ et $y$ sont éloignés. -Inversement, une petite valeur de retour indiquera qu'ils sont proches. Ainsi, l'assignation de chaque point à un _cluster_ se déroule de la manière suivante : @@ -47,33 +60,93 @@ Ainsi, l'assignation de chaque point à un _cluster_ se déroule de la manière 3. Assigner le point au _cluster_ du _centroïde_ le plus proche . -### Distance euclidienne -La distance euclidienne ($D_e$) entre un point $x$ et $y$ correspond à : -$$ \vec{D_e} = \sqrt{(x_2-x_1)^2 + (y_2-y_1)^2} = \sqrt{(x-y)^2} $$ +## Calcul de similarité + +Les fonctions de calcul de similarité (qu'on peut vulgariser comme +"fonction distance") de deux points entre eux sont: + +- indépendantes de l'algorithme k-means +- choisies en fonction du résultat souhaité + +Elles prennent en paramètre deux points et retournent un e valeur numérique. +Une grande valeur de retour indiquera que les deux points sont éloignés. +Inversément, une petite valeur de retour indiquera qu'ils sont proches. -### Distance de Manhattan +### Exemples + +Voici quelques exemples de fonctions de calcul de similarité. + +#### Distance Euclidienne + +La distance euclidienne entre deux points $x$ et $y$ est définie par: + +$$ \vec{D_e} = \sqrt{(x_2-x_1)^2 + (y_2-y_1)^2} = \sqrt{(x-y)^2} $$ + +#### Distance de Manhattan La distance de Manhattan ($D_m$) entre un point $x$ et $y$ correspond à : $$ \vec{D_m} = |(x_1 - y_1)| + |(x_2 - y_2)| $$ -## Déterminer le $k$ optimal -Afin de tirer les meilleures conclusions du résultat de notre algorithme des k-moyennes, il faut déterminer le $k$ (nombre de _cluster_) optimal. -Pour cela il existe de nombreuses méthodes, les plus connues étant : -- La méthode du coude (Elbow Method) -- L'analyse par silhouette (Silhouette analysis) -# Énoncé -À partir d'un fichier contenant des points à 2 dimensions (chaque coordonnées étant un nombre à virgule flotante), vous devez implémenter l'algorithme k-moyennes et permettre la visualisation des différents clusters créés. -Cet algorithme peut s'appliquer facilement à tous types de données -pouvant être représentées sous forme de vecteurs de valeurs. -Cependant, nous avons décidé de limiter ce travail aux vecteurs à valeurs -décimales, en 2 dimensions, pour en simplifier la visualisation -et la vérification de notre algorithme. + + + + + +# Implémentation + +## Format d'entrée + +L'entrée sera un fichier spécifié en argument au programme. +Si aucun argument est fourni, le fichier d'entrée sera l'entrée standard (stdin). + +Le fichier contiendra: + +- sur la première ligne, le nombre de dimensions des points de l'ensemble +- sur la deuxième ligne, le nombre de clusters voulu +- un point par ligne, sous forme de N valeurs séparées par des virgules + +```txt +<nombre de dimensions> +<nombre de clusters> +x1,x2,...,xn +y1,y2,...,yn +... +``` + +## Format de sortie + +La sortie sera écrite dans un fichier spécifié en argument au programme. +Si aucun argument est fourni, le fichier de sortie sera la sortie standard (stdout). + +Le fichier contiendra: + +- sur la première ligne, le nombre de dimensions des points de l'ensemble +- sur la deuxième ligne, le nombre de clusters +- une étoile "*" signifie le début d'un cluster; cette dernière est suivie + d'un entier (1 à K) qui serait l'ID du cluster + (attention, l'ID n'est pas une étiquette; il est arbitraire) +- pour chaque étoile, une liste de points appartenant au même cluster, + avec le même format que les points d'entrée + +```txt +<nombre de dimensions> +<nombre de clusters> +*<ID cluster 1> +x1,x2,...,xn +y1,y2,...,yn +... +*<ID cluster 2> +z1,z2,...,zn +t1,t2,...,tn +... +``` + ## Interface utilisateur @@ -105,28 +178,6 @@ Votre programme doit implémenter les fonctions suivantes : - Déterminer les points appartenant aux _clusters_ - Déterminer le K optimal (Elbow optimal, silhouette method, ...) -Ainsi que les structures ci-dessous : - -```c -typedef struct _cluster { - struct _point* centroid; - int color; -} cluster; - -typedef struct _point { - float x; - float y; - char* label; // for tests - struct _cluster* cluster; - int color; -} point; - -typedef struct _kmeans { - int k; - struct _cluster* clusters_array; // k size - struct _point** points_array; -} kmeans; -``` ## 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.