From 13ae2147fdb725de17e5140689da6ec50db7b0c0 Mon Sep 17 00:00:00 2001
From: Numbtus <matias.mennecart.etu@univ-lille.fr>
Date: Fri, 29 Nov 2024 11:10:58 +0100
Subject: [PATCH] debut d'implemenation du choix de l'attribut de
 classification

---
 DevEfficace/rapport.md                        |  5 +-
 .../controller/AddDataController.java         | 95 ++++++++++---------
 .../sae/classification/knn/MethodKNN.java     | 17 +---
 .../model/ClassificationModel.java            |  8 +-
 .../sae/classification/model/Iris.java        | 10 ++
 .../classification/model/LoadableData.java    |  8 +-
 .../sae/classification/model/Pokemon.java     | 48 ++++++++--
 .../sae/classification/utils/ViewUtil.java    |  6 +-
 8 files changed, 125 insertions(+), 72 deletions(-)

diff --git a/DevEfficace/rapport.md b/DevEfficace/rapport.md
index 57e2c8b..8811065 100644
--- a/DevEfficace/rapport.md
+++ b/DevEfficace/rapport.md
@@ -120,7 +120,10 @@ On obtient donc un taux de reussiste plutôt élevé. A chaque fois l'algorithme
 | Distance Manhattan Normalisée | 0.178 | 0.188 | 0.2 | 0.215 | 0.205 | 0.203 | 0.194 | 0.190 | 0.184 | 0.180 | 0.190 | 7 |
 ---
 
-ajoyter un commentaire sur les resultats
+Le taux de reussiste est ici plus bas, cela s'explique notement par le nombre d'attribut different et la complexité a identifier le type d'un pokemon. 
+Cependant le taux de reussiste reste satisfaisant et stable.
+
+Classification par isLegendary
 
 ## Efficacité
 
