create full brutforce over parameters
This commit is contained in:
parent
ce8fd32642
commit
65fa782b10
@ -1,3 +1,11 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.controllers;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@ -9,8 +17,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.ulstu.configuration.ApiConfiguration;
|
||||
import ru.ulstu.models.ForecastParams;
|
||||
import ru.ulstu.models.ModelingResult;
|
||||
import ru.ulstu.models.TimeSeries;
|
||||
import ru.ulstu.models.exceptions.ModelingException;
|
||||
import ru.ulstu.services.MethodParamBruteForce;
|
||||
import ru.ulstu.services.TimeSeriesService;
|
||||
|
||||
@RestController
|
||||
@ -18,9 +28,12 @@ import ru.ulstu.services.TimeSeriesService;
|
||||
public class TimeSeriesController {
|
||||
|
||||
private final TimeSeriesService timeSeriesService;
|
||||
private final MethodParamBruteForce methodParamBruteForce;
|
||||
|
||||
public TimeSeriesController(TimeSeriesService timeSeriesService) {
|
||||
public TimeSeriesController(TimeSeriesService timeSeriesService,
|
||||
MethodParamBruteForce methodParamBruteForce) {
|
||||
this.timeSeriesService = timeSeriesService;
|
||||
this.methodParamBruteForce = methodParamBruteForce;
|
||||
}
|
||||
|
||||
@PostMapping("getForecast")
|
||||
@ -29,4 +42,10 @@ public class TimeSeriesController {
|
||||
return new ResponseEntity<>(timeSeriesService.getForecast(forecastParams.getOriginalTimeSeries(),
|
||||
forecastParams.getCountForecast()), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("getSmoothed")
|
||||
@ApiOperation("Получить сглаженный временной ряд")
|
||||
public ResponseEntity<ModelingResult> getSmoothedTimeSeries(@RequestBody TimeSeries timeSeries) throws ModelingException {
|
||||
return new ResponseEntity<>(methodParamBruteForce.getSmoothedTimeSeries(timeSeries), HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,15 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.models;
|
||||
|
||||
import ru.ulstu.tsMethods.exponential.param.TimeSeriesMethodParamValue;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethodParamValue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -8,11 +17,16 @@ public class ModelingResult {
|
||||
private final TimeSeries timeSeries;
|
||||
private final List<TimeSeriesMethodParamValue> paramValues;
|
||||
private final Score score;
|
||||
private final TimeSeriesMethod timeSeriesMethod;
|
||||
|
||||
public ModelingResult(TimeSeries timeSeries, List<TimeSeriesMethodParamValue> paramValues, Score score) {
|
||||
public ModelingResult(TimeSeries timeSeries,
|
||||
List<TimeSeriesMethodParamValue> paramValues,
|
||||
Score score,
|
||||
TimeSeriesMethod timeSeriesMethod) {
|
||||
this.timeSeries = timeSeries;
|
||||
this.paramValues = paramValues;
|
||||
this.score = score;
|
||||
this.timeSeriesMethod = timeSeriesMethod;
|
||||
}
|
||||
|
||||
public TimeSeries getTimeSeries() {
|
||||
@ -26,4 +40,8 @@ public class ModelingResult {
|
||||
public Score getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public TimeSeriesMethod getTimeSeriesMethod() {
|
||||
return timeSeriesMethod;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,14 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import ru.ulstu.score.ScoreMethod;
|
||||
|
||||
public class Score {
|
||||
@ -18,4 +27,9 @@ public class Score {
|
||||
public Number getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Double getDoubleValue() {
|
||||
return value.doubleValue();
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,40 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.score;
|
||||
|
||||
import ru.ulstu.models.Score;
|
||||
import ru.ulstu.models.TimeSeries;
|
||||
import ru.ulstu.models.TimeSeriesValue;
|
||||
import ru.ulstu.models.exceptions.ModelingException;
|
||||
|
||||
public abstract class ScoreMethod {
|
||||
public abstract Number evaluate(TimeSeries originalTimeSeries, TimeSeries modelTimeSeries);
|
||||
private final String name;
|
||||
|
||||
public ScoreMethod(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Score getScore(TimeSeries original, TimeSeries model) throws ModelingException {
|
||||
return new Score(this, evaluate(original, model));
|
||||
}
|
||||
|
||||
public abstract Number evaluate(TimeSeries original, TimeSeries model) throws ModelingException;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
protected TimeSeriesValue getValueOnSameDate(TimeSeriesValue timeSeriesValueToFind, TimeSeries timeSeries) throws ModelingException {
|
||||
return timeSeries.getValues()
|
||||
.stream()
|
||||
.filter(v -> v.getDate().equals(timeSeriesValueToFind.getDate()))
|
||||
.findAny()
|
||||
.orElseThrow(() -> new ModelingException("Значение модельного ряда не найдено в оригинальном ряде: " + timeSeriesValueToFind.getDate()));
|
||||
}
|
||||
}
|
||||
|
33
src/main/java/ru/ulstu/score/Smape.java
Normal file
33
src/main/java/ru/ulstu/score/Smape.java
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.score;
|
||||
|
||||
import ru.ulstu.models.TimeSeries;
|
||||
import ru.ulstu.models.TimeSeriesValue;
|
||||
import ru.ulstu.models.exceptions.ModelingException;
|
||||
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
public class Smape extends ScoreMethod {
|
||||
public Smape() {
|
||||
super("Smape");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number evaluate(TimeSeries original, TimeSeries model) throws ModelingException {
|
||||
double sum = 0;
|
||||
for (TimeSeriesValue modelValue : model.getValues()) {
|
||||
double actualValue = getValueOnSameDate(modelValue, original).getValue();
|
||||
sum += abs(modelValue.getValue() - actualValue)
|
||||
/ ((abs(actualValue) + abs(modelValue.getValue())) / 2);
|
||||
}
|
||||
sum = Math.round(sum * 100) / 100;
|
||||
return sum * 100 / model.getLength();
|
||||
}
|
||||
}
|
@ -1,60 +1,138 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.services;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.ulstu.models.ModelingResult;
|
||||
import ru.ulstu.models.TimeSeries;
|
||||
import ru.ulstu.models.exceptions.ModelingException;
|
||||
import ru.ulstu.score.ScoreMethod;
|
||||
import ru.ulstu.score.Smape;
|
||||
import ru.ulstu.tsMethods.MethodParameter;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
||||
import ru.ulstu.tsMethods.exponential.param.TimeSeriesMethodParam;
|
||||
import ru.ulstu.tsMethods.exponential.param.TimeSeriesMethodParamValue;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethodParamValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
@Service
|
||||
public class MethodParamBruteForce {
|
||||
private final int DEFAULT_THREAD_COUNT = 10;
|
||||
private final List<TimeSeriesMethod> methods;
|
||||
private ExecutorService executors = Executors.newFixedThreadPool(10);
|
||||
private final ScoreMethod scoreMethod = new Smape();
|
||||
private final ExecutorService executors = Executors.newFixedThreadPool(DEFAULT_THREAD_COUNT);
|
||||
|
||||
public MethodParamBruteForce(List<TimeSeriesMethod> methods) {
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
public TimeSeries getForecast(TimeSeries timeSeries) {
|
||||
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
public TimeSeries getForecastWithOptimalLength(TimeSeries timeSeries) {
|
||||
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
public TimeSeries getSmoothedTimeSeries(TimeSeries timeSeries) {
|
||||
List<Future<ModelingResult>> results = new ArrayList<>();
|
||||
public ModelingResult getSmoothedTimeSeries(TimeSeries timeSeries) throws ModelingException {
|
||||
//List<Future<ModelingResult>> results = new ArrayList<>();
|
||||
List<ModelingResult> results2 = new CopyOnWriteArrayList<>();
|
||||
for (TimeSeriesMethod method : methods) {
|
||||
List<TimeSeriesMethodParam> availableParams = method.getAvailableParams();
|
||||
Map<TimeSeriesMethodParam, List<Number>> paramsAvailableValues = new HashMap<>();
|
||||
for (TimeSeriesMethodParam param : availableParams) {
|
||||
paramsAvailableValues.put(param, param.getAvailableValues());
|
||||
List<List<TimeSeriesMethodParamValue>> availableParametersValues = getAvailableParametersValues(method.getAvailableParameters());
|
||||
for (List<TimeSeriesMethodParamValue> parametersValues : availableParametersValues) {
|
||||
/*results.add(executors.submit(() -> {
|
||||
TimeSeries model = method.createFor(timeSeries)
|
||||
.setAvailableParameters(parametersValues)
|
||||
.getModel();
|
||||
return new ModelingResult(model, parametersValues, scoreMethod.getScore(timeSeries, model));
|
||||
}));*/
|
||||
|
||||
TimeSeries model = method.createFor(timeSeries)
|
||||
.setAvailableParameters(parametersValues)
|
||||
.getModel();
|
||||
results2.add(new ModelingResult(model,
|
||||
parametersValues,
|
||||
scoreMethod.getScore(timeSeries, model),
|
||||
method));
|
||||
}
|
||||
List<TimeSeriesMethodParamValue> paramValues = new ArrayList<>();
|
||||
results.add(executors.submit(() -> {
|
||||
return new ModelingResult(method.getModel(),
|
||||
method.createFor(timeSeries)
|
||||
.setAvailableParams(paramValues)
|
||||
.getModel());
|
||||
}));
|
||||
}
|
||||
TimeSeries result = null;
|
||||
try {
|
||||
result = results.get(0).get();
|
||||
/*results.forEach(modelingResultFuture -> {
|
||||
try {
|
||||
modelingResultFuture.get();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
for (Future<ModelingResult> futureModelingResult: results) {
|
||||
results2.add(futureModelingResult.get());
|
||||
}*/
|
||||
return results2.stream()
|
||||
.min(Comparator.comparing(modelingResult -> modelingResult.getScore().getDoubleValue()))
|
||||
.orElse(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<List<TimeSeriesMethodParamValue>> getAvailableParametersValues(List<MethodParameter> availableParameters) {
|
||||
List<List<TimeSeriesMethodParamValue>> result = new ArrayList<>();
|
||||
Map<MethodParameter, Integer> parameterOffset = new TreeMap<>();
|
||||
Map<MethodParameter, List<Number>> parameterValues = new TreeMap<>();
|
||||
for (MethodParameter methodParameter : availableParameters) {
|
||||
parameterOffset.put(methodParameter, 0);
|
||||
parameterValues.put(methodParameter, methodParameter.getAvailableValues());
|
||||
}
|
||||
while (!isAllValuesUsed(parameterOffset, parameterValues)) {
|
||||
List<TimeSeriesMethodParamValue> resultRow = new ArrayList<>();
|
||||
for (MethodParameter methodParameter : parameterOffset.keySet()) {
|
||||
resultRow.add(new TimeSeriesMethodParamValue(methodParameter,
|
||||
parameterValues.get(methodParameter).get(parameterOffset.get(methodParameter))));
|
||||
}
|
||||
incrementOffset(parameterOffset, parameterValues);
|
||||
result.add(resultRow);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void incrementOffset(Map<MethodParameter, Integer> parameterOffset,
|
||||
Map<MethodParameter, List<Number>> parameterValues) {
|
||||
List<MethodParameter> parameters = new ArrayList<>(parameterOffset.keySet());
|
||||
int i = 0;
|
||||
while (i < parameters.size() && !isAllValuesUsed(parameterOffset, parameterValues)) {
|
||||
if (parameterOffset.get(parameters.get(i)) == parameterValues.get(parameters.get(i)).size() - 1) {
|
||||
parameterOffset.put(parameters.get(i), 0);
|
||||
i++;
|
||||
//continue;
|
||||
}
|
||||
if (parameterOffset.get(parameters.get(i)) < parameterValues.get(parameters.get(i)).size()) {
|
||||
parameterOffset.put(parameters.get(i), parameterOffset.get(parameters.get(i)) + 1);
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAllValuesUsed(Map<MethodParameter, Integer> parameterOffset,
|
||||
Map<MethodParameter, List<Number>> parameterValues) {
|
||||
for (MethodParameter methodParameter : parameterOffset.keySet()) {
|
||||
if (parameterOffset.get(methodParameter) != parameterValues.get(methodParameter).size() - 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,8 @@ import ru.ulstu.models.exceptions.ModelingException;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
||||
import ru.ulstu.tsMethods.exponential.AddTrendAddSeason;
|
||||
import ru.ulstu.tsMethods.exponential.NoTrendNoSeason;
|
||||
import ru.ulstu.tsMethods.exponential.param.Alpha;
|
||||
import ru.ulstu.tsMethods.exponential.param.Beta;
|
||||
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParamValue;
|
||||
import ru.ulstu.tsMethods.exponential.param.Gamma;
|
||||
import ru.ulstu.tsMethods.exponential.param.Season;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.Alpha;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue;
|
||||
|
||||
|
||||
@Service
|
||||
@ -29,24 +26,16 @@ public class TimeSeriesService {
|
||||
|
||||
public TimeSeries getForecast(TimeSeries timeSeries, int countPoints) throws ModelingException {
|
||||
TimeSeriesMethod method;
|
||||
method = new NoTrendNoSeason(timeSeries, new ExponentialMethodParamValue<>(new Alpha(), 0.8));
|
||||
method = new AddTrendAddSeason(timeSeries,
|
||||
new ExponentialMethodParamValue<>(new Alpha(), 0.5),
|
||||
new ExponentialMethodParamValue<>(new Beta(), 0.5),
|
||||
new ExponentialMethodParamValue<>(new Gamma(), 0.5),
|
||||
new ExponentialMethodParamValue<>(new Season(), 17));
|
||||
method = new NoTrendNoSeason().createFor(timeSeries).setAlpha(new ExponentialMethodParamValue<>(new Alpha(), 0.8));
|
||||
method = new AddTrendAddSeason().createFor(timeSeries);
|
||||
return method.getForecast(countPoints);
|
||||
}
|
||||
|
||||
public TimeSeries smoothTimeSeries(TimeSeries timeSeries) throws ModelingException {
|
||||
//NoTrendNoSeason nn = new NoTrendNoSeason(timeSeries, ExponentialMethodParams.of(ExponentialParamName.ALPHA, 0.8));
|
||||
TimeSeriesMethod method;
|
||||
method = new NoTrendNoSeason(timeSeries, new ExponentialMethodParamValue<>(new Alpha(), 0.8));
|
||||
method = new AddTrendAddSeason(timeSeries,
|
||||
new ExponentialMethodParamValue<>(new Alpha(), 0.5),
|
||||
new ExponentialMethodParamValue<>(new Beta(), 0.5),
|
||||
new ExponentialMethodParamValue<>(new Gamma(), 0.5),
|
||||
new ExponentialMethodParamValue<>(new Season(), 17));
|
||||
method = new NoTrendNoSeason().createFor(timeSeries);
|
||||
method = new AddTrendAddSeason().createFor(timeSeries);
|
||||
return method.getModel();
|
||||
}
|
||||
}
|
||||
|
30
src/main/java/ru/ulstu/tsMethods/MethodParameter.java
Normal file
30
src/main/java/ru/ulstu/tsMethods/MethodParameter.java
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class MethodParameter implements Comparable {
|
||||
protected String name;
|
||||
|
||||
public MethodParameter(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public abstract List<Number> getAvailableValues();
|
||||
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
return this.name.compareTo(((MethodParameter) o).getName());
|
||||
}
|
||||
}
|
@ -1,22 +1,31 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import ru.ulstu.TimeSeriesUtils;
|
||||
import ru.ulstu.models.TimeSeries;
|
||||
import ru.ulstu.models.TimeSeriesValue;
|
||||
import ru.ulstu.models.exceptions.ForecastValidateException;
|
||||
import ru.ulstu.models.exceptions.ModelingException;
|
||||
import ru.ulstu.models.exceptions.TimeSeriesValidateException;
|
||||
import ru.ulstu.tsMethods.exponential.param.TimeSeriesMethodParam;
|
||||
import ru.ulstu.tsMethods.exponential.param.TimeSeriesMethodParamValue;
|
||||
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Наиболее общая логика моделировани и прогнозирования временных рядов
|
||||
* Наиболее общая логика моделировании и прогнозирования временных рядов
|
||||
*/
|
||||
public abstract class TimeSeriesMethod {
|
||||
@JsonIgnore
|
||||
protected TimeSeries originalTimeSeries;
|
||||
@JsonIgnore
|
||||
private TimeSeries model;
|
||||
|
||||
public abstract TimeSeriesMethod createFor(TimeSeries originalTimeSeries);
|
||||
@ -113,13 +122,15 @@ public abstract class TimeSeriesMethod {
|
||||
}
|
||||
|
||||
public TimeSeries getModel() throws ModelingException {
|
||||
if (model == null) {
|
||||
makeModel();
|
||||
}
|
||||
//TODO: what if always run?
|
||||
//if (model == null) {
|
||||
makeModel();
|
||||
//}
|
||||
return model;
|
||||
}
|
||||
|
||||
public abstract List<TimeSeriesMethodParam> getAvailableParams();
|
||||
@JsonIgnore
|
||||
public abstract List<MethodParameter> getAvailableParameters();
|
||||
|
||||
public abstract TimeSeriesMethod setAvailableParams(List<TimeSeriesMethodParamValue> params);
|
||||
public abstract TimeSeriesMethod setAvailableParameters(List<TimeSeriesMethodParamValue> parameters);
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
*
|
||||
* * Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||
* * You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods;
|
||||
|
||||
public class TimeSeriesMethodParamValue {
|
||||
protected MethodParameter parameter;
|
||||
protected Number value;
|
||||
|
||||
public TimeSeriesMethodParamValue(MethodParameter parameter, Number value) {
|
||||
this.parameter = parameter;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public MethodParameter getParameter() {
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public Number getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
@ -11,35 +11,51 @@ package ru.ulstu.tsMethods.exponential;
|
||||
import ru.ulstu.models.TimeSeries;
|
||||
import ru.ulstu.models.exceptions.ModelingException;
|
||||
import ru.ulstu.models.exceptions.TimeSeriesValidateException;
|
||||
import ru.ulstu.tsMethods.MethodParameter;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
||||
import ru.ulstu.tsMethods.exponential.param.Alpha;
|
||||
import ru.ulstu.tsMethods.exponential.param.Beta;
|
||||
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParamValue;
|
||||
import ru.ulstu.tsMethods.exponential.param.Gamma;
|
||||
import ru.ulstu.tsMethods.exponential.param.Season;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethodParamValue;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.Alpha;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.Beta;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.Gamma;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.Season;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class AddTrendAddSeason extends TimeSeriesMethod {
|
||||
private final ExponentialMethodParamValue<Alpha> alpha;
|
||||
private final ExponentialMethodParamValue<Beta> beta;
|
||||
private final ExponentialMethodParamValue<Gamma> gamma;
|
||||
private final ExponentialMethodParamValue<Season> season;
|
||||
private ExponentialMethodParamValue<Alpha> alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5);
|
||||
private ExponentialMethodParamValue<Beta> beta = new ExponentialMethodParamValue<>(Beta.getInstance(), 0.5);
|
||||
private ExponentialMethodParamValue<Gamma> gamma = new ExponentialMethodParamValue<>(Gamma.getInstance(), 0.5);
|
||||
private ExponentialMethodParamValue<Season> season = new ExponentialMethodParamValue<>(Season.getInstance(), 12);
|
||||
private final List<Double> sComponent = new ArrayList<>();
|
||||
private final List<Double> tComponent = new ArrayList<>();
|
||||
private final List<Double> iComponent = new ArrayList<>();
|
||||
|
||||
public AddTrendAddSeason(TimeSeries timeSeries,
|
||||
ExponentialMethodParamValue<Alpha> alpha,
|
||||
ExponentialMethodParamValue<Beta> beta,
|
||||
ExponentialMethodParamValue<Gamma> gamma,
|
||||
ExponentialMethodParamValue<Season> season) throws ModelingException {
|
||||
super(timeSeries);
|
||||
public AddTrendAddSeason createFor(TimeSeries timeSeries) {
|
||||
this.originalTimeSeries = timeSeries;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AddTrendAddSeason setAlpha(ExponentialMethodParamValue<Alpha> alpha) {
|
||||
this.alpha = alpha;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AddTrendAddSeason setBeta(ExponentialMethodParamValue<Beta> beta) {
|
||||
this.beta = beta;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AddTrendAddSeason setGamma(ExponentialMethodParamValue<Gamma> gamma) {
|
||||
this.gamma = gamma;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AddTrendAddSeason setSeason(ExponentialMethodParamValue<Season> season) {
|
||||
this.season = season;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,4 +116,28 @@ public class AddTrendAddSeason extends TimeSeriesMethod {
|
||||
}
|
||||
return forecast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MethodParameter> getAvailableParameters() {
|
||||
return Arrays.asList(alpha.getParam(), beta.getParam(), gamma.getParam(), season.getParam());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSeriesMethod setAvailableParameters(List<TimeSeriesMethodParamValue> parameters) {
|
||||
for (TimeSeriesMethodParamValue parameter : parameters) {
|
||||
if (parameter.getParameter() instanceof Alpha) {
|
||||
alpha.setValue(parameter.getValue());
|
||||
}
|
||||
if (parameter.getParameter() instanceof Beta) {
|
||||
beta.setValue(parameter.getValue());
|
||||
}
|
||||
if (parameter.getParameter() instanceof Gamma) {
|
||||
gamma.setValue(parameter.getValue());
|
||||
}
|
||||
if (parameter.getParameter() instanceof Season) {
|
||||
season.setValue(parameter.getValue());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -8,32 +8,43 @@
|
||||
|
||||
package ru.ulstu.tsMethods.exponential;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.ulstu.models.TimeSeries;
|
||||
import ru.ulstu.models.exceptions.ModelingException;
|
||||
import ru.ulstu.tsMethods.MethodParameter;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
||||
import ru.ulstu.tsMethods.exponential.param.Alpha;
|
||||
import ru.ulstu.tsMethods.exponential.param.Beta;
|
||||
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParamValue;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethodParamValue;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.Alpha;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.Beta;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class AddTrendNoSeason extends TimeSeriesMethod {
|
||||
private final ExponentialMethodParamValue<Alpha> alpha;
|
||||
private final ExponentialMethodParamValue<Beta> beta;
|
||||
private ExponentialMethodParamValue<Alpha> alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5);
|
||||
private ExponentialMethodParamValue<Beta> beta = new ExponentialMethodParamValue<>(Beta.getInstance(), 0.5);
|
||||
private final List<Double> sComponent = new ArrayList<>();
|
||||
private final List<Double> tComponent = new ArrayList<>();
|
||||
|
||||
public AddTrendNoSeason(TimeSeries timeSeries,
|
||||
ExponentialMethodParamValue<Alpha> alpha,
|
||||
ExponentialMethodParamValue<Beta> beta) throws ModelingException {
|
||||
super(timeSeries);
|
||||
public AddTrendNoSeason createFor(TimeSeries timeSeries) {
|
||||
this.originalTimeSeries = timeSeries;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AddTrendNoSeason setAlpha(ExponentialMethodParamValue<Alpha> alpha) {
|
||||
this.alpha = alpha;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AddTrendNoSeason setBeta(ExponentialMethodParamValue<Beta> beta) {
|
||||
this.beta = beta;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TimeSeries getModelOfValidTimeSeries() throws ModelingException {
|
||||
protected TimeSeries getModelOfValidTimeSeries() {
|
||||
sComponent.clear();
|
||||
tComponent.clear();
|
||||
sComponent.add(originalTimeSeries.getFirstValue().getValue());
|
||||
@ -61,4 +72,22 @@ public class AddTrendNoSeason extends TimeSeriesMethod {
|
||||
}
|
||||
return forecast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MethodParameter> getAvailableParameters() {
|
||||
return Arrays.asList(alpha.getParam(), beta.getParam());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSeriesMethod setAvailableParameters(List<TimeSeriesMethodParamValue> parameters) {
|
||||
for (TimeSeriesMethodParamValue parameter : parameters) {
|
||||
if (parameter.getParameter() instanceof Alpha) {
|
||||
alpha.setValue(parameter.getValue());
|
||||
}
|
||||
if (parameter.getParameter() instanceof Beta) {
|
||||
beta.setValue(parameter.getValue());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -8,21 +8,20 @@
|
||||
|
||||
package ru.ulstu.tsMethods.exponential;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.ulstu.models.TimeSeries;
|
||||
import ru.ulstu.models.exceptions.ModelingException;
|
||||
import ru.ulstu.tsMethods.MethodParameter;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
||||
import ru.ulstu.tsMethods.exponential.param.Alpha;
|
||||
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParam;
|
||||
import ru.ulstu.tsMethods.exponential.param.ExponentialMethodParamValue;
|
||||
import ru.ulstu.tsMethods.TimeSeriesMethodParamValue;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.Alpha;
|
||||
import ru.ulstu.tsMethods.exponential.parameter.ExponentialMethodParamValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
|
||||
public class NoTrendNoSeason extends TimeSeriesMethod {
|
||||
private ExponentialMethodParamValue<Alpha> alpha;
|
||||
private ExponentialMethodParamValue<Alpha> alpha = new ExponentialMethodParamValue<>(Alpha.getInstance(), 0.5);
|
||||
private final List<Double> sComponent = new ArrayList<>();
|
||||
|
||||
public NoTrendNoSeason createFor(TimeSeries timeSeries) {
|
||||
@ -36,7 +35,7 @@ public class NoTrendNoSeason extends TimeSeriesMethod {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TimeSeries getModelOfValidTimeSeries() throws ModelingException {
|
||||
protected TimeSeries getModelOfValidTimeSeries() {
|
||||
sComponent.clear();
|
||||
sComponent.add(originalTimeSeries.getFirstValue().getValue());
|
||||
TimeSeries model = new TimeSeries("Model of " + originalTimeSeries.getName());
|
||||
@ -60,15 +59,15 @@ public class NoTrendNoSeason extends TimeSeriesMethod {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExponentialMethodParam> getAvailableParams() {
|
||||
public List<MethodParameter> getAvailableParameters() {
|
||||
return Collections.singletonList(alpha.getParam());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSeriesMethod setAvailableParams(List<ExponentialMethodParamValue> params) {
|
||||
for (ExponentialMethodParamValue param : params) {
|
||||
if (param.getParam() instanceof Alpha) {
|
||||
alpha.setValue(param.getValue());
|
||||
public TimeSeriesMethod setAvailableParameters(List<TimeSeriesMethodParamValue> parameters) {
|
||||
for (TimeSeriesMethodParamValue parameter : parameters) {
|
||||
if (parameter.getParameter() instanceof Alpha) {
|
||||
alpha.setValue(parameter.getValue());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
@ -6,10 +6,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods.exponential.param;
|
||||
package ru.ulstu.tsMethods.exponential.parameter;
|
||||
|
||||
public class Alpha extends ExponentialMethodParam {
|
||||
public class Alpha extends ExponentialMethodParameter {
|
||||
public Alpha() {
|
||||
super("ALPHA", 0, 1, DEFAULT_OPTIMIZATION_STEP);
|
||||
}
|
||||
|
||||
public static Alpha getInstance() {
|
||||
return new Alpha();
|
||||
}
|
||||
}
|
@ -6,10 +6,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods.exponential.param;
|
||||
package ru.ulstu.tsMethods.exponential.parameter;
|
||||
|
||||
public class Beta extends ExponentialMethodParam {
|
||||
public class Beta extends ExponentialMethodParameter {
|
||||
public Beta() {
|
||||
super("BETA", 0, 1, DEFAULT_OPTIMIZATION_STEP);
|
||||
}
|
||||
|
||||
public static Beta getInstance() {
|
||||
return new Beta();
|
||||
}
|
||||
}
|
@ -6,9 +6,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods.exponential.param;
|
||||
package ru.ulstu.tsMethods.exponential.parameter;
|
||||
|
||||
public class ExponentialMethodParamValue<T extends ExponentialMethodParam> {
|
||||
public class ExponentialMethodParamValue<T extends ExponentialMethodParameter> {
|
||||
private final T param;
|
||||
private Number value;
|
||||
|
@ -6,26 +6,27 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods.exponential.param;
|
||||
package ru.ulstu.tsMethods.exponential.parameter;
|
||||
|
||||
public abstract class ExponentialMethodParam {
|
||||
public static final Float DEFAULT_OPTIMIZATION_STEP = 0.01f;
|
||||
private final String key;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import ru.ulstu.tsMethods.MethodParameter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ExponentialMethodParameter extends MethodParameter {
|
||||
public static final Float DEFAULT_OPTIMIZATION_STEP = 0.1f;
|
||||
private final Number minValue;
|
||||
private final Number maxValue;
|
||||
private final Number optimizationStep;
|
||||
|
||||
public ExponentialMethodParam(String key, Number minValue, Number maxValue, Number optimizationStep) {
|
||||
this.key = key;
|
||||
public ExponentialMethodParameter(String name, Number minValue, Number maxValue, Number optimizationStep) {
|
||||
super(name);
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
this.optimizationStep = optimizationStep;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public Number getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
@ -38,10 +39,20 @@ public abstract class ExponentialMethodParam {
|
||||
return optimizationStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public List<Number> getAvailableValues() {
|
||||
List<Number> values = new ArrayList<>();
|
||||
for (double i = minValue.doubleValue(); i <= maxValue.doubleValue(); i += optimizationStep.doubleValue()) {
|
||||
values.add(i);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TimeSeriesMethodParam{" +
|
||||
"key='" + key + '\'' +
|
||||
"name='" + name + '\'' +
|
||||
", minValue=" + minValue +
|
||||
", maxValue=" + maxValue +
|
||||
", delta=" + optimizationStep +
|
@ -6,10 +6,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods.exponential.param;
|
||||
package ru.ulstu.tsMethods.exponential.parameter;
|
||||
|
||||
public class Gamma extends ExponentialMethodParam {
|
||||
public class Gamma extends ExponentialMethodParameter {
|
||||
public Gamma() {
|
||||
super("Gamma", 0, 1, DEFAULT_OPTIMIZATION_STEP);
|
||||
}
|
||||
|
||||
public static Gamma getInstance() {
|
||||
return new Gamma();
|
||||
}
|
||||
}
|
@ -6,12 +6,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ru.ulstu.tsMethods.exponential.param;
|
||||
package ru.ulstu.tsMethods.exponential.parameter;
|
||||
|
||||
public class Season extends ExponentialMethodParam {
|
||||
public class Season extends ExponentialMethodParameter {
|
||||
private final static int DEFAULT_SEASON_OPTIMIZATION_STEP = 1;
|
||||
|
||||
public Season() {
|
||||
super("Сезонность", 0, 12, DEFAULT_SEASON_OPTIMIZATION_STEP);
|
||||
}
|
||||
|
||||
public static Season getInstance() {
|
||||
return new Season();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user