/** * @param individual The derivation to be tested. * @param d The features used to test the derivation. * @return A list with the test results. * @throws GggpExceptionImpl */ public List<Integer> test(Derivation individual, DoubleMatrix2D d) throws GggpExceptionImpl { List<Integer> res = null; Collection<AuxFeatureFitnessImpl> auxFit; Iterator<AuxFeatureFitnessImpl> itAux; AuxFeatureFitnessImpl auxFitE; Collection<Rules> cr; Iterator<Rules> itr; Rules r; int normalClass; int injuryClass; int fit; int falsePositive; int falseNegative; int indefined; boolean evaluation; if ((individual != null) && (d != null)) { auxFitE = new AuxFeatureFitnessImpl(); auxFit = auxFitE.mapFeaturesWithLabel(d); cr = parseRules(individual, "real"); itAux = auxFit.iterator(); fit = 0; falsePositive = 0; falseNegative = 0; indefined = 0; /** * To each feature, all the rules are applied. Only the rules that returns TRUE are * considered, and in function of the class (normal or injury) associated to the rule, one of * two variables are incremented ("normalClass" = normal class, and "injuryClass" = normal * class). At the end, the result is classified in FIT (a right prognosis), FALSE_NEGATIVE, * FALSE_POSITIVE or INDEFINED. */ while (itAux.hasNext()) { auxFitE = itAux.next(); itr = cr.iterator(); normalClass = 0; injuryClass = 0; while (itr.hasNext()) { r = itr.next(); evaluation = r.evaluatesRule(auxFitE.getFeatures(), r.getAntecedent()); if (evaluation) { if (((r.getConsecuent()).toUpperCase()).equals("NORMAL")) { normalClass++; } else { injuryClass++; } } } /** Classification of the results. */ if (auxFitE.getLabel().equals(new Double(0))) { if (normalClass > injuryClass) { fit++; } else { if (normalClass < injuryClass) { falsePositive++; } else { indefined++; } } } else { if (injuryClass > normalClass) { fit++; } else { if (injuryClass < normalClass) { falseNegative++; } else { indefined++; } } } } res = new LinkedList<Integer>(); /** Add the amount of classified items (series). */ res.add(new Integer(d.rows())); /** Add the amount of right prognosis (FIT). */ res.add(new Integer(fit)); /** Add the amount of false negatives. */ res.add(new Integer(falseNegative)); /** Add the amount of false positives. */ res.add(new Integer(falsePositive)); /** Add the amount of indefined. */ res.add(new Integer(indefined)); } return res; }
/** * The function calculates for each derivation (d) that belongs to "individuals", the * entropy-based fitness function of the rule set associated to d, over the isokinetic curves * sample set "features". * * @param individuals The derivations with the rule set associated to each one. * @param features The sample set of isokinetic curves. */ private Map<Derivation, Double> fitness( Collection<Derivation> individuals, DoubleMatrix2D features, boolean applyEnt) throws GggpExceptionImpl { Map<Derivation, Double> res = null; Collection<AuxFeatureFitnessImpl> auxFit; Iterator<AuxFeatureFitnessImpl> itAux; AuxFeatureFitnessImpl auxFitE; Iterator<Derivation> it; Derivation d; Collection<Rules> cr; Iterator<Rules> itr; Rules r; int normalClass; int injuryClass; double notSuccess; boolean evaluation; double success; double ebff; double efc; double H; double auxFitness; if ((individuals != null) && (features != null)) { auxFit = new LinkedList<AuxFeatureFitnessImpl>(); auxFitE = new AuxFeatureFitnessImpl(); auxFit = auxFitE.mapFeaturesWithLabel(this.getFeatures()); res = new ConcurrentHashMap<Derivation, Double>(); it = individuals.iterator(); while (it.hasNext()) { d = it.next(); cr = parseRules(d, "real"); itAux = auxFit.iterator(); success = 0; H = 0; /** * To each isokinetic curve auxFitE, all the DB's rules are applied. Only the rules that * returns TRUE are considered, and depending of the class (normal or injury) associated to * the rule and to auxFitE, one of two variables are incremented ("normalClass" = normal * class, and "injuryClass" = normal class). At the end, the class with more hits is * returned. */ while (itAux.hasNext()) { auxFitE = itAux.next(); itr = cr.iterator(); normalClass = 0; injuryClass = 0; notSuccess = 0; /** Applies all the rules over the isokinetic curve auxFiteE */ while (itr.hasNext()) { r = itr.next(); evaluation = r.evaluatesRule(auxFitE.getFeatures(), r.getAntecedent()); if (evaluation) { if (((r.getConsecuent()).toUpperCase()).equals("NORMAL")) { if (auxFitE.getLabel().equals(new Double(1))) { /** The rule misclassify the isokinetic curve. */ notSuccess++; } normalClass++; } else { if (auxFitE.getLabel().equals(new Double(0))) { /** The rule misclassify the isokinetic curve. */ notSuccess++; } injuryClass++; } } } if (applyEnt) { if (cr.size() != 0) { /** * The entropy function component of the rule set over the isokinetic curve auxFitE. */ efc = notSuccess / (2 * cr.size()); } else { efc = 0; } /** * The entropy funtion of the distribution of the rule set's non success results, over * the sample of isokinect curves. */ if (efc != 0) { H = H - efc * Math.log(efc); } } /** * Classification of the result, that is: if the rules made a right prognosis, increment * success, otherwise it does nothing. */ if (auxFitE.getLabel().equals(new Double(0))) { if (normalClass > injuryClass) { /** The rule set classify properly the isokinetic curve. */ success++; } } else { if (injuryClass > normalClass) { /** The rule set classify properly the isokinetic curve. */ success++; } } } if (applyEnt) { auxFitness = (success - H); } else { auxFitness = success; } if (auxFitness != 0) { /** * The entropy-based fitness function of the rule set over the isokinetic curves sample * set. */ ebff = auxFitness / features.rows(); } else { ebff = 0; } res.put(d, ebff); } } return res; }
/** * @param fileGrammar The path and name of the file with the Grammar's definition. * @param fileFeaturesTotal The path and name of the file with the features in order to calculate * the initial values for the initial population. * @param fileFeaturesTrain The path and name of the file with the features in order to train the * GGGP system. * @param cols The column's amount of fileFeatures (18). * @param sizeP The GGGP System's size population (200). * @param maxDepth Maximum Depth of the Derivations (10). * @param symbol The Element's symbol to which the Evolutionary Gradient will be applied ("real"). * @param symbol2 The Element's symbol which has the name of the feature, for which the * Evolutionary Gradient is looking for a real value that will be used in a rule ("TV1"). * @param K The parameter used in the Tournament operator. * @param perBest If elitism'll be applied, the parameters defines which percentage of the current * generation'll survive in the next (the survivals are selected by theirs fitness,ie, only * the individuals with the best fitness are selected). * @param elitism It defines if elitism is applied or not. * @param amountIter It defines the maximum amount of training's iterations. * @param percentage It defines the maximum fitness to be reached, ie, if the training process * reach this fitness the process is stopped. * @param applyEnt It defines if apply Entropy or not in the fitness calculation. * @return The Derivation (the best individual) that results from the training process. * @throws GggpExceptionImpl */ public Collection<Derivation> train( String fileGrammar, String fileFeaturesTotal, String fileFeaturesTrain, int cols, int sizeP, int maxDepth, String symbol, int symbol2, int K, int perBest, boolean elitism, int amountIter, double percentage, boolean applyEnt) throws GggpExceptionImpl { Runtime rt = Runtime.getRuntime(); List<Object> parameters; Map<String, Double> feat; Collection<Derivation> newIndividuals; @SuppressWarnings("unused") Collection<Derivation> newPopulation = null; @SuppressWarnings("unused") Collection<Derivation> matingPool; int auxAmountIter; AuxFeatureFitnessImpl auxFitE; double currentPer; Map<Derivation, Double> currentFitness; /** Load the features of the training items with theirs labels . */ this.loadFeatures(fileFeaturesTrain, null); /** Load the Grammar associated to the GGGP System . */ this.loadGrammar(fileGrammar); /** ################### START INIT POPULATION ################## * */ parameters = new LinkedList<Object>(); /** The function DELTA to be used in the Evolutionary Gradient. */ parameters.add(new FunctionImpl()); /** Size of the GGGP System's Population. */ parameters.add(new Integer(sizeP)); /** Maximum Depth of the Derivations. */ parameters.add(new Integer(maxDepth)); /** The Element's symbol to which the Evolutionary Gradient will be applied . */ parameters.add(symbol); /** * The Element's symbol which has the name of the feature, for which the Evolutionary Gradient * is looking for a real value that will be used in a rule. */ parameters.add(symbol2); /** * Feat is the mapping from the name of each feature to his average real value in the training * and test items. */ auxFitE = new AuxFeatureFitnessImpl(); feat = auxFitE.featuresInitialValues(fileFeaturesTotal); parameters.add(feat); /** It creates the initial GGGP System's population. */ newIndividuals = null; newIndividuals = this.initPopulation(2, parameters); parameters = null; parameters = new LinkedList<Object>(); parameters.add(new Boolean(applyEnt)); currentFitness = this.fitness(newIndividuals, this.getFeatures(), parameters); currentPer = java.util.Collections.max(currentFitness.values()); this.setFitness(currentFitness); /** ################### END INIT POPULATION ################## * */ /** ################### START THE TRAINING PROCESS ################### */ auxAmountIter = 1; while ((auxAmountIter <= amountIter) && (currentPer < percentage)) { System.out.println("Iteration number: " + auxAmountIter); auxAmountIter++; /** ################### START CREATE MATING POOL ################## * */ parameters = null; parameters = new LinkedList<Object>(); /** The parameter K used in the Tournament operator. */ parameters.add(new Integer(K)); /** The name of the file with the features of the training items. */ parameters.add(fileFeaturesTrain); /** The amount of columns of the file with the features of the training items. */ parameters.add(new Integer(cols)); /** If apply entropy or not in fitness calculation. */ parameters.add(new Boolean(applyEnt)); /** It creates the mating pool from the current GGGP System's population. */ matingPool = null; matingPool = this.parentSelection(this.getPopulation(), null, this.getFitness(), sizeP, 1, parameters); /** ################### END CREATE MATING POOL ################## * */ /** ################### START CREATE POPULATION'S NEXT GENERATION ################## * */ parameters = null; parameters = new LinkedList<Object>(); /** The crossover method. */ parameters.add(new Integer(2)); /** Maximum Depth of the Derivations. */ parameters.add(new Integer(maxDepth)); /** The Element's symbol to which the Evolutionary Gradient will be applied . */ parameters.add(symbol); /** It creates the next generation of individuals from the mating pool . */ newIndividuals = null; newIndividuals = this.nextGeneration(this.getMatingPool(), parameters); /** ################### END CREATE POPULATION'S NEXT GENERATION ################## * */ /** ################### START CHANGE CURRENT POPULATION ################## * */ newPopulation = null; newPopulation = this.survivalSelection(this.getPopulation(), newIndividuals, 1, null, elitism, perBest); try { this.clearStructures(rt); } catch (GrammarExceptionImpl ex) { } this.setPopulation(newPopulation); parameters = null; parameters = new LinkedList<Object>(); parameters.add(new Boolean(applyEnt)); currentFitness = this.fitness(newPopulation, this.getFeatures(), parameters); currentPer = java.util.Collections.max(currentFitness.values()); this.setFitness(currentFitness); /** ################### END CHANGE CURRENT POPULATION ################## * */ } /** ################### END THE TRAINING PROCESS ################### */ System.out.println(); System.out.println("The TRAIN Maximum Fitness is: " + currentPer); return newPopulation; }