#3 -- add fuzzy time series for forecasting

This commit is contained in:
Anton Romanov 2022-04-21 11:54:55 +04:00
parent 4417fc2ceb
commit 371dfe5665
2 changed files with 53 additions and 23 deletions

View File

@ -1,21 +1,21 @@
package ru.ulstu.method.ftransform; package ru.ulstu.method.ftransform;
/** /**
* Треугольная функция принадлежности * Базисная функция
*/ */
public class AComponent { public class AComponent {
private int start; // левая граница треугольника private double start; // левая граница треугольника
private int end; // правая граница треугольника private double end; // правая граница треугольника
private int top; // вершина треугольника private double top; // вершина треугольника
public int getStart() { public double getStart() {
return start; return start;
} }
public AComponent() { public AComponent() {
} }
public AComponent(int start, int top, int end) { public AComponent(double start, double top, double end) {
this.start = start; this.start = start;
this.top = top; this.top = top;
this.end = end; this.end = end;
@ -26,19 +26,23 @@ public class AComponent {
} }
public int getEnd() { public double getEnd() {
return end; return end;
} }
public void setEnd(int end) { public void setEnd(double end) {
this.end = end; this.end = end;
} }
public int getTop() { public double getTop() {
return top; return top;
} }
public void setTop(int top) { public int getTopInt() {
return (int) Math.round(top);
}
public void setTop(double top) {
this.top = top; this.top = top;
} }
@ -54,4 +58,9 @@ public class AComponent {
} }
return 0; 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 org.springframework.stereotype.Component;
import ru.ulstu.datamodel.Model; import ru.ulstu.datamodel.Model;
import ru.ulstu.datamodel.ts.TimeSeries; import ru.ulstu.datamodel.ts.TimeSeries;
import ru.ulstu.datamodel.ts.TimeSeriesValue;
import ru.ulstu.method.Method; import ru.ulstu.method.Method;
import ru.ulstu.method.MethodParamValue; import ru.ulstu.method.MethodParamValue;
import ru.ulstu.method.MethodParameter; import ru.ulstu.method.MethodParameter;
import java.util.ArrayList;
import java.util.List; import java.util.List;
@Component @Component
public class FTransform extends Method { public class FTransform extends Method {
private final static int NUMBER_OF_FUZZY_VALUES = 3;
@Override @Override
protected FTransformModel getModelOfValidTimeSeries(TimeSeries ts, protected FTransformModel getModelOfValidTimeSeries(TimeSeries ts,
@ -29,8 +32,8 @@ public class FTransform extends Method {
sum1 += membership * ts.getNumericValue(j); sum1 += membership * ts.getNumericValue(j);
sum2 += membership; sum2 += membership;
} }
piecewiseLinearTrend.addValue(ts.getValue(aComponent.getTop()), sum1 / sum2); piecewiseLinearTrend.addValue(ts.getValue(aComponent.getTopInt()), sum1 / sum2);
tsModel.addValue(ts.getValue(aComponent.getTop()), sum1 / sum2); tsModel.addValue(ts.getValue(aComponent.getTopInt()), sum1 / sum2);
} }
return model; return model;
} }
@ -41,27 +44,27 @@ public class FTransform extends Method {
while (currentPoint < ts.getLength()) { while (currentPoint < ts.getLength()) {
int startPoint = (currentPoint == 0) int startPoint = (currentPoint == 0)
? 0 ? 0
: piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop(); : piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTopInt();
AComponent bf = new AComponent(startPoint, currentPoint, (int) (currentPoint + Math.round(numberOfCoveredPoints / 2.0))); AComponent aComponent = new AComponent(startPoint, currentPoint, (int) (currentPoint + Math.round(numberOfCoveredPoints / 2.0)));
if (bf.getStart() < 0) { if (aComponent.getStart() < 0) {
bf.setStart(0); aComponent.setStart(0);
} }
if (bf.getEnd() > ts.getLength() - 1) { if (aComponent.getEnd() > ts.getLength() - 1) {
bf.setEnd(ts.getLength() - 1); aComponent.setEnd(ts.getLength() - 1);
} }
if (bf.getTop() > ts.getLength() - 1) { if (aComponent.getTop() > ts.getLength() - 1) {
bf.setTop(ts.getLength() - 1); aComponent.setTop(ts.getLength() - 1);
} }
piecewiseLinearTrend.add(bf); piecewiseLinearTrend.add(aComponent);
currentPoint += deltaForTriangle; currentPoint += deltaForTriangle;
} }
if (piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd() != piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getTop()) { 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.get(piecewiseLinearTrend.size() - 1).getEnd()); piecewiseLinearTrend.get(piecewiseLinearTrend.size() - 1).getEnd());
piecewiseLinearTrend.add(bf); piecewiseLinearTrend.add(aComponent);
} }
return piecewiseLinearTrend; return piecewiseLinearTrend;
} }
@ -69,6 +72,24 @@ public class FTransform extends Method {
@Override @Override
protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) { protected TimeSeries getForecastWithValidParams(Model model, TimeSeries forecast) {
FTransformModel fTransformModel = (FTransformModel) model; 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++) { for (int t = 1; t < forecast.getLength(); t++) {
forecast.getValues().get(t).setValue(fTransformModel.getPiecewiseLinearTrend().getLastValue().getValue()); forecast.getValues().get(t).setValue(fTransformModel.getPiecewiseLinearTrend().getLastValue().getValue());
} }