source: trunk/CrossPare/src/de/ugoe/cs/cpdp/training/GPTraining.java @ 110

Last change on this file since 110 was 110, checked in by atrautsch, 8 years ago

docfix

File size: 29.5 KB
Line 
1package de.ugoe.cs.cpdp.training;
2
3import java.util.LinkedList;
4import java.util.List;
5
6import org.apache.commons.collections4.list.SetUniqueList;
7
8import weka.classifiers.AbstractClassifier;
9import weka.classifiers.Classifier;
10import weka.core.Instance;
11import weka.core.Instances;
12import org.apache.commons.lang3.ArrayUtils;
13import org.jgap.Configuration;
14import org.jgap.InvalidConfigurationException;
15import org.jgap.gp.CommandGene;
16import org.jgap.gp.GPProblem;
17
18import org.jgap.gp.function.Add;
19import org.jgap.gp.function.Multiply;
20import org.jgap.gp.function.Log;
21import org.jgap.gp.function.Subtract;
22import org.jgap.gp.function.Divide;
23import org.jgap.gp.function.Sine;
24import org.jgap.gp.function.Cosine;
25import org.jgap.gp.function.Max;
26import org.jgap.gp.function.Exp;
27
28import org.jgap.gp.impl.DeltaGPFitnessEvaluator;
29import org.jgap.gp.impl.GPConfiguration;
30import org.jgap.gp.impl.GPGenotype;
31import org.jgap.gp.impl.TournamentSelector;
32import org.jgap.gp.terminal.Terminal;
33import org.jgap.gp.GPFitnessFunction;
34import org.jgap.gp.IGPProgram;
35import org.jgap.gp.terminal.Variable;
36import org.jgap.gp.MathCommand;
37import org.jgap.util.ICloneable;
38
39import de.ugoe.cs.cpdp.util.WekaUtils;
40
41import org.jgap.gp.impl.ProgramChromosome;
42import org.jgap.util.CloneException;
43
44/**
45 * Genetic Programming Trainer
46 *
47 * Implementation (mostly) according to Liu et al. Evolutionary Optimization of Software Quality Modeling with Multiple Repositories.
48 *
49 * - GPRun is a Run of a complete Genetic Programm Evolution, we want several complete runs.
50 * - GPVClassifier is the Validation Classifier
51 * - GPVVClassifier is the Validation-Voting Classifier
52 *
53 *  config: <setwisetrainer name="GPTraining" param="populationSize:1000,numberRuns:10" />
54 */
55public class GPTraining implements ISetWiseTrainingStrategy, IWekaCompatibleTrainer  {
56   
57    private GPVVClassifier classifier = null;
58   
59    // default values from the paper
60    private int populationSize = 1000;
61    private int initMinDepth = 2;
62    private int initMaxDepth = 6;
63    private int tournamentSize = 7;
64    private int maxGenerations = 50;
65    private double errorType2Weight = 15;
66    private int numberRuns = 20;  // im paper 20 per errorType2Weight then additional 20
67    private int maxDepth = 20;  // max depth within one program
68    private int maxNodes = 100;  // max nodes within one program
69
70    @Override
71    public void setParameter(String parameters) {
72       
73        String[] params = parameters.split(",");
74        String[] keyvalue = new String[2];
75
76        for(int i=0; i < params.length; i++) {
77            keyvalue = params[i].split(":");
78           
79            switch(keyvalue[0]) {
80                case "populationSize":
81                    this.populationSize = Integer.parseInt(keyvalue[1]);
82                break;
83               
84                case "initMinDepth":
85                    this.initMinDepth = Integer.parseInt(keyvalue[1]);
86                break;
87               
88                case "tournamentSize":
89                    this.tournamentSize = Integer.parseInt(keyvalue[1]);
90                break;
91               
92                case "maxGenerations":
93                    this.maxGenerations = Integer.parseInt(keyvalue[1]);
94                break;
95               
96                case "errorType2Weight":
97                    this.errorType2Weight = Double.parseDouble(keyvalue[1]);
98                break;
99               
100                case "numberRuns":
101                    this.numberRuns = Integer.parseInt(keyvalue[1]);
102                break;
103               
104                case "maxDepth":
105                    this.maxDepth = Integer.parseInt(keyvalue[1]);
106                break;
107               
108                case "maxNodes":
109                    this.maxNodes = Integer.parseInt(keyvalue[1]);
110                break;
111            }
112        }
113       
114        this.classifier = new GPVVClassifier();
115        ((GPVClassifier)this.classifier).configure(populationSize, initMinDepth, initMaxDepth, tournamentSize, maxGenerations, errorType2Weight, numberRuns, maxDepth, maxNodes);
116    }
117
118    @Override
119    public void apply(SetUniqueList<Instances> traindataSet) {
120        try {
121            classifier.buildClassifier(traindataSet);
122        }catch(Exception e) {
123            throw new RuntimeException(e);
124        }
125    }
126
127    @Override
128    public String getName() {
129        return "GPTraining";
130    }
131
132    @Override
133    public Classifier getClassifier() {
134        return this.classifier;
135    }
136   
137    public class InstanceData {
138        private double[][] instances_x;
139        private boolean[] instances_y;
140       
141        public InstanceData(Instances instances) {
142            this.instances_x = new double[instances.numInstances()][instances.numAttributes()-1];
143            this.instances_y = new boolean[instances.numInstances()];
144           
145            Instance current;
146            for(int i=0; i < this.instances_x.length; i++) {
147                current = instances.get(i);
148                this.instances_x[i] = WekaUtils.instanceValues(current);
149                this.instances_y[i] = 1.0 == current.classValue();
150            }
151        }
152       
153        public double[][] getX() {
154            return instances_x;
155        }
156        public boolean[] getY() {
157            return instances_y;
158        }
159    }
160   
161    /**
162     * One Run executed by a GP Classifier
163     */
164    public class GPRun extends AbstractClassifier {
165        private static final long serialVersionUID = -4250422550107888789L;
166
167        private int populationSize;
168        private int initMinDepth;
169        private int initMaxDepth;
170        private int tournamentSize;
171        private int maxGenerations;
172        private double errorType2Weight;
173        private int maxDepth;
174        private int maxNodes;
175       
176        private GPGenotype gp;
177        private GPProblem problem;
178       
179        public void configure(int populationSize, int initMinDepth, int initMaxDepth, int tournamentSize, int maxGenerations, double errorType2Weight, int maxDepth, int maxNodes) {
180            this.populationSize = populationSize;
181            this.initMinDepth = initMinDepth;
182            this.initMaxDepth = initMaxDepth;
183            this.tournamentSize = tournamentSize;
184            this.maxGenerations = maxGenerations;
185            this.errorType2Weight = errorType2Weight;
186            this.maxDepth = maxDepth;
187            this.maxNodes = maxNodes;
188        }
189       
190        public GPGenotype getGp() {
191            return this.gp;
192        }
193       
194        public Variable[] getVariables() {
195            return ((CrossPareGP)this.problem).getVariables();
196        }
197
198        @Override
199        public void buildClassifier(Instances traindata) throws Exception {
200            InstanceData train = new InstanceData(traindata);           
201            this.problem = new CrossPareGP(train.getX(), train.getY(), this.populationSize, this.initMinDepth, this.initMaxDepth, this.tournamentSize, this.errorType2Weight, this.maxDepth, this.maxNodes);
202            this.gp = problem.create();
203            this.gp.evolve(this.maxGenerations);
204        }
205       
206        /**
207         * GPProblem implementation
208         */
209        class CrossPareGP extends GPProblem {
210            private double[][] instances;
211            private boolean[] output;
212
213            private int maxDepth;
214            private int maxNodes;
215           
216            private Variable[] x;
217
218            public CrossPareGP(double[][] instances, boolean[] output, int populationSize, int minInitDept, int maxInitDepth, int tournamentSize, double errorType2Weight, int maxDepth, int maxNodes) throws InvalidConfigurationException {
219                super(new GPConfiguration());
220               
221                this.instances = instances;
222                this.output = output;
223                this.maxDepth = maxDepth;
224                this.maxNodes = maxNodes;
225
226                Configuration.reset();
227                GPConfiguration config = this.getGPConfiguration();
228               
229                this.x = new Variable[this.instances[0].length];
230               
231                for(int j=0; j < this.x.length; j++) {
232                    this.x[j] = Variable.create(config, "X"+j, CommandGene.DoubleClass);   
233                }
234
235                config.setGPFitnessEvaluator(new DeltaGPFitnessEvaluator()); // smaller fitness is better
236                //config.setGPFitnessEvaluator(new DefaultGPFitnessEvaluator()); // bigger fitness is better
237
238                config.setMinInitDepth(minInitDept);
239                config.setMaxInitDepth(maxInitDepth);
240               
241                config.setCrossoverProb((float)0.60);
242                config.setReproductionProb((float)0.10);
243                config.setMutationProb((float)0.30);
244
245                config.setSelectionMethod(new TournamentSelector(tournamentSize));
246
247                config.setPopulationSize(populationSize);
248
249                config.setMaxCrossoverDepth(4);
250                config.setFitnessFunction(new CrossPareFitness(this.x, this.instances, this.output, errorType2Weight));
251                config.setStrictProgramCreation(true);
252            }
253
254            // used for running the fitness function again for testing
255            public Variable[] getVariables() {
256                return this.x;
257            }
258
259
260            public GPGenotype create() throws InvalidConfigurationException {
261                GPConfiguration config = this.getGPConfiguration();
262
263                // return type
264                Class[] types = {CommandGene.DoubleClass};
265
266                // Arguments of result-producing chromosome: none
267                Class[][] argTypes = { {} };
268
269                // variables + functions, we set the variables with the values of the instances here
270                CommandGene[] vars = new CommandGene[this.instances[0].length];
271                for(int j=0; j < this.instances[0].length; j++) {
272                    vars[j] = this.x[j];
273                }
274                CommandGene[] funcs = {
275                    new Add(config, CommandGene.DoubleClass),
276                    new Subtract(config, CommandGene.DoubleClass),
277                    new Multiply(config, CommandGene.DoubleClass),
278                    new Divide(config, CommandGene.DoubleClass),
279                    new Sine(config, CommandGene.DoubleClass),
280                    new Cosine(config, CommandGene.DoubleClass),
281                    new Exp(config, CommandGene.DoubleClass),
282                    new Log(config, CommandGene.DoubleClass),
283                    new GT(config, CommandGene.DoubleClass),
284                    new Max(config, CommandGene.DoubleClass),
285                    new Terminal(config, CommandGene.DoubleClass, -100.0, 100.0, true), // min, max, whole numbers
286                };
287
288                CommandGene[] comb = (CommandGene[])ArrayUtils.addAll(vars, funcs);
289                CommandGene[][] nodeSets = {
290                    comb,
291                };
292               
293                // we only have one chromosome so this suffices
294                int minDepths[] = {config.getMinInitDepth()};
295                int maxDepths[] = {this.maxDepth};
296                GPGenotype result = GPGenotype.randomInitialGenotype(config, types, argTypes, nodeSets, minDepths, maxDepths, this.maxNodes, false); // 40 = maxNodes, true = verbose output
297
298                return result;
299            }
300        }
301
302       
303        /**
304         * Fitness function
305         */
306        class CrossPareFitness extends GPFitnessFunction {
307           
308            private static final long serialVersionUID = 75234832484387L;
309
310            private Variable[] x;
311
312            private double[][] instances;
313            private boolean[] output;
314
315            private double errorType2Weight = 1.0;
316
317            // needed in evaluate
318            //private Object[] NO_ARGS = new Object[0];
319
320            private double sfitness = 0.0f;
321            private int errorType1 = 0;
322            private int errorType2 = 0;
323
324            public CrossPareFitness(Variable[] x, double[][] instances, boolean[] output, double errorType2Weight) {
325                this.x = x;
326                this.instances = instances;
327                this.output = output;
328                this.errorType2Weight = errorType2Weight;
329            }
330
331            public int getErrorType1() {
332                return this.errorType1;
333            }
334
335            public int getErrorType2() {
336                return this.errorType2;
337            }
338
339            public double getSecondFitness() {
340                return this.sfitness;
341            }
342
343            public int getNumInstances() {
344                return this.instances.length;
345            }
346
347            /**
348             * This is the fitness function
349             *
350             * Our fitness is best if we have the less wrong classifications, this includes a weight for type2 errors
351             */
352            @Override
353            protected double evaluate(final IGPProgram program) {
354                double pfitness = 0.0f;
355                this.sfitness = 0.0f;
356                double value = 0.0f;
357
358                // count classification errors
359                this.errorType1 = 0;
360                this.errorType2 = 0;
361
362                for(int i=0; i < this.instances.length; i++) {
363
364                    // requires that we have a variable for each column of our dataset (attribute of instance)
365                    for(int j=0; j < this.x.length; j++) {
366                        this.x[j].set(this.instances[i][j]);
367                    }
368
369                    // value gives us a double, if < 0.5 we set this instance as faulty
370                    value = program.execute_double(0, this.x);
371
372                    if(value < 0.5) {
373                        if(this.output[i] != true) {
374                            this.errorType1 += 1;
375                        }
376                    }else {
377                        if(this.output[i] == true) {
378                            this.errorType2 += 1;
379                        }
380                    }
381                }
382
383                // now calc pfitness
384                pfitness = (this.errorType1 + this.errorType2Weight * this.errorType2) / this.instances.length;
385
386                // number of nodes in the programm, if lower then 10 we assign sFitness of 10
387                // we can set metadata with setProgramData to save this
388                if(program.getChromosome(0).getSize(0) < 10) {
389                    program.setApplicationData(10.0f);
390                }
391
392                return pfitness;
393            }
394        }
395       
396        /**
397         * Custom GT implementation used in the GP Algorithm.
398         */
399         public class GT extends MathCommand implements ICloneable {
400             
401             private static final long serialVersionUID = 113454184817L;
402
403             public GT(final GPConfiguration a_conf, java.lang.Class a_returnType) throws InvalidConfigurationException {
404                 super(a_conf, 2, a_returnType);
405             }
406
407             public String toString() {
408                 return "GT(&1, &2)";
409             }
410
411             public String getName() {
412                 return "GT";
413             }   
414
415             public float execute_float(ProgramChromosome c, int n, Object[] args) {
416                 float f1 = c.execute_float(n, 0, args);
417                 float f2 = c.execute_float(n, 1, args);
418
419                 float ret = 1.0f;
420                 if(f1 > f2) {
421                     ret = 0.0f;
422                 }
423
424                 return ret;
425             }
426
427             public double execute_double(ProgramChromosome c, int n, Object[] args) {
428                 double f1 = c.execute_double(n, 0, args);
429                 double f2 = c.execute_double(n, 1, args);
430
431                 double ret = 1;
432                 if(f1 > f2)  {
433                     ret = 0;
434                 }
435                 return ret;
436             }
437
438             public Object clone() {
439                 try {
440                     GT result = new GT(getGPConfiguration(), getReturnType());
441                     return result;
442                 }catch(Exception ex) {
443                     throw new CloneException(ex);
444                 }
445             }
446         }
447    }
448   
449    /**
450     * GP Multiple Data Sets Validation-Voting Classifier
451     *
452     * Basically the same as the GP Multiple Data Sets Validation Classifier.
453     * But here we do keep a model candidate for each training set which may later vote
454     *
455     */
456    public class GPVVClassifier extends GPVClassifier {
457
458        private static final long serialVersionUID = -654710583852839901L;
459        private List<Classifier> classifiers = null;
460       
461        @Override
462        public void buildClassifier(Instances arg0) throws Exception {
463            // TODO Auto-generated method stub
464           
465        }
466       
467        /** Build the GP Multiple Data Sets Validation-Voting Classifier
468         *
469         * This is according to Section 6 of the Paper by Liu et al.
470         * It is basically the Multiple Data Sets Validation Classifier but here we keep the best models an let them vote.
471         *
472         * @param traindataSet
473         * @throws Exception
474         */
475        public void buildClassifier(SetUniqueList<Instances> traindataSet) throws Exception {
476
477            // each classifier is trained with one project from the set
478            // then is evaluated on the rest
479            classifiers = new LinkedList<>();
480            for(int i=0; i < traindataSet.size(); i++) {
481               
482                // candidates we get out of evaluation
483                LinkedList<Classifier> candidates = new LinkedList<>();
484               
485                // number of runs
486                for(int k=0; k < this.numberRuns; k++) {
487                    Classifier classifier = new GPRun();
488                    ((GPRun)classifier).configure(this.populationSize, this.initMinDepth, this.initMaxDepth, this.tournamentSize, this.maxGenerations, this.errorType2Weight, this.maxDepth, this.maxNodes);
489                   
490                    // one project is training data
491                    classifier.buildClassifier(traindataSet.get(i));
492                   
493                    double[] errors;
494                    // rest of the set is evaluation data, we evaluate now
495                    for(int j=0; j < traindataSet.size(); j++) {
496                        if(j != i) {
497                            // if type1 and type2 errors are < 0.5 we allow the model in the candidates
498                            errors = this.evaluate((GPRun)classifier, traindataSet.get(j));
499                            if((errors[0] < 0.5) && (errors[0] < 0.5)) {
500                                candidates.add(classifier);
501                            }
502                        }
503                    }
504                }
505               
506                // now after the evaluation we do a model selection where only one model remains for the given training data
507                double smallest_error_count = Double.MAX_VALUE;
508                double[] errors;
509                Classifier best = null;
510                for(int ii=0; ii < candidates.size(); ii++) {
511                    for(int j=0; j < traindataSet.size(); j++) {
512                        if(j != i) {
513                            errors = this.evaluate((GPRun)candidates.get(ii), traindataSet.get(j));
514                           
515                            if(errors[0]+errors[1] < smallest_error_count) {
516                                best = candidates.get(ii);
517                            }
518                        }
519                    }
520                }
521               
522                // now we have the best classifier for this training data
523                classifiers.add(best);
524            }
525        }
526       
527        /**
528         * Use the best classifiers for each training data in a majority voting
529         */
530        @Override
531        public double classifyInstance(Instance instance) {
532           
533            int vote_positive = 0;
534           
535            for (int i = 0; i < classifiers.size(); i++) {
536                Classifier classifier = classifiers.get(i);
537               
538                GPGenotype gp = ((GPRun)classifier).getGp();
539                Variable[] vars = ((GPRun)classifier).getVariables();
540               
541                IGPProgram fitest = gp.getAllTimeBest();  // all time fitest
542                for(int j = 0; j < instance.numAttributes()-1; j++) {
543                   vars[j].set(instance.value(j));
544                }
545               
546                if(fitest.execute_double(0, vars) < 0.5) {
547                    vote_positive += 1;
548                }
549            }
550           
551            if(vote_positive >= (classifiers.size()/2)) {
552                return 1.0;
553            }else {
554                return 0.0;
555            }
556        }
557    }
558   
559    /**
560     * GP Multiple Data Sets Validation Classifier
561     *
562     * We train a Classifier with one training project $numberRun times.
563     * Then we evaluate the classifier on the rest of the training projects and keep the best classifier.
564     * After that we have for each training project the best classifier as per the evaluation on the rest of the data set.
565     * Then we determine the best classifier from these candidates and keep it to be used later.
566     */
567    public class GPVClassifier extends AbstractClassifier {
568       
569        private List<Classifier> classifiers = null;
570        private Classifier best = null;
571
572        private static final long serialVersionUID = 3708714057579101522L;
573
574        protected int populationSize;
575        protected int initMinDepth;
576        protected int initMaxDepth;
577        protected int tournamentSize;
578        protected int maxGenerations;
579        protected double errorType2Weight;
580        protected int numberRuns;
581        protected int maxDepth;
582        protected int maxNodes;
583
584        /**
585         * Configure the GP Params and number of Runs
586         *
587         * @param populationSize
588         * @param initMinDepth
589         * @param initMaxDepth
590         * @param tournamentSize
591         * @param maxGenerations
592         * @param errorType2Weight
593         */
594        public void configure(int populationSize, int initMinDepth, int initMaxDepth, int tournamentSize, int maxGenerations, double errorType2Weight, int numberRuns, int maxDepth, int maxNodes) {
595            this.populationSize = populationSize;
596            this.initMinDepth = initMinDepth;
597            this.initMaxDepth = initMaxDepth;
598            this.tournamentSize = tournamentSize;
599            this.maxGenerations = maxGenerations;
600            this.errorType2Weight = errorType2Weight;
601            this.numberRuns = numberRuns;
602            this.maxDepth = maxDepth;
603            this.maxNodes = maxNodes;
604        }
605       
606        /** Build the GP Multiple Data Sets Validation Classifier
607         *
608         * This is according to Section 6 of the Paper by Liu et al. except for the selection of the best model.
609         * Section 4 describes a slightly different approach.
610         *
611         * @param traindataSet
612         * @throws Exception
613         */
614        public void buildClassifier(SetUniqueList<Instances> traindataSet) throws Exception {
615
616            // each classifier is trained with one project from the set
617            // then is evaluated on the rest
618            for(int i=0; i < traindataSet.size(); i++) {
619               
620                // candidates we get out of evaluation
621                LinkedList<Classifier> candidates = new LinkedList<>();
622               
623                // numberRuns full GPRuns, we generate numberRuns models for each traindata
624                for(int k=0; k < this.numberRuns; k++) {
625                    Classifier classifier = new GPRun();
626                    ((GPRun)classifier).configure(this.populationSize, this.initMinDepth, this.initMaxDepth, this.tournamentSize, this.maxGenerations, this.errorType2Weight, this.maxDepth, this.maxNodes);
627                   
628                    classifier.buildClassifier(traindataSet.get(i));
629                   
630                    double[] errors;
631
632                    // rest of the set is evaluation data, we evaluate now
633                    for(int j=0; j < traindataSet.size(); j++) {
634                        if(j != i) {
635                            // if type1 and type2 errors are < 0.5 we allow the model in the candidate list
636                            errors = this.evaluate((GPRun)classifier, traindataSet.get(j));
637                            if((errors[0] < 0.5) && (errors[0] < 0.5)) {
638                                candidates.add(classifier);
639                            }
640                        }
641                    }
642                }
643               
644                // after the numberRuns we have < numberRuns candidate models for this trainData
645                // we now evaluate the candidates
646                // finding the best model is not really described in the paper we go with least errors
647                double smallest_error_count = Double.MAX_VALUE;
648                double[] errors;
649                Classifier best = null;
650                for(int ii=0; ii < candidates.size(); ii++) {
651                    for(int j=0; j < traindataSet.size(); j++) {
652                        if(j != i) {
653                            errors = this.evaluate((GPRun)candidates.get(ii), traindataSet.get(j));
654                           
655                            if(errors[0]+errors[1] < smallest_error_count) {
656                                best = candidates.get(ii);
657                            }
658                        }
659                    }
660                }
661               
662                // now we have the best classifier for this training data
663                classifiers.add(best);
664            } /* endfor trainData */
665           
666            // now we have one best classifier for each trainData
667            // we evaluate again to find the best classifier of all time
668            // this selection is now according to section 4 of the paper and not 6 where an average of the 6 models is build
669            double smallest_error_count = Double.MAX_VALUE;
670            double error_count;
671            double errors[];
672            for(int j=0; j < classifiers.size(); j++) {
673                error_count = 0;
674                Classifier current = classifiers.get(j);
675                for(int i=0; i < traindataSet.size(); i++) {
676                    errors = this.evaluate((GPRun)current, traindataSet.get(i));
677                    error_count = errors[0] + errors[1];
678                }
679               
680                if(error_count < smallest_error_count) {
681                    best = current;
682                }
683            }
684        }
685       
686        @Override
687        public void buildClassifier(Instances traindata) throws Exception {
688            final Classifier classifier = new GPRun();
689            ((GPRun)classifier).configure(populationSize, initMinDepth, initMaxDepth, tournamentSize, maxGenerations, errorType2Weight, this.maxDepth, this.maxNodes);
690            classifier.buildClassifier(traindata);
691            classifiers.add(classifier);
692        }
693       
694        /**
695         * Evaluation of the Classifier
696         *
697         * We evaluate the classifier with the Instances of the evalData.
698         * It basically assigns the instance attribute values to the variables of the s-expression-tree and
699         * then counts the missclassifications.
700         *
701         * @param classifier
702         * @param evalData
703         * @return
704         */
705        public double[] evaluate(GPRun classifier, Instances evalData) {
706            GPGenotype gp = classifier.getGp();
707            Variable[] vars = classifier.getVariables();
708           
709            IGPProgram fitest = gp.getAllTimeBest();  // selects the fitest of all not just the last generation
710           
711            double classification;
712            int error_type1 = 0;
713            int error_type2 = 0;
714            int positive = 0;
715            int negative = 0;
716           
717            for(Instance instance: evalData) {
718               
719                // assign instance attribute values to the variables of the s-expression-tree
720                double[] tmp = WekaUtils.instanceValues(instance);
721                for(int i = 0; i < tmp.length; i++) {
722                    vars[i].set(tmp[i]);
723                }
724               
725                classification = fitest.execute_double(0, vars);
726               
727                // we need to count the absolutes of positives for percentage
728                if(instance.classValue() == 1.0) {
729                    positive +=1;
730                }else {
731                    negative +=1;
732                }
733               
734                // classification < 0.5 we say defective
735                if(classification < 0.5) {
736                    if(instance.classValue() != 1.0) {
737                        error_type1 += 1;
738                    }
739                }else {
740                    if(instance.classValue() == 1.0) {
741                        error_type2 += 1;
742                    }
743                }
744            }
745           
746            // return error types percentages for the types
747            double et1_per = error_type1 / negative;
748            double et2_per = error_type2 / positive;
749            return new double[]{et1_per, et2_per};
750        }
751       
752        /**
753         * Use only the best classifier from our evaluation phase
754         */
755        @Override
756        public double classifyInstance(Instance instance) {
757            GPGenotype gp = ((GPRun)best).getGp();
758            Variable[] vars = ((GPRun)best).getVariables();
759           
760            IGPProgram fitest = gp.getAllTimeBest();  // all time fitest
761            for(int i = 0; i < instance.numAttributes()-1; i++) {
762               vars[i].set(instance.value(i));
763            }
764           
765            double classification = fitest.execute_double(0, vars);
766           
767            if(classification < 0.5) {
768                return 1.0;
769            }else {
770                return 0.0;
771            }
772        }
773    }
774}
Note: See TracBrowser for help on using the repository browser.