Skip to content
Snippets Groups Projects
Commit 949d098d authored by dario.genga's avatar dario.genga
Browse files

Add first draft of the statement

parent b5f0661f
Branches
No related tags found
No related merge requests found
...@@ -7,7 +7,7 @@ read: ${PDF} ...@@ -7,7 +7,7 @@ read: ${PDF}
firefox $^ firefox $^
%.pdf: %.md Makefile %.pdf: %.md Makefile
pandoc --pdf-engine=xelatex -o $@ $< pandoc --pdf-engine=xelatex -N -o $@ $<
clean: clean:
rm -rf ${PDF} rm -rf ${PDF}
......
img/kmeans_clustering.png

67.6 KiB

---
title: Programmation séquentielle - K-Means
author:
- GENGA Dario
- JAQUET Steven
- MAYA Inès
- ROSSMANN Théo
- STEFANOVIC Boris
date: 2022-05-10
geometry: "margin=40mm"
mainfont: DejaVu Sans
header-includes:
- \usepackage{float}
- \let\origfigure\figure
- \let\endorigfigure\endfigure
- \renewenvironment{figure}[1][2] {\expandafter\origfigure\expandafter[H]} {\endorigfigure}
---
# Buts
- 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 partitionnement de données
De façon générale, le partitionnement de données 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.
# Méthodes des k-moyennes
Dans ce travail vous devrez implémenter l'algorithme k-moyennes (k-means en anglais)
qui permet de partionner un groupe de données par rapport à une metrique définie.
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.
# Énoncé
À partir d'un fichier contenant des points à 2 dimensions, implémenter l'algorithme k-moyennes et visualiser les différents clusters créés.
## Fonction distance
Afin de quantifier la proximité de deux éléments entre eux, nous avons
besoin de définir une fonction distance, qui sera notre métrique.
Cette fonction distance peut être aussi simple qu'une distance
de Manhattan ou une distance euclidienne, par exemple.
Cette fonction prend en argument deux vecteurs éléments de notre univers.
$$d(x,y)$$
Une grande valeur de retour indiquera que $x$ et $y$ sont éloignés.
Inversément, une petite valeur de retour indiquera qu'ils sont proches.
## Distance euclidienne
- calculer la distance entre un point a l'aide de la dst euclidienne et les centroides : sqrt((x2-x1)^2 + (y2-y1)^2) = sqrt((x-y)^2)
- comparer les dst qui séparent le point aux centroides
- assigner le point au centroide le plus proche
- faire ca pour tous les points
## Distance de Manhattan
- calculer la distance entre un point a l'aide de la dst euclidienne et les centroides : |(x2 - x1)| + |(y2-y1)|
- comparer les dst qui séparent le point aux centroides
- assigner le point au centroide le plus proche
- faire ca pour tous les points
## Fonctions à implémenter
Votre programme doit implémenter les fonctions suivantes :
- Définir _k_ centroide aleatoirement
- Calculer la distance euclidienne entre le centre d'un centroide et d'un point
- Calculer la nouvelle position d'un centroide (à partir de la moyenne des points)
- Lire un fichier contenant des points
- Déterminer les points appartenant aux closters
- Déterminer le K optimal (Elbow optimal, silhouette method, ...)
Ainsi que les structures ci-dessous :
```c
typedef struct _cluster {
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;
cluster clusters_array[k];
point** points_array;
} kmeans;
```
### centroides
- placer des centroides aléatoirement
- définir quels points appartient a quel centroide
- faire la moyenne de points qui sont egroupés à ce centroide
- changer les cordonnées des centroides
- répeter les actions jusqu'à que les cordonnées du centroides ne change pas
## Type de données
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 nos tests aux vecteurs à valeurs
naturelles, en 2 dimensions, pour en simplifier la visualisation
et la vérification de notre algorithme.
$$v \in \mathbb{N}^2$$
# Bonus
**BONUS 1** : étendre l'implémentation pour pouvoir utiliser des vecteurs
à $n$ dimensions avec $n$ passé en paramètre au début de la procédure.
**BONUS 2** : implémentation de l'algorithme PCA pour la visualisation
de vecteurs à plus de 2 dimensions.
## Interface utilisateur
Le programme fonctionnera entièrement en ligne de commande, avec possibilité
de spécifier un fichier d'entrée. A cette fin nous utiliserons des appels à
fscanf(...) et la lecture des arguments en ligne de commande.
Par défaut, le programme lira les données dans la console / sur
l'entrée standard (permet les "pipe").
# Vérification
## Validation des résultats
### Tester le bon choix des centres originaux
Pour un univers de densité relativement homogène, il ne devrait pas
y avoir de grand déséquilibre dans le nombre d'éléments par partition.
### Tester le partitionnement
Pour évaluer la justesse relative d'un résultat, pour un ensemble
de centres donné, il suffit de mesurer la distance de chaque point
à tous les centres.
De ces distances-là, si la plus petite n'est pas celle au centre du
groupe dont l'élément fait partie, il y a erreur.
## Validation de l'algorithme
Nous allons dans un premier temps utiliser des données générées
artificiellement et pré-labélisées.
Ainsi, si on se retrouve avec une correspondance exacte entre les labels
et les groupes, le test sera considéré comme validé.
Nous n'allons pas faire appel au pseudo-aléatoire dans un premier temps.
# Analyse
## De quoi dépend la qualité des résultats ?
Par qualité, nous entendons une bonne minimisation des distances
mentionnées plus haut.
- bon choix de centres initiaux
- nombre d'itérations suffisant
File deleted
readme.md 0 → 100644
% 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.
# 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.
![kmeans clustering](./img/kmeans_clustering.png)
## 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.
## 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_).
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).
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.
## 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.
Afin de quantifier la proximité de deux éléments entre eux, nous avons
besoin de définir une fonction distance, qui sera notre métrique.
Cette fonction distance peut retourner simplement une distance
de Manhattan ou une distance euclidienne et prend en argument deux vecteurs éléments de notre univers.
$$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 :
1. Calculer la distance entre le point et les _centroïdes_.
2. Comparer les distances pour déterminer le _centroïde_ le plus proche.
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} $$
### Distance de Manhattan
La distance de Manhattan ($D_m$) entre un point $x$ et $y$ correspond à :
$$ \vec{D_m} = |(x_2 - x_2)| + |(y_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.
## Interface utilisateur
Le programme fonctionnera entièrement en ligne de commande, avec possibilité
de spécifier un fichier d'entrée. À cette fin nous utiliserons des appels à
fscanf(...) et la lecture des arguments en ligne de commande.
Par défaut, le programme lira les données dans la console / sur
l'entrée standard (permet les "pipe").
## Déroulement de l'algorithme
Une fois nos données correctement chargées, il faudra appliquer l'algorithme des k-moyennes à ces dernières :
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.
5. Afficher les points et _clusters_ à l'écran (avec des couleurs !)
Il faudra utiliser la librairie gfx pour afficher vos résultats.
## 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, ...)
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.
É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.
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.
# Travail à rendre
- Le repos git contenant le code réalisé.
- Vous devrez également présenter votre travail à l'aide d'un support (Powerpoint par exemple).
# Travail suppémentaire possible
## Affichage en temps réel
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.
## Implémentation avec vecteurs à $n$ dimensions
Étendre l'implémentation pour pouvoir utiliser des vecteurs
à $n$ dimensions avec $n$ passé en paramètre au début de la procédure.
Afin de pouvoir visualiser les résultats, vous devrez également implémenter l'algorithme PCA pour la visualisation de vecteurs à plus de 2 dimensions.
\ No newline at end of file
File added
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment