292 lines
8.8 KiB
Java
292 lines
8.8 KiB
Java
package Presenter.Evaluation;
|
|
|
|
import Model.Interval;
|
|
import Model.Line;
|
|
import Model.LineModel;
|
|
import Model.Point;
|
|
import Presenter.Algorithms.*;
|
|
import Presenter.Generator.DatasetGenerator;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.LinkedList;
|
|
import java.util.List;
|
|
import java.util.Observable;
|
|
import javax.swing.JOptionPane;
|
|
import sun.awt.image.ImageWatched.Link;
|
|
|
|
/**
|
|
* Implementierung verschiedener Algorithmen zur Berechnung von Ausgleichsgeraden.
|
|
*
|
|
* @Author: Armin Wolf
|
|
* @Email: a_wolf28@uni-muenster.de
|
|
* @Date: 01.08.2017.
|
|
*/
|
|
public class EvaluateAlgorithms extends Observable {
|
|
|
|
private Double m;
|
|
private Double b;
|
|
private Integer iterationCount;
|
|
|
|
private LineModel arrangement;
|
|
|
|
private LinkedList<Line> lms;
|
|
private LinkedList<Line> rm;
|
|
private LinkedList<Line> ts;
|
|
|
|
private LinkedList<Point> nodeLms;
|
|
private LinkedList<Point> nodeTs;
|
|
|
|
private String[] lmsResult;
|
|
private String[] rmResult;
|
|
private String[] tsResult;
|
|
/*
|
|
ret.add(mse(errorValues).toString());
|
|
ret.add(rmse(errorValues).toString());
|
|
ret.add(mae(errorValues).toString());
|
|
ret.add(mdae(errorValues).toString());
|
|
|
|
ret.add(mape(perrorValues).toString());
|
|
ret.add(mdape(perrorValues).toString());
|
|
ret.add(rmspe(perrorValues).toString());
|
|
ret.add(rmdspe(perrorValues).toString());
|
|
*/
|
|
private String[] names = {"MSE", "RMSE", "MAE", "MDAE", "MAPE", "MDAPE", "RMSPE", "RMDSPE"};
|
|
|
|
private Thread lmsThread;
|
|
private Thread rmThread;
|
|
private Thread tsThread;
|
|
|
|
private Double[] tsRes = new Double[2];
|
|
private Double[] rmRes = new Double[2];
|
|
private Double[] lmsRes = new Double[2];
|
|
|
|
public EvaluateAlgorithms(Double m, Double b, Integer iterationCount) {
|
|
this.m = m;
|
|
this.b = b;
|
|
this.iterationCount = iterationCount;
|
|
}
|
|
|
|
public EvaluateAlgorithms(){
|
|
this.m = null;
|
|
this.b = null;
|
|
this.iterationCount = 1;
|
|
}
|
|
|
|
public void run() throws InterruptedException {
|
|
|
|
|
|
this.arrangement = new LineModel();
|
|
|
|
DatasetGenerator generator;
|
|
|
|
if (m != null && b != null) {
|
|
generator = new DatasetGenerator(m, b);
|
|
} else {
|
|
generator = new DatasetGenerator();
|
|
}
|
|
|
|
arrangement.setLines(generator.generateDataset());
|
|
setChanged();
|
|
String[] msg = {"eval-dataset-generated"};
|
|
notifyObservers(msg);
|
|
|
|
IntersectionCounter counter = new IntersectionCounter();
|
|
counter.run(arrangement.getLines(), new Interval(-99999, 99999));
|
|
counter.calculateIntersectionAbscissas(arrangement);
|
|
|
|
lms = new LinkedList<>(arrangement.getLines());
|
|
rm = new LinkedList<>(arrangement.getLines());
|
|
ts = new LinkedList<>(arrangement.getLines());
|
|
nodeLms = new LinkedList<>(arrangement.getNodes());
|
|
nodeTs = new LinkedList<>(arrangement.getNodes());
|
|
|
|
|
|
|
|
lmsThread = new Thread(() -> {
|
|
LeastMedianOfSquaresEstimator lmsAlg = new LeastMedianOfSquaresEstimator(lms, nodeLms);
|
|
lmsAlg.run();
|
|
lmsAlg.getResult();
|
|
List<Double> errors = sampsonError(arrangement.getLines(), lmsAlg.getSlope(), lmsAlg.getyInterception());
|
|
List<Double> perrors = percentigeError(arrangement.getLines(), lmsAlg.getSlope(), lmsAlg.getyInterception());
|
|
|
|
lmsRes[0] = lmsAlg.getSlope();
|
|
lmsRes[1] = lmsAlg.getyInterception();
|
|
lmsResult = getResults(errors,perrors);
|
|
|
|
});
|
|
rmThread = new Thread(() -> {
|
|
RepeatedMedianEstimator rmAlg = new RepeatedMedianEstimator(rm);
|
|
rmAlg.run();
|
|
rmAlg.getResult();
|
|
List<Double> errors = sampsonError(arrangement.getLines(), rmAlg.getSlope(), rmAlg.getyInterception());
|
|
List<Double> perrors = percentigeError(arrangement.getLines(), rmAlg.getSlope(), rmAlg.getyInterception());
|
|
|
|
rmRes[0] = rmAlg.getSlope();
|
|
rmRes[1] = rmAlg.getyInterception();
|
|
rmResult = getResults(errors,perrors);
|
|
});
|
|
tsThread = new Thread(() -> {
|
|
TheilSenEstimator tsAlg = new TheilSenEstimator(ts, nodeTs);
|
|
tsAlg.run();
|
|
tsAlg.getResult();
|
|
List<Double> errors = sampsonError(arrangement.getLines(), tsAlg.getSlope(), tsAlg.getyInterception());
|
|
List<Double> perrors = percentigeError(arrangement.getLines(), tsAlg.getSlope(), tsAlg.getyInterception());
|
|
tsRes[0] = tsAlg.getSlope();
|
|
tsRes[1] = tsAlg.getyInterception();
|
|
tsResult = getResults(errors,perrors);
|
|
});
|
|
|
|
lmsThread.start();
|
|
rmThread.start();
|
|
tsThread.start();
|
|
|
|
lmsThread.join();
|
|
rmThread.join();
|
|
tsThread.join();
|
|
|
|
createGlobalResult();
|
|
|
|
}
|
|
|
|
public void createGlobalResult(){
|
|
ArrayList<String> result = new ArrayList<>();
|
|
for (int i=0;i<names.length;i++){
|
|
result.add("eval");
|
|
result.add(names[i]);
|
|
result.add(tsResult[i]);
|
|
result.add(rmResult[i]);
|
|
result.add(lmsResult[i]);
|
|
setChanged();
|
|
notifyObservers(result.stream().toArray(String[]::new));
|
|
result.clear();
|
|
}
|
|
|
|
String[] separator = {"eval", "", "", "", ""};
|
|
setChanged();
|
|
notifyObservers(separator);
|
|
|
|
//visualisiere m,b
|
|
|
|
ArrayList<String> lines = new ArrayList<>();
|
|
lines.add("lines-res");
|
|
//lms res
|
|
lines.add(lmsRes[0]+"");
|
|
lines.add(lmsRes[1]+"");
|
|
|
|
//rm res
|
|
lines.add(rmRes[0]+"");
|
|
lines.add(rmRes[1]+"");
|
|
|
|
//ts res
|
|
lines.add(tsRes[0]+"");
|
|
lines.add(tsRes[1]+"");
|
|
|
|
setChanged();
|
|
notifyObservers(lines.stream().toArray(String[]::new));
|
|
}
|
|
|
|
|
|
public String[] getResults(List<Double> errorValues, List<Double> perrorValues) {
|
|
|
|
ArrayList<String> ret = new ArrayList<>();
|
|
ret.add(mse(errorValues).toString());
|
|
ret.add(rmse(errorValues).toString());
|
|
ret.add(mae(errorValues).toString());
|
|
ret.add(mdae(errorValues).toString());
|
|
|
|
ret.add(mape(perrorValues).toString());
|
|
ret.add(mdape(perrorValues).toString());
|
|
ret.add(rmspe(perrorValues).toString());
|
|
ret.add(rmdspe(perrorValues).toString());
|
|
|
|
|
|
return ret.stream().toArray(String[]::new);
|
|
}
|
|
|
|
/* Skalierungs Abhängige Approximationsgüten */
|
|
public Double mse(List<Double> errorValues) {
|
|
double error = 0;
|
|
|
|
for (Double d : errorValues) {
|
|
error += Math.pow(d, 2);
|
|
}
|
|
|
|
error /= errorValues.size();
|
|
|
|
return error;
|
|
}
|
|
|
|
public Double rmse(List<Double> errorValues) {
|
|
return Math.sqrt(mse(errorValues));
|
|
}
|
|
|
|
public Double mae(List<Double> errorValues) {
|
|
double error = 0;
|
|
|
|
for (Double d : errorValues) {
|
|
error += Math.abs(d);
|
|
}
|
|
|
|
error /= errorValues.size();
|
|
|
|
return error;
|
|
}
|
|
|
|
public Double mdae(List<Double> errorValues) {
|
|
return FastElementSelector.randomizedSelect((ArrayList<Double>) errorValues, errorValues.size() * 0.5);
|
|
}
|
|
|
|
|
|
/* Percentege Error Approximation Measures */
|
|
public Double mape(List<Double> errorValues){
|
|
return mae(errorValues);
|
|
}
|
|
|
|
public Double mdape(List<Double> errorValues){
|
|
return mape(errorValues);
|
|
}
|
|
|
|
public Double rmspe(List<Double> errorValues){
|
|
return rmse(errorValues);
|
|
}
|
|
|
|
public Double rmdspe(List<Double> errorValues){
|
|
ArrayList squares = new ArrayList();
|
|
for (Double d : errorValues){
|
|
squares.add(Math.pow(d,2));
|
|
}
|
|
|
|
return Math.sqrt(FastElementSelector.randomizedSelect(squares, squares.size() * 0.5));
|
|
}
|
|
|
|
|
|
public List<Double> percentigeError(final LinkedList<Line> lines, Double m, Double b){
|
|
ArrayList<Double> sampsonError = (ArrayList<Double>) sampsonError(lines, m, b);
|
|
ArrayList<Double> r = new ArrayList<>();
|
|
|
|
for (int j=0;j<sampsonError.size();j++){
|
|
r.add(100 * sampsonError.get(j) / lines.get(j).getB());
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
public List<Double> sampsonError(final LinkedList<Line> lines, Double m, Double b) {
|
|
|
|
//Liste mit den Fehler zu jedem Punkt
|
|
List<Double> sampsonerror = new ArrayList<>();
|
|
|
|
for (Line line : lines) {
|
|
Double error = Math.pow(m * line.getM() - line.getB() + b, 2) / (Math.pow(m, 2) + 1);
|
|
sampsonerror.add(error);
|
|
}
|
|
|
|
return sampsonerror;
|
|
}
|
|
|
|
|
|
public LinkedList<Line> getData(){
|
|
return arrangement.getLines();
|
|
}
|
|
}
|