diff --git a/src/main/java/fr/univlille/sae/classification/controller/AddDataController.java b/src/main/java/fr/univlille/sae/classification/controller/AddDataController.java
index 9a220bd..4d38f1f 100644
--- a/src/main/java/fr/univlille/sae/classification/controller/AddDataController.java
+++ b/src/main/java/fr/univlille/sae/classification/controller/AddDataController.java
@@ -45,56 +45,61 @@ public class AddDataController {
         ClassificationModel model = ClassificationModel.getClassificationModel();
         if (!model.getDatas().isEmpty()) {
             Map<String, Object> attrMap = model.getDatas().get(0).getAttributesNames();
+            int classificationType = model.getDatas().get(0).getClassificationType();
             for (Map.Entry<String, Object> entry : attrMap.entrySet()) {
                 String attrName = entry.getKey();
                 Object attrValue = entry.getValue();
 
-                Label label = new Label(attrName);
-                HBox hbox = new HBox(10, label);
-                hbox.setAlignment(Pos.CENTER);
-                hbox.setSpacing(10);
-
-                if (attrValue instanceof Double) {
-                    Spinner<Double> doubleSpinner = new Spinner<>();
-                    doubleSpinner.setEditable(true);
-                    SpinnerValueFactory<Double> valueFactory =
-                            new SpinnerValueFactory.DoubleSpinnerValueFactory(
-                                    0.0,
-                                    9999,
-                                    0.0,
-                                    0.5
-                            );
-                    doubleSpinner.setValueFactory(valueFactory);
-                    hbox.getChildren().add(doubleSpinner);
-                    components.add(doubleSpinner);
-                }
-                else if (attrValue instanceof Integer) {
-                    Spinner<Integer> integerSpinner = new Spinner<>();
-                    integerSpinner.setEditable(true);
-                    SpinnerValueFactory<Integer> valueFactory =
-                            new SpinnerValueFactory.IntegerSpinnerValueFactory(
-                                    0,
-                                    Integer.MAX_VALUE,
-                                    0,
-                                    1
-                            );
-                    integerSpinner.setValueFactory(valueFactory);
-                    hbox.getChildren().add(integerSpinner);
-                    components.add(integerSpinner);
-                }
-                else if (attrValue instanceof String) {
-                    TextField textField = new TextField();
-                    hbox.getChildren().add(textField);
-                    components.add(textField);
-                }
-                else if (attrValue instanceof Boolean) {
-                    ChoiceBox<String> choiceBox = new ChoiceBox<>();
-                    choiceBox.getItems().addAll("VRAI", "FAUX");
-                    choiceBox.setValue("VRAI");
-                    hbox.getChildren().add(choiceBox);
-                    components.add(choiceBox);
+                if(!attrMap.keySet().toArray()[classificationType].equals(attrName))  {
+                    Label label = new Label(attrName);
+                    HBox hbox = new HBox(10, label);
+                    hbox.setAlignment(Pos.CENTER);
+                    hbox.setSpacing(10);
+
+                    if (attrValue instanceof Double) {
+                        Spinner<Double> doubleSpinner = new Spinner<>();
+                        doubleSpinner.setEditable(true);
+                        SpinnerValueFactory<Double> valueFactory =
+                                new SpinnerValueFactory.DoubleSpinnerValueFactory(
+                                        0.0,
+                                        9999,
+                                        0.0,
+                                        0.5
+                                );
+                        doubleSpinner.setValueFactory(valueFactory);
+                        hbox.getChildren().add(doubleSpinner);
+                        components.add(doubleSpinner);
+                    }
+                    else if (attrValue instanceof Integer) {
+                        Spinner<Integer> integerSpinner = new Spinner<>();
+                        integerSpinner.setEditable(true);
+                        SpinnerValueFactory<Integer> valueFactory =
+                                new SpinnerValueFactory.IntegerSpinnerValueFactory(
+                                        0,
+                                        Integer.MAX_VALUE,
+                                        0,
+                                        1
+                                );
+                        integerSpinner.setValueFactory(valueFactory);
+                        hbox.getChildren().add(integerSpinner);
+                        components.add(integerSpinner);
+                    }
+                    else if (attrValue instanceof String) {
+                        TextField textField = new TextField();
+                        hbox.getChildren().add(textField);
+                        components.add(textField);
+                    }
+                    else if (attrValue instanceof Boolean) {
+                        ChoiceBox<String> choiceBox = new ChoiceBox<>();
+                        choiceBox.getItems().addAll("VRAI", "FAUX");
+                        choiceBox.setValue("VRAI");
+                        hbox.getChildren().add(choiceBox);
+                        components.add(choiceBox);
+                    }
+                    entries.getChildren().add(hbox);
                 }
-                entries.getChildren().add(hbox);
+
+
             }
         }
     }
diff --git a/src/main/java/fr/univlille/sae/classification/knn/MethodKNN.java b/src/main/java/fr/univlille/sae/classification/knn/MethodKNN.java
index 686303c..c27e2df 100644
--- a/src/main/java/fr/univlille/sae/classification/knn/MethodKNN.java
+++ b/src/main/java/fr/univlille/sae/classification/knn/MethodKNN.java
@@ -51,15 +51,6 @@ public class MethodKNN {
         }
     }
 
