algorithms-for-computing-li.../LinearRegressionTool/src/main/java/de/wwwu/awolf/presenter/evaluation/EvaluatationHandler.java

283 lines
11 KiB
Java
Raw Normal View History

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;
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;
import java.io.File;
2020-04-05 18:53:52 +00:00
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
2020-03-21 00:37:09 +00:00
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.
*/
public class EvaluatationHandler implements Runnable, Flow.Publisher<Data> {
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-09-08 19:23:02 +00:00
/**
* Konstruktor zur evaluation
*
2020-03-20 17:08:18 +00:00
* @param type Typ der evaluation
* @param n Größe des Datensatzes
2020-04-05 18:53:52 +00:00
* @param alg 0 = lms, 1 = rm, 2 = ts, 3 = lms, rm, 4 = lms, ts, 5 = rm, ts, 6 = lms, rm, ts,
* @param datasettyp typ der zu generierenden Datensatz
2017-09-08 19:23:02 +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);
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;
}
/**
* Konstruktor zur evaluation
*
* @param type Typ der evaluation
2020-04-05 18:53:52 +00:00
* @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
*/
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);
this.type = type;
this.alg = alg;
2020-03-21 19:54:03 +00:00
}
2020-04-05 18:53:52 +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());
AlgorithmComparison comparison = new AlgorithmComparison(Arrays.asList(naiv, advanced),
Collections.unmodifiableSet(arrangement.getLines()));
2020-03-21 19:54:03 +00:00
ComparisonResult comparisonResult = comparison.compare();
2020-03-21 19:54:03 +00:00
Map<String, String> result = new HashMap<>();
2020-04-05 18:53:52 +00:00
result.putAll(
getScaleDependentMeasure(arrangement.getLines(), comparisonResult, advanced));
result.putAll(
getScaledErrorBasedMeasure(arrangement.getLines(), comparisonResult, advanced,
naiv));
2020-03-21 19:54:03 +00:00
Logging.logInfo("finished with execution of the algorithms.");
2020-03-21 19:54:03 +00:00
this.resultMapping.put(advanced, result);
return this.resultMapping;
}
2020-04-05 18:53:52 +00:00
private Map<Algorithm.Type, Map<String, String>> benchmarkDifferentEstimators(
List<Algorithm.Type> types) {
2020-03-21 19:54:03 +00:00
Logging.logInfo("AlgorithmComparison with Types: " + types);
2020-04-05 18:53:52 +00:00
AlgorithmComparison comparison = new AlgorithmComparison(types,
Collections.unmodifiableSet(arrangement.getLines()));
2020-03-21 19:54:03 +00:00
ComparisonResult comparisonResult = comparison.compare();
2020-04-05 18:53:52 +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;
}
/**
* 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);
switch (type) {
2017-09-07 17:39:55 +00:00
case 0:
//der alg der gewählt wurde
if (alg == 0) {
2020-04-05 18:53:52 +00:00
result = benchmarkSameEstimator(Algorithm.Type.LMS,
Algorithm.Type.NAIVE_LMS);
} else if (alg == 1) {
2020-04-05 18:53:52 +00:00
result = benchmarkSameEstimator(Algorithm.Type.RM,
Algorithm.Type.NAIVE_RM);
} else {
2020-04-05 18:53:52 +00:00
result = benchmarkSameEstimator(Algorithm.Type.TS,
Algorithm.Type.NAIVE_TS);
}
2017-09-07 17:39:55 +00:00
break;
case 1:
switch (alg) {
2017-09-08 19:23:02 +00:00
case 3:
2020-04-05 18:53:52 +00:00
result = benchmarkDifferentEstimators(
Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.RM));
2017-09-08 19:23:02 +00:00
break;
case 4:
2020-04-05 18:53:52 +00:00
result = benchmarkDifferentEstimators(
Arrays.asList(Algorithm.Type.LMS, Algorithm.Type.TS));
2017-09-08 19:23:02 +00:00
break;
case 5:
2020-04-05 18:53:52 +00:00
result = benchmarkDifferentEstimators(
Arrays.asList(Algorithm.Type.RM, Algorithm.Type.TS));
2017-09-08 19:23:02 +00:00
break;
case 6:
2020-04-05 18:53:52 +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
}
/**
* Die berechneten Ergebnisse werden an den Beobachter übermittelt um dann visualisiert zu werden.
2020-03-20 17:08:18 +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
}
/**
* Startet die Berechnung der skalierungsabbhängigen Maße.
2020-03-20 17:08:18 +00:00
*
* @param lines Liste der Geraden
2020-03-20 17:08:18 +00:00
* @return Liste mit den Ergebnissen, bereit zum visualisieren
*/
2020-04-05 18:53:52 +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
}
/**
* Startet die Berechnung der Maße die auf dem prozentualen Fehler basieren.
2020-03-20 17:08:18 +00:00
*
* @param lines Liste der Geraden
2020-03-20 17:08:18 +00:00
* @return Liste mit den Ergebnissen, bereit zum visualisieren
*/
2020-04-05 18:53:52 +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();
2020-04-05 18:53:52 +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
}
/**
* Startet die Berechnung der skalierungsunabbhängigen Maße.
2020-03-20 17:08:18 +00:00
*
* @param lines Liste der Geraden
2020-03-20 17:08:18 +00:00
* @return Liste mit den Ergebnissen, bereit zum visualisieren
*/
2020-04-05 18:53:52 +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();
2020-04-05 18:53:52 +00:00
ScaledErrorBasedMeasure scaledErrorBasedMeasure = new ScaledErrorBasedMeasure(lines, m,
b,
naivM, naivB);
2020-03-21 19:54:03 +00:00
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
}
/**
* @return Liste der Geraden auf der die Berechnungen ausgeführt wurden
*/
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
}