Implémentation de l’algorithme K-Means en java (partie 2)
par
, 29/04/2020 à 08h22 (904 Affichages)
Pour faire suite à la partie 1 voici mon implémentation des objets Point et Centroïde
1/ Point
Cet objet permet de stocker les coordonnées 2D d’un individu et de mesurer sa distance à un autre point. J’aurais pu spécialiser la classe abstraite Point2D du package AWT, mais seule la méthode getDistance() nous servira. D’autant que dans un souci de généricité et à l’aide des patrons de conceptions nous pourrons à terme remplacer Point par une unité de stockage de dimension plus importante ou dont les métrique reposent sur des échelles discrètes. Mais pour cette série de d’article je me limiterai à un plan euclidien afin de pouvoir étendre le spectre étudié jusqu’à la représentation graphique en Swing/javaFX voire, s’il y a un public intéressé, à la visualisation web.
2/ Centroïde
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getDistance(Point P) { double dist = Math.sqrt(Math.pow(P.getX() - this.getX(), 2) + Math.pow(P.getY() - this.getY(), 2)); return dist; } public double getX() { return x; } public double getY() { return y; } @Override public String toString() { return "Point [x=" + x + ", y=" + y + "]"; } }
Cet objet est structurellement composé de ses propres coordonnées et du cluster de points dont il est le plus proche, soit respectivement :
- Center un objet de type Point
- Sector une collection de points
Le Centroïde à vocation à renouveler son cluster à chaque itération de l’étape d’assignation. C’est la raison pour laquelle il existe une méthode de vidage du cluster empty().
Le centroïde possède également une méthode qui retourne le barycentre de son cluster. J’ai volontairement écrit cette méthode en invoquant sur les collections des méthodes utilisant les lambda-expressions introduite depuis Java 8. L’intérêt pour moi est de faire passer sur ce code source mon transpiler qui converti le Java en JS et ainsi pouvoir pré-mâcher le portage de cette mini-appli java vers ce que je pratique au quotidien (Angular Node). Et l’intérêt pour les lecteurs est de découvrir cette approche fonctionnelle du code. Mais je m’y engage, je ferai les prochaines classes en Java 5 traditionnel si cher au cœur des développeurs JEE. N’hésitez pas à me demander si vous souhaitez une version traditionnelle de cette méthode… ou si au contraire vous plébiscitez cette notation.
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class Centroide { private List<Point> sector; private Point center; public Centroide(Point center) { this.center = center; this.sector = new ArrayList<Point>(); } public Point getCenter() { return center; } public void setCenter(Point center) { this.center = center; } public List<Point> getSector() { return sector; } public void empty() { this.sector.clear(); } public void add (Point p) { this.sector.add(p); } public Point getBarycenter() { double Abs = this.sector.stream().map(element -> element.getX()).reduce(Double.valueOf(0), (subtotal, element) -> subtotal + element)/this.sector.size(); double Ord = this.sector.stream().map(element -> element.getY()).reduce(Double.valueOf(0), (subtotal, element) -> subtotal + element)/this.sector.size(); Point p = new Point(Abs, Ord); return p; } @Override public String toString() { return "Centroide [sector=" + sector + ", center=" + center + "]"; } }
Dans la partie 3 je vous livrerai la dernière classe DataSet et peut être une autre si je découvre qu’elle n’est pas suffisante pour totalement implémenter l'algorithme