source: trunk/CrossPare/src/de/ugoe/cs/cpdp/Experiment.java @ 30

Last change on this file since 30 was 27, checked in by sherbold, 10 years ago
  • updated experiment and SoftwareVersion? such that the order of the results will now always be the same and not depend on the order of the data loading. Instead, it depends on the string-order of the projects and versions that are loaded.
  • Property svn:mime-type set to text/plain
File size: 9.2 KB
Line 
1package de.ugoe.cs.cpdp;
2
3import java.io.File;
4import java.util.Collections;
5import java.util.LinkedList;
6import java.util.List;
7import java.util.logging.Level;
8
9import org.apache.commons.collections4.list.SetUniqueList;
10
11import weka.core.Instances;
12import de.ugoe.cs.cpdp.dataprocessing.IProcessesingStrategy;
13import de.ugoe.cs.cpdp.dataprocessing.ISetWiseProcessingStrategy;
14import de.ugoe.cs.cpdp.dataselection.IPointWiseDataselectionStrategy;
15import de.ugoe.cs.cpdp.dataselection.ISetWiseDataselectionStrategy;
16import de.ugoe.cs.cpdp.eval.IEvaluationStrategy;
17import de.ugoe.cs.cpdp.loader.IVersionLoader;
18import de.ugoe.cs.cpdp.training.ISetWiseTrainingStrategy;
19import de.ugoe.cs.cpdp.training.ITrainer;
20import de.ugoe.cs.cpdp.training.ITrainingStrategy;
21import de.ugoe.cs.cpdp.versions.IVersionFilter;
22import de.ugoe.cs.cpdp.versions.SoftwareVersion;
23import de.ugoe.cs.util.console.Console;
24
25/**
26 * Class responsible for executing an experiment according to an {@link ExperimentConfiguration}. The steps of an experiment are as follows:
27 * <ul>
28 *  <li>load the data from the provided data path</li>
29 *  <li>filter the data sets according to the provided version filters</li>
30 *  <li>execute the following steps for each data sets as test data that is not ignored through the test version filter:
31 *  <ul>
32 *   <li>filter the data sets to setup the candidate training data:
33 *   <ul>
34 *    <li>remove all data sets from the same project</li>
35 *    <li>filter all data sets according to the training data filter
36 *   </ul></li>
37 *   <li>apply the setwise preprocessors</li>
38 *   <li>apply the setwise data selection algorithms</li>
39 *   <li>apply the setwise postprocessors</li>
40 *   <li>train the setwise training classifiers</li>
41 *   <li>unify all remaining training data into one data set</li>
42 *   <li>apply the preprocessors</li>
43 *   <li>apply the pointwise data selection algorithms</li>
44 *   <li>apply the postprocessors</li>
45 *   <li>train the normal classifiers</li>
46 *   <li>evaluate the results for all trained classifiers on the training data</li>
47 *  </ul></li>
48 * </ul>
49 *
50 * Note that this class implements {@link Runnable}, i.e., each experiment can be started in its own thread.
51 * @author Steffen Herbold
52 */
53public class Experiment implements Runnable {
54
55        /**
56         * configuration of the experiment
57         */
58        private final ExperimentConfiguration config;
59       
60        /**
61         * Constructor. Creates a new experiment based on a configuration.
62         * @param config configuration of the experiment
63         */
64        public Experiment(ExperimentConfiguration config) {
65                this.config = config;
66        }
67       
68        /**
69         * Executes the experiment with the steps as described in the class comment.
70         * @see Runnable#run()
71         */
72        @Override
73        public void run() {
74                final List<SoftwareVersion> versions = new LinkedList<>();
75               
76                for(IVersionLoader loader : config.getLoaders()) {
77                        versions.addAll(loader.load());
78                }
79               
80                for( IVersionFilter filter : config.getVersionFilters() ) {
81                        filter.apply(versions);
82                }
83                boolean writeHeader = true;
84                int versionCount = 1;
85                int testVersionCount = 0;
86               
87                for( SoftwareVersion testVersion : versions ) {
88                        if( isVersion(testVersion, config.getTestVersionFilters()) ) {
89                                testVersionCount++;
90                        }
91                }
92               
93                // sort versions
94                Collections.sort(versions);
95               
96                for( SoftwareVersion testVersion : versions ) {
97                        if( isVersion(testVersion, config.getTestVersionFilters()) ) {
98                                Console.traceln(Level.INFO, String.format("[%s] [%02d/%02d] %s: starting", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion()));
99                               
100                                // Setup testdata and training data
101                                Instances testdata = testVersion.getInstances();
102                                String testProject = testVersion.getProject();
103                                SetUniqueList<Instances> traindataSet = SetUniqueList.setUniqueList(new LinkedList<Instances>());
104                                for( SoftwareVersion trainingVersion : versions ) {
105                                        if( isVersion(trainingVersion, config.getTrainingVersionFilters()) ) {
106                                                if( trainingVersion!=testVersion ) {
107                                                        if( !trainingVersion.getProject().equals(testProject) ) {
108                                                                traindataSet.add(trainingVersion.getInstances());
109                                                        }
110                                                }
111                                        }
112                                }
113                               
114                                for( ISetWiseProcessingStrategy processor : config.getSetWisePreprocessors() ) {
115                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying setwise preprocessor %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), processor.getClass().getName()));
116                                        processor.apply(testdata, traindataSet);
117                                }
118                                for( ISetWiseDataselectionStrategy dataselector : config.getSetWiseSelectors() ) {
119                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying setwise selection %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), dataselector.getClass().getName()));
120                                        dataselector.apply(testdata, traindataSet);
121                                }
122                                for( ISetWiseProcessingStrategy processor : config.getSetWisePostprocessors() ) {
123                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying setwise postprocessor %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), processor.getClass().getName()));
124                                        processor.apply(testdata, traindataSet);
125                                }
126                                for( ISetWiseTrainingStrategy setwiseTrainer : config.getSetWiseTrainers() ) {
127                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying setwise trainer %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), setwiseTrainer.getName()));
128                                        setwiseTrainer.apply(traindataSet);
129                                }
130                                Instances traindata = makeSingleTrainingSet(traindataSet);
131                                for( IProcessesingStrategy processor : config.getPreProcessors() ) {
132                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying preprocessor %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), processor.getClass().getName()));
133                                        processor.apply(testdata, traindata);
134                                }
135                                for( IPointWiseDataselectionStrategy dataselector : config.getPointWiseSelectors() ) {
136                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying pointwise selection %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), dataselector.getClass().getName()));
137                                        traindata = dataselector.apply(testdata, traindata);
138                                }
139                                for( IProcessesingStrategy processor : config.getPostProcessors() ) {
140                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying setwise postprocessor %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), processor.getClass().getName()));
141                                        processor.apply(testdata, traindata);
142                                }
143                                for( ITrainingStrategy trainer : config.getTrainers() ) {
144                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying trainer %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), trainer.getName()));
145                                        trainer.apply(traindata);
146                                }
147                                File resultsDir = new File(config.getResultsPath());
148                                if (!resultsDir.exists()) {
149                                        resultsDir.mkdir();
150                                }
151                                for( IEvaluationStrategy evaluator : config.getEvaluators() ) {
152                                        Console.traceln(Level.FINE, String.format("[%s] [%02d/%02d] %s: applying evaluator %s", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion(), evaluator.getClass().getName()));
153                                        List<ITrainer> allTrainers = new LinkedList<>();
154                                        for( ISetWiseTrainingStrategy setwiseTrainer : config.getSetWiseTrainers() ) {
155                                                allTrainers.add(setwiseTrainer);
156                                        }
157                                        for( ITrainingStrategy trainer : config.getTrainers() ) {
158                                                allTrainers.add(trainer);
159                                        }
160                                        if( writeHeader ) {
161                                                evaluator.setParameter(config.getResultsPath() + "/" + config.getExperimentName() + ".csv");
162                                        }
163                                        evaluator.apply(testdata, traindata, allTrainers, writeHeader);
164                                        writeHeader = false;
165                                }
166                                Console.traceln(Level.INFO, String.format("[%s] [%02d/%02d] %s: finished", config.getExperimentName(), versionCount, testVersionCount, testVersion.getVersion()));
167                                versionCount++;
168                        }
169                }
170        }
171       
172        /**
173         * Helper method that checks if a version passes all filters.
174         * @param version version that is checked
175         * @param filters list of the filters
176         * @return true, if the version passes all filters, false otherwise
177         */
178        private boolean isVersion(SoftwareVersion version, List<IVersionFilter> filters) {
179                boolean result = true;
180                for( IVersionFilter filter : filters) {
181                        result &= !filter.apply(version);
182                }
183                return result;
184        }
185
186        /**
187         * Helper method that combines a set of Weka {@link Instances} sets into a single {@link Instances} set.
188         * @param traindataSet set of {@link Instances} to be combines
189         * @return single {@link Instances} set
190         */
191        public static Instances makeSingleTrainingSet(SetUniqueList<Instances> traindataSet) {
192                Instances traindataFull = null;
193                for( Instances traindata : traindataSet) {
194                        if( traindataFull==null ) {
195                                traindataFull = new Instances(traindata);
196                        } else {
197                                for( int i=0 ; i<traindata.numInstances() ; i++ ) {
198                                        traindataFull.add(traindata.instance(i));
199                                }
200                        }
201                }
202                return traindataFull;
203        }
204}
Note: See TracBrowser for help on using the repository browser.