#3 -- add fuzzy time series for forecasting

This commit is contained in:
Anton Romanov 2022-04-21 11:54:55 +04:00 committed by Anton Skalkin
parent 151d44b362
commit e9adff9a87
2 changed files with 53 additions and 23 deletions

View File

@ -1,21 +1,21 @@
package ru.ulstu.method.ftransform;
/**
* Треугольная функция принадлежности
* Базисная функция
*/
public class AComponent {
private int start; // левая граница треугольника
private int end; // правая граница треугольника
private int top; // вершина треугольника
private double start; // левая граница треугольника
private double end; // правая граница треугольника
private double top; // вершина треугольника
public int getStart() {
public double getStart() {
return start;
}
public AComponent() {
}
public AComponent(int start, int top, int end) {
public AComponent(double start, double top, double end) {
this.start = start;
this.top = top;
this.end = end;
@ -26,19 +26,23 @@ public class AComponent {
}
public int getEnd() {
public double getEnd() {
return end;
}
public void setEnd(int end) {
public void setEnd(double end) {
this.end = end;
}
public int getTop() {
public double getTop() {
return top;
}
public void setTop(int top) {
public int getTopInt() {
return (int) Math.round(top);
}
public void setTop(double top) {
this.top = top;
}
@ -54,4 +58,9 @@ public class AComponent {
}
return 0;
}
@Override
public String toString() {
return "start=" + start;
}
}

View File

@ -3,14 +3,17 @@ package ru.ulstu.method.ftransform;
import org.springframework.stereotype.Component;
import ru.ulstu.datamodel.Model;
import ru.ulstu.datamodel.ts.TimeSeries;
import ru.ulstu.datamodel.ts.TimeSeriesValue;
import ru.ulstu.method.Method;
import ru.ulstu.method.MethodParamValue;
import ru.ulstu.method.MethodParameter;
import java.util.ArrayList;
import java.util.List;
@Component
public class FTransform extends Method {
private final static int NUMBER_OF_FUZZY_VALUES = 3;
@Override
protected FTransformModel getModelOfValidTimeSeries(TimeSeries ts,
@ -29,8 +32,8 @@ public class FTransform extends Method {
sum1 += membership * ts.getNumericValue(j);
sum2 += membership;
}
piecewiseLinearTrend.addValue(ts.getValue(aComponent.getTop()), sum1 / sum2);
tsModel.addValue(ts.getValue(aComponent.getTop()), sum1 / sum2);
piecewiseLinearTrend.addValue(ts.getValue(aComponent.getTopInt()), sum1 / sum2);
tsModel.addValue(ts.getValue(aComponent.getTopInt()), sum1 / sum2);
}
return model;
}
@ -41,27 +44,27 @@ public class FTransform extends Method {
while (currentPoint < ts.getLength()) {
int startPoint = (currentPoint == 0)
? 0
: piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop();
AComponent bf = new AComponent(startPoint, currentPoint, (int) (currentPoint + Math.round(numberOfCoveredPoints / 2.0)));
if (bf.getStart() < 0) {
bf.setStart(0);
: piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTopInt();
AComponent aComponent = new AComponent(startPoint, currentPoint, (int) (currentPoint + Math.round(numberOfCoveredPoints / 2.0)));
if (aComponent.getStart() < 0) {
aComponent.setStart(0);
}
if (bf.getEnd() > ts.getLength() - 1) {
bf.setEnd(ts.getLength() - 1);
if (aComponent.getEnd() > ts.getLength() - 1) {
aComponent.setEnd(ts.getLength() - 1);
}
if (bf.getTop() > ts.getLength() - 1) {
bf.setTop(ts.getLength() - 1);
if (aComponent.getTop() > ts.getLength() - 1) {
aComponent.setTop(ts.getLength() - 1);
}
piecewiseLinearTrend.add(bf);
piecewiseLinearTrend.add(aComponent);
currentPoint += deltaForTriangle;
}
if (piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd() != piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop()) {
AComponent bf = new AComponent(piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop(),
AComponent aComponent = new AComponent(piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop(),
piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd(),
piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd());
piecewiseLinearTrend.add(bf);
piecewiseLinearTrend.add(aComponent);
}
return piecewiseLinearTrend;
}
@ -69,6 +72,24 @@ public class FTransform extends Method {
@Override
protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) {
FTransformModel fTransformModel = (FTransformModel) model;
double minValue = fTransformModel.getPiecewiseLinearTrend().getValues().stream().map(TimeSeriesValue::getValue).min(Double::compareTo).orElse(0.0);
double maxValue = fTransformModel.getPiecewiseLinearTrend().getValues().stream().map(TimeSeriesValue::getValue).max(Double::compareTo).orElse(0.0);
List<AComponent> fuzzyValues = new ArrayList<>();
double diff = (maxValue - minValue) / NUMBER_OF_FUZZY_VALUES;
for (int i = 0; i < NUMBER_OF_FUZZY_VALUES; i++) {
fuzzyValues.add(new AComponent(i * diff, i * diff + diff / 2, i * diff + diff));
}
List<AComponent> fuzzyTimeSeries = new ArrayList<>();
for (int i = 0; i < model.getTimeSeriesModel().getLength(); i++) {
for (AComponent fuzzyValue : fuzzyValues) {
if (model.getTimeSeriesModel().getValue(i).getValue() >= fuzzyValue.getStart()
&& model.getTimeSeriesModel().getValue(i).getValue() <= fuzzyValue.getEnd()) {
fuzzyTimeSeries.add(fuzzyValue);
}
}
}
for (int t = 1; t < forecast.getLength(); t++) {
forecast.getValues().get(t).setValue(fTransformModel.getPiecewiseLinearTrend().getLastValue().getValue());
}