2020-03-21 00:37:09 +00:00
|
|
|
package de.wwwu.awolf.presenter.evaluation;
|
|
|
|
|
|
|
|
import de.wwwu.awolf.model.Line;
|
|
|
|
import de.wwwu.awolf.model.LineModel;
|
|
|
|
import de.wwwu.awolf.model.communication.Data;
|
|
|
|
import de.wwwu.awolf.model.communication.EvaluationData;
|
|
|
|
import de.wwwu.awolf.model.communication.SubscriberType;
|
2020-03-21 19:54:03 +00:00
|
|
|
import de.wwwu.awolf.model.evaluation.ComparisonResult;
|
2020-03-21 00:37:09 +00:00
|
|
|
import de.wwwu.awolf.presenter.Presenter;
|
|
|
|
import de.wwwu.awolf.presenter.algorithms.Algorithm;
|
2020-03-28 15:24:35 +00:00
|
|
|
import de.wwwu.awolf.presenter.data.DataHandler;
|
2020-03-21 19:54:03 +00:00
|
|
|
import de.wwwu.awolf.presenter.data.generator.DatasetGenerator;
|
|
|
|
import de.wwwu.awolf.presenter.evaluation.measures.PercentageErrorBasedMeasure;
|
|
|
|
import de.wwwu.awolf.presenter.evaluation.measures.ScaleDependentMeasure;
|
|
|
|
import de.wwwu.awolf.presenter.evaluation.measures.ScaledErrorBasedMeasure;
|
2020-03-21 00:37:09 +00:00
|
|
|
import de.wwwu.awolf.presenter.util.Logging;
|
2017-08-01 19:59:33 +00:00
|
|
|
|
2017-09-19 11:34:06 +00:00
|
|
|
import java.io.File;
|
2020-03-21 00:37:09 +00:00
|
|
|
import java.util.*;
|
|
|
|
import java.util.concurrent.Flow;
|
2017-08-01 19:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
|
|
|
*
|
|
|
|
* @Author: Armin Wolf
|
|
|
|
* @Email: a_wolf28@uni-muenster.de
|
|
|
|
* @Date: 01.08.2017.
|
|
|
|
*/
|
2020-03-28 15:24:35 +00:00
|
|
|
public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
|
2017-08-03 06:27:38 +00:00
|
|
|
|
2017-08-02 20:42:01 +00:00
|
|
|
private LineModel arrangement;
|
2017-09-07 17:39:55 +00:00
|
|
|
private DatasetGenerator generator;
|
2017-08-01 19:59:33 +00:00
|
|
|
|
2017-09-07 17:39:55 +00:00
|
|
|
//übergebene Parameter
|
|
|
|
private int type;
|
|
|
|
private int iterations;
|
|
|
|
private int alg;
|
2020-03-21 00:37:09 +00:00
|
|
|
private Flow.Subscriber<? super Data> subscriber;
|
2020-03-21 19:54:03 +00:00
|
|
|
private Map<Algorithm.Type, Map<String, String>> resultMapping;
|
2017-08-02 20:42:01 +00:00
|
|
|
|
2017-09-08 19:23:02 +00:00
|
|
|
/**
|
2017-09-10 15:45:47 +00:00
|
|
|
* Konstruktor zur evaluation
|
|
|
|
*
|
2020-03-20 17:08:18 +00:00
|
|
|
* @param type Typ der evaluation
|
|
|
|
* @param n Größe des Datensatzes
|
|
|
|
* @param alg 0 = lms,
|
|
|
|
* 1 = rm,
|
|
|
|
* 2 = ts,
|
|
|
|
* 3 = lms, rm,
|
|
|
|
* 4 = lms, ts,
|
|
|
|
* 5 = rm, ts,
|
|
|
|
* 6 = lms, rm, ts,
|
2017-10-15 10:45:47 +00:00
|
|
|
* @param datasettyp typ der zu generierenden Datensatz
|
2017-09-08 19:23:02 +00:00
|
|
|
*/
|
2020-03-28 15:24:35 +00:00
|
|
|
public EvaluatationHandler(int type, int n, int alg, DataHandler.DataType datasettyp) {
|
|
|
|
Presenter instance = Presenter.getInstance();
|
|
|
|
subscribe(instance);
|
2017-09-07 17:39:55 +00:00
|
|
|
this.arrangement = new LineModel();
|
2020-03-21 19:54:03 +00:00
|
|
|
this.resultMapping = new EnumMap<>(Algorithm.Type.class);
|
|
|
|
|
2020-03-28 15:24:35 +00:00
|
|
|
Set<Line> data = instance.generateDataset(n, datasettyp);
|
2020-03-21 19:54:03 +00:00
|
|
|
Logging.logInfo("Starting the Benchmark...");
|
|
|
|
arrangement.setLines(data);
|
|
|
|
|
|
|
|
Logging.logInfo("Benchmark on Dataset: " + datasettyp + " with " + n + " points");
|
|
|
|
|
2017-09-07 17:39:55 +00:00
|
|
|
this.type = type;
|
2017-09-08 19:23:02 +00:00
|
|
|
this.iterations = n;
|
2017-09-07 17:39:55 +00:00
|
|
|
this.alg = alg;
|
|
|
|
}
|
2017-08-03 06:27:38 +00:00
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
|
|
|
* Konstruktor zur evaluation
|
|
|
|
*
|
|
|
|
* @param type Typ der evaluation
|
|
|
|
* @param alg 0 = lms,
|
|
|
|
* 1 = rm,
|
|
|
|
* 2 = ts,
|
|
|
|
* 3 = lms, rm,
|
|
|
|
* 4 = lms, ts,
|
|
|
|
* 5 = rm, ts,
|
|
|
|
* 6 = lms, rm, ts,
|
|
|
|
* @param file Datei die importiert werden soll
|
|
|
|
*/
|
2020-03-28 15:24:35 +00:00
|
|
|
public EvaluatationHandler(int type, int alg, File file) {
|
|
|
|
Presenter instance = Presenter.getInstance();
|
|
|
|
subscribe(instance);
|
|
|
|
instance.importDataset(file);
|
|
|
|
this.arrangement = instance.getModel();
|
2020-03-21 19:54:03 +00:00
|
|
|
this.resultMapping = new EnumMap<>(Algorithm.Type.class);
|
2017-09-19 11:34:06 +00:00
|
|
|
|
|
|
|
this.type = type;
|
|
|
|
this.alg = alg;
|
2020-03-21 19:54:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private Map<Algorithm.Type, Map<String, String>> benchmarkSameEstimator(final Algorithm.Type advanced, final Algorithm.Type naiv) {
|
|
|
|
Logging.logInfo("AlgorithmComparison with Types: " + advanced.name() + ", " + naiv.name());
|
2020-03-28 15:24:35 +00:00
|
|
|
AlgorithmComparison comparison = new AlgorithmComparison(Arrays.asList(naiv, advanced), Collections.unmodifiableSet(arrangement.getLines()));
|
2020-03-21 19:54:03 +00:00
|
|
|
ComparisonResult comparisonResult = comparison.compare();
|
2017-09-19 11:34:06 +00:00
|
|
|
|
|
|
|
|
2020-03-21 19:54:03 +00:00
|
|
|
Map<String, String> result = new HashMap<>();
|
|
|
|
result.putAll(getScaleDependentMeasure(arrangement.getLines(), comparisonResult, advanced));
|
|
|
|
result.putAll(getScaledErrorBasedMeasure(arrangement.getLines(), comparisonResult, advanced, naiv));
|
|
|
|
Logging.logInfo("finished with execution of the algorithms.");
|
2017-09-19 11:34:06 +00:00
|
|
|
|
2020-03-21 19:54:03 +00:00
|
|
|
this.resultMapping.put(advanced, result);
|
|
|
|
return this.resultMapping;
|
2017-09-19 11:34:06 +00:00
|
|
|
}
|
|
|
|
|
2020-03-21 19:54:03 +00:00
|
|
|
private Map<Algorithm.Type, Map<String, String>> benchmarkDifferentEstimators(List<Algorithm.Type> types) {
|
|
|
|
Logging.logInfo("AlgorithmComparison with Types: " + types);
|
2020-03-28 15:24:35 +00:00
|
|
|
AlgorithmComparison comparison = new AlgorithmComparison(types, Collections.unmodifiableSet(arrangement.getLines()));
|
2020-03-21 19:54:03 +00:00
|
|
|
ComparisonResult comparisonResult = comparison.compare();
|
|
|
|
|
2020-03-23 06:58:40 +00:00
|
|
|
types.forEach(typeEntry -> this.resultMapping.put(typeEntry, getPercentigeErrorBasedMeasure(arrangement.getLines(), comparisonResult, typeEntry)));
|
2020-03-21 19:54:03 +00:00
|
|
|
Logging.logInfo("finished with execution of the algorithms.");
|
|
|
|
return this.resultMapping;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
|
|
|
* Startet die Evaluation zu den passenden Typ. Bei beendigung wird der Beobachter informiert.
|
|
|
|
*/
|
2020-03-21 19:54:03 +00:00
|
|
|
@Override
|
2020-03-20 17:08:18 +00:00
|
|
|
public void run() {
|
2020-03-21 19:54:03 +00:00
|
|
|
Map<Algorithm.Type, Map<String, String>> result = new EnumMap<>(Algorithm.Type.class);
|
2017-09-10 15:45:47 +00:00
|
|
|
switch (type) {
|
2017-09-07 17:39:55 +00:00
|
|
|
case 0:
|
2017-09-10 15:45:47 +00:00
|
|
|
//der alg der gewählt wurde
|
|
|
|
if (alg == 0) {
|
2020-03-21 19:54:03 +00:00
|
|
|
result = benchmarkSameEstimator(Algorithm.Type.LMS, Algorithm.Type.NAIV_LMS);
|
2017-09-10 15:45:47 +00:00
|
|
|
} else if (alg == 1) {
|
2020-03-21 19:54:03 +00:00
|
|
|
result = benchmarkSameEstimator(Algorithm.Type.RM, Algorithm.Type.NAIV_RM);
|
2017-09-10 15:45:47 +00:00
|
|
|
} else {
|
2020-03-21 19:54:03 +00:00
|
|
|
result = benchmarkSameEstimator(Algorithm.Type.TS, Algorithm.Type.NAIV_TS);
|
2017-09-10 15:45:47 +00:00
|
|
|
}
|
2017-09-07 17:39:55 +00:00
|
|
|
break;
|
|
|
|
case 1:
|
2017-09-10 15:45:47 +00:00
|
|
|
switch (alg) {
|
2017-09-08 19:23:02 +00:00
|
|
|
case 3:
|
2020-03-21 19:54:03 +00:00
|
|
|
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM));
|
2017-09-08 19:23:02 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2020-03-21 19:54:03 +00:00
|
|
|
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.TS));
|
2017-09-08 19:23:02 +00:00
|
|
|
break;
|
|
|
|
case 5:
|
2020-03-21 19:54:03 +00:00
|
|
|
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.RM, Algorithm.Type.TS));
|
2017-09-08 19:23:02 +00:00
|
|
|
break;
|
|
|
|
case 6:
|
2020-03-21 19:54:03 +00:00
|
|
|
result = benchmarkDifferentEstimators(Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM, Algorithm.Type.TS));
|
2017-09-08 19:23:02 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-09-07 17:39:55 +00:00
|
|
|
break;
|
|
|
|
}
|
2020-03-21 19:54:03 +00:00
|
|
|
sendTableApproximationData(result);
|
2017-08-03 18:37:59 +00:00
|
|
|
}
|
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
|
|
|
* Die berechneten Ergebnisse werden an den Beobachter übermittelt um dann visualisiert zu werden.
|
2020-03-20 17:08:18 +00:00
|
|
|
*
|
2017-10-15 10:45:47 +00:00
|
|
|
* @param result Ergebnisse
|
|
|
|
*/
|
2020-03-21 19:54:03 +00:00
|
|
|
private void sendTableApproximationData(Map<Algorithm.Type, Map<String, String>> result) {
|
2017-08-03 18:37:59 +00:00
|
|
|
|
2020-03-21 00:37:09 +00:00
|
|
|
EvaluationData data = new EvaluationData();
|
2020-03-21 19:54:03 +00:00
|
|
|
data.setType(SubscriberType.EVALUATION_TABLE_DATA);
|
|
|
|
data.setMultipleColumnResult(result);
|
|
|
|
data.setRowsPerColumn(result.keySet().size());
|
2020-03-21 00:37:09 +00:00
|
|
|
this.subscriber.onNext(data);
|
2017-08-01 19:59:33 +00:00
|
|
|
}
|
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
|
|
|
* Startet die Berechnung der skalierungsabbhängigen Maße.
|
2020-03-20 17:08:18 +00:00
|
|
|
*
|
2017-10-15 10:45:47 +00:00
|
|
|
* @param lines Liste der Geraden
|
2020-03-20 17:08:18 +00:00
|
|
|
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
2017-10-15 10:45:47 +00:00
|
|
|
*/
|
2020-03-28 15:24:35 +00:00
|
|
|
private Map<String, String> getScaleDependentMeasure(final Set<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type type) {
|
2020-03-21 19:54:03 +00:00
|
|
|
|
|
|
|
Logging.logInfo("Calculating ScaleDependentMeasure for " + type);
|
|
|
|
|
|
|
|
Double m = comparisonResult.get(type).getM();
|
|
|
|
Double b = comparisonResult.get(type).getB();
|
|
|
|
|
2017-09-07 17:39:55 +00:00
|
|
|
ScaleDependentMeasure scaleDependentMeasure = new ScaleDependentMeasure(lines, m, b);
|
2020-03-21 19:54:03 +00:00
|
|
|
Map<String, String> ret = new HashMap<>();
|
|
|
|
ret.put(type + " MSE", scaleDependentMeasure.mse().toString());
|
|
|
|
ret.put(type + " RMSE", scaleDependentMeasure.rmse().toString());
|
|
|
|
ret.put(type + " MAE", scaleDependentMeasure.mae().toString());
|
|
|
|
ret.put(type + " MDAE", scaleDependentMeasure.mdae().toString());
|
|
|
|
ret.put(type + " SLOPE", m.toString());
|
|
|
|
ret.put(type + " y-INTERCEPTION", b.toString());
|
|
|
|
|
|
|
|
Logging.logInfo("finished calculating ScaleDependentMeasure.");
|
2017-08-01 19:59:33 +00:00
|
|
|
|
2017-09-07 17:39:55 +00:00
|
|
|
return ret;
|
2017-08-01 19:59:33 +00:00
|
|
|
}
|
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
|
|
|
* Startet die Berechnung der Maße die auf dem prozentualen Fehler basieren.
|
2020-03-20 17:08:18 +00:00
|
|
|
*
|
2017-10-15 10:45:47 +00:00
|
|
|
* @param lines Liste der Geraden
|
2020-03-20 17:08:18 +00:00
|
|
|
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
2017-10-15 10:45:47 +00:00
|
|
|
*/
|
2020-03-28 15:24:35 +00:00
|
|
|
private Map<String, String> getPercentigeErrorBasedMeasure(final Set<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type type) {
|
2020-03-21 19:54:03 +00:00
|
|
|
Logging.logInfo("Calculating PercentigeErrorBasedMeasure for " + type);
|
|
|
|
Double m = comparisonResult.get(type).getM();
|
|
|
|
Double b = comparisonResult.get(type).getB();
|
|
|
|
|
2017-09-07 17:39:55 +00:00
|
|
|
PercentageErrorBasedMeasure percentageErrorBasedMeasure = new PercentageErrorBasedMeasure(lines, m, b);
|
2020-03-21 19:54:03 +00:00
|
|
|
Map<String, String> ret = new HashMap<>();
|
|
|
|
ret.put(type + " MAPE", percentageErrorBasedMeasure.mape().toString());
|
|
|
|
ret.put(type + " MDAPE", percentageErrorBasedMeasure.mdape().toString());
|
|
|
|
ret.put(type + " RMSPE", percentageErrorBasedMeasure.rmspe().toString());
|
|
|
|
ret.put(type + " RMDSPE", percentageErrorBasedMeasure.rmdspe().toString());
|
|
|
|
ret.put(type + " SLOPE", m.toString());
|
|
|
|
ret.put(type + " y-INTERCEPTION", b.toString());
|
|
|
|
Logging.logInfo("finished calculating PercentigeErrorBasedMeasure.");
|
2017-09-07 17:39:55 +00:00
|
|
|
return ret;
|
2017-08-03 18:37:59 +00:00
|
|
|
}
|
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
|
|
|
* Startet die Berechnung der skalierungsunabbhängigen Maße.
|
2020-03-20 17:08:18 +00:00
|
|
|
*
|
2017-10-15 10:45:47 +00:00
|
|
|
* @param lines Liste der Geraden
|
2020-03-20 17:08:18 +00:00
|
|
|
* @return Liste mit den Ergebnissen, bereit zum visualisieren
|
2017-10-15 10:45:47 +00:00
|
|
|
*/
|
2020-03-28 15:24:35 +00:00
|
|
|
private Map<String, String> getScaledErrorBasedMeasure(final Set<Line> lines, final ComparisonResult comparisonResult, final Algorithm.Type advanced, final Algorithm.Type naiv) {
|
2020-03-21 19:54:03 +00:00
|
|
|
|
|
|
|
Logging.logInfo("Calculating ScaledErrorBasedMeasure for " + advanced + ", " + naiv);
|
|
|
|
|
|
|
|
//first
|
|
|
|
Double m = comparisonResult.get(advanced).getM();
|
|
|
|
Double b = comparisonResult.get(advanced).getB();
|
|
|
|
//second
|
|
|
|
Double naivM = comparisonResult.get(naiv).getM();
|
|
|
|
Double naivB = comparisonResult.get(naiv).getB();
|
|
|
|
|
|
|
|
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m, b, naivM, naivB);
|
|
|
|
Map<String, String> ret = new HashMap<>();
|
|
|
|
ret.put(advanced + " MSE", scaledErrorBasedMeasure.mse().toString());
|
|
|
|
ret.put(advanced + " RMSE", scaledErrorBasedMeasure.rmse().toString());
|
|
|
|
ret.put(advanced + " MAE", scaledErrorBasedMeasure.mae().toString());
|
|
|
|
ret.put(advanced + " MDAE", scaledErrorBasedMeasure.mdae().toString());
|
|
|
|
ret.put(advanced + " Naiv-SLOPE", naivM.toString());
|
|
|
|
ret.put(advanced + " Naiv-y-INTERCEPTION", naivB.toString());
|
|
|
|
|
|
|
|
Logging.logInfo("finished calculating ScaledErrorBasedMeasure.");
|
2017-09-07 17:39:55 +00:00
|
|
|
return ret;
|
2017-08-01 19:59:33 +00:00
|
|
|
}
|
|
|
|
|
2017-10-15 10:45:47 +00:00
|
|
|
/**
|
|
|
|
* @return Liste der Geraden auf der die Berechnungen ausgeführt wurden
|
|
|
|
*/
|
2020-03-28 15:24:35 +00:00
|
|
|
public Set<Line> getData() {
|
2017-09-05 18:39:52 +00:00
|
|
|
return arrangement.getLines();
|
|
|
|
}
|
2020-03-21 00:37:09 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void subscribe(Flow.Subscriber<? super Data> subscriber) {
|
|
|
|
this.subscriber = subscriber;
|
|
|
|
}
|
2017-08-01 19:59:33 +00:00
|
|
|
}
|