-    /**
-     * Permet de recuperer les K-voisins les plus proches d'une données dans un jeu de données
-     * en fonction d'une Distance.
-     * @param datas Le jeu de données
-     * @param data  La donnée avec laquelle calculer la distance
-     * @param k     Le nombre de voisins a recupérer
-     * @param distance
-     * @return
-     */
     public static List<LoadableData> kVoisins(List<LoadableData> datas, LoadableData data, int k, Distance distance) {
 
         // On recupere toutes les données
@@ -77,7 +68,7 @@ public class MethodKNN {
 
 
 
-    public static String estimateClass(List<LoadableData> datas, LoadableData data, int k, Distance distance) {
+    public static String estimateClass(List<LoadableData> datas, LoadableData data, int k, Distance distance) throws IllegalAccessException {
 
         // On recupere les K voisions  de data.
         List<LoadableData> kVoisins = MethodKNN.kVoisins(datas, data, k, distance);
@@ -105,7 +96,7 @@ public class MethodKNN {
     }
 
 
-    public static int bestK(List<LoadableData> datas, Distance distance) {
+    public static int bestK(List<LoadableData> datas, Distance distance) throws IllegalAccessException {
         // On borne le K pour eviter de trouver un K trop grand
         int maxK = (int) (Math.sqrt(datas.size()));
         System.out.println("Max k: " + maxK);
@@ -128,7 +119,7 @@ public class MethodKNN {
     }
 
 
-    public static double robustesse(List<LoadableData> datas, int k, Distance distance, double testPart) {
+    public static double robustesse(List<LoadableData> datas, int k, Distance distance, double testPart) throws IllegalAccessException {
 
 
 
@@ -167,7 +158,7 @@ public class MethodKNN {
         return taux/(1/testPart);
     }
 
-    public static void main(String[] args) throws CsvRequiredFieldEmptyException {
+    public static void main(String[] args) throws CsvRequiredFieldEmptyException, IllegalAccessException {
 
         //Test de la robustesse et du meillleur K
 
diff --git a/src/main/java/fr/univlille/sae/classification/model/ClassificationModel.java b/src/main/java/fr/univlille/sae/classification/model/ClassificationModel.java
index 403e01c..f37d551 100644
--- a/src/main/java/fr/univlille/sae/classification/model/ClassificationModel.java
+++ b/src/main/java/fr/univlille/sae/classification/model/ClassificationModel.java
@@ -101,6 +101,8 @@ public class ClassificationModel extends Observable {
             notifyObservers();
         } catch (IOException e) {
             System.err.println("Erreur lors du chargement des données : " + e.getMessage());
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -121,7 +123,11 @@ public class ClassificationModel extends Observable {
     public void classifierDonnee(LoadableData data) {
         if(dataToClass.get(data) != null && dataToClass.get(data)) return;
         this.dataToClass.remove(data);
-        data.setClassification(MethodKNN.estimateClass(datas, data, k, distance));
+        try {
+            data.setClassification(MethodKNN.estimateClass(datas, data, k, distance));
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
         notifyObservers(data);
         dataToClass.put(data, true);
     }
diff --git a/src/main/java/fr/univlille/sae/classification/model/Iris.java b/src/main/java/fr/univlille/sae/classification/model/Iris.java
index fbf1734..381a193 100644
--- a/src/main/java/fr/univlille/sae/classification/model/Iris.java
+++ b/src/main/java/fr/univlille/sae/classification/model/Iris.java
@@ -68,6 +68,16 @@ public class Iris extends LoadableData {
         return variety;
     }
 
+    @Override
+    public Map<String, Object> getClassifiedAttributes() {
+        return Map.of();
+    }
+
+    @Override
+    public int getClassificationType() {
+        return 0;
+    }
+
     /**
      * Définit la classification (variété) de l'Iris.
      * @param classification variété à définir.
diff --git a/src/main/java/fr/univlille/sae/classification/model/LoadableData.java b/src/main/java/fr/univlille/sae/classification/model/LoadableData.java
index d1b6696..90d43b0 100644
--- a/src/main/java/fr/univlille/sae/classification/model/LoadableData.java
+++ b/src/main/java/fr/univlille/sae/classification/model/LoadableData.java
@@ -29,7 +29,7 @@ public abstract class LoadableData {
      * Renvoie la classification de l'objet.
      * @return classification sous forme de chaîne.
      */
-    public abstract String getClassification();
+    public abstract String getClassification() throws IllegalAccessException;
 
     /**
      * Renvoie les types de classification définis.
@@ -97,11 +97,15 @@ public abstract class LoadableData {
 
     */
 
+    public abstract Map<String, Object> getClassifiedAttributes();
+
+    public abstract int getClassificationType() ;
+
     /**
      * Définit la classification de l'objet.
      * @param classification classification à définir.
      */
-    public abstract void setClassification(String classification);
+    public abstract void setClassification(String classification) throws IllegalAccessException;
 
     public abstract Map<String, Object> getAttributesNames();
 
diff --git a/src/main/java/fr/univlille/sae/classification/model/Pokemon.java b/src/main/java/fr/univlille/sae/classification/model/Pokemon.java
index 7ac5fad..faec110 100644
--- a/src/main/java/fr/univlille/sae/classification/model/Pokemon.java
+++ b/src/main/java/fr/univlille/sae/classification/model/Pokemon.java
@@ -1,9 +1,8 @@
 package fr.univlille.sae.classification.model;
 
 import com.opencsv.bean.CsvBindByName;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
+
+import java.util.*;
 
 public class Pokemon extends LoadableData{
 
@@ -37,6 +36,7 @@ public class Pokemon extends LoadableData{
     @CsvBindByName(column = "is_legendary")
     private boolean isLegendary;
 
+    private int classificationType = 5;
 
     public Pokemon(String name, int attack, int baseEggSteps, double captureRate, int defense, int experienceGrowth, int hp, int spAttack, int spDefense, String type1, String type2, double speed, boolean isLegendary) {
         super();
@@ -76,8 +76,8 @@ public class Pokemon extends LoadableData{
      * @return classification sous forme de chaîne.
      */
     @Override
-    public String getClassification() {
-        return type1;
+    public String getClassification() throws IllegalAccessException {
+        return (String) this.getClass().getDeclaredFields()[classificationType].get(this).toString();
     }
 
     /**
@@ -86,10 +86,42 @@ public class Pokemon extends LoadableData{
      * @param classification classification à définir.
      */
     @Override
-    public void setClassification(String classification) {
-        this.type1 = classification;
+    public void setClassification(String classification) throws IllegalAccessException {
+       this.getClass().getDeclaredFields()[classificationType].set("", classification);
+    }
+
+
+    /**
+     * Permet de modifier l'attribut sur lequelle ont souhaite classifier
+     * Ne sont valable que les attributs present dans getClassificationAttributes()
+     *
+     * Le numéro de l'attribut correspond a sa place dans la liste de tous le attributs.
+     * @param classificationType
+     */
+    public void setClassificationType(int classificationType) throws IllegalArgumentException{
+        if(classificationType < 0 || classificationType > getAttributesNames().size()) throw new IllegalArgumentException("Cette attribut n'existe pas");
+        if(getClassifiedAttributes().containsKey(getAttributesNames().keySet().toArray()[classificationType])) throw new IllegalArgumentException("Cette attribut ne peut pas être utiliser pour la classification");
+        this.classificationType = classificationType;
+    }
+
+
+
+
+    public Map<String, Object> getClassifiedAttributes() {
+        Map<String, Object> attributes = new HashMap<>();
+
+        attributes.put("Experience growth", experienceGrowth);
+        attributes.put("Type 1", type1);
+        attributes.put("Type 2", type2);
+        attributes.put("Is legendary", isLegendary);
+
+        return attributes;
     }
 
+    @Override
+    public int getClassificationType() {
+        return classificationType;
+    }
 
     /**
      * Renvoie les noms des attributs de l'objet.
@@ -109,6 +141,8 @@ public class Pokemon extends LoadableData{
         attrNames.put("HP", hp);
         attrNames.put("Special attack", spAttack);
         attrNames.put("Special defense", spDefense);
+        attrNames.put("Type 1", type1);
+        attrNames.put("Type 2", type2);
         attrNames.put("Speed", speed);
         attrNames.put("Is legendary", isLegendary);
         return attrNames;
diff --git a/src/main/java/fr/univlille/sae/classification/utils/ViewUtil.java b/src/main/java/fr/univlille/sae/classification/utils/ViewUtil.java
index 2217c06..aeb72aa 100644
--- a/src/main/java/fr/univlille/sae/classification/utils/ViewUtil.java
+++ b/src/main/java/fr/univlille/sae/classification/utils/ViewUtil.java
@@ -87,9 +87,9 @@ public class ViewUtil {
 
                 tempHBox = new HBox();
                 label = new Label(colorsString[i+j]);
-                rectangle = new Rectangle(10, 10);
-                rectangle.setFill(colors.get(colorsString[i+j]));
-                tempHBox.getChildren().addAll(rectangle, label);
+                Circle circle = new Circle(5);
+                circle.setFill(colors.get(colorsString[i+j]));
+                tempHBox.getChildren().addAll(circle, label);
                 line.getChildren().add(tempHBox);
 
             }
-- 
GitLab