diff --git a/DevEfficace/rapport.md b/DevEfficace/rapport.md index 57e2c8bb503e8153ea05fd21d650bed7563c12c6..88110653b61e7e6f0c763359c635fd4c21e7f0a6 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 9a220bdf4e1c24f8db37dad2a63785c1c25873de..4d38f1f0d7b078b7a5511cae8186bc47f2b122cf 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 686303ccf2d4e88c048c40d37c40ebe7719370b4..c27e2df513ced5ab0a53559accbdfc9317c5b0e5 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 403e01cbbfdc0b1b94d65de4ec9196c80d43878a..f37d5519057e01c16df3f10d791c0be0ed0059cc 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 fbf1734713ae37b123b20e4f9f1f06cbfce9fe32..381a19395a1d8a97109f3fc46d247ee2851b57e2 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 d1b6696c9a3b53870870913fb953e819b3f1a413..90d43b00dd0e2d417e23a711af22a552310dea44 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 7ac5fad96ac847d5199b969014b9c3f852fa4e79..faec110043fb617da86efbef5e0f752c7b57bed7 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 2217c066ed36bdc8b7c4522533f301623810569e..aeb72aafad696eafd60fb055824fe9bc837cf1bf 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); }