#2 -- complete additive trent and seasonality
This commit is contained in:
parent
6598df034d
commit
f3614979bd
@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import ru.ulstu.configurations.ApiConfiguration;
|
import ru.ulstu.configurations.ApiConfiguration;
|
||||||
import ru.ulstu.models.Forecast;
|
|
||||||
import ru.ulstu.models.ForecastParams;
|
import ru.ulstu.models.ForecastParams;
|
||||||
import ru.ulstu.models.TimeSeries;
|
import ru.ulstu.models.TimeSeries;
|
||||||
import ru.ulstu.models.exceptions.ModelingException;
|
import ru.ulstu.models.exceptions.ModelingException;
|
||||||
@ -52,7 +51,7 @@ public class TimeSeriesController {
|
|||||||
|
|
||||||
@PostMapping("getForecast")
|
@PostMapping("getForecast")
|
||||||
@ApiOperation("Получить прогноз временного ряда")
|
@ApiOperation("Получить прогноз временного ряда")
|
||||||
public ResponseEntity<Forecast> getForecastTimeSeries(@RequestBody ForecastParams forecastParams) throws ModelingException {
|
public ResponseEntity<TimeSeries> getForecastTimeSeries(@RequestBody ForecastParams forecastParams) throws ModelingException {
|
||||||
return new ResponseEntity<>(timeSeriesService.getForecast(forecastParams.getOriginalTimeSeries(),
|
return new ResponseEntity<>(timeSeriesService.getForecast(forecastParams.getOriginalTimeSeries(),
|
||||||
forecastParams.getCountForecast()), HttpStatus.OK);
|
forecastParams.getCountForecast()), HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
package ru.ulstu.models;
|
|
||||||
|
|
||||||
public class Forecast {
|
|
||||||
private Model model;
|
|
||||||
private TimeSeries forecast;
|
|
||||||
|
|
||||||
public Forecast(Model model) {
|
|
||||||
this.model = model;
|
|
||||||
this.forecast = new TimeSeries("Forecast time series of '" + model.getOriginalTimeSeries().getName() + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Model getModel() {
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSeries getForecastTimeSeries() {
|
|
||||||
return forecast;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addValue(TimeSeriesValue timeSeriesValue) {
|
|
||||||
forecast.addValue(timeSeriesValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Forecast{" +
|
|
||||||
"model=" + model +
|
|
||||||
", forecast=" + forecast +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package ru.ulstu.models;
|
|
||||||
|
|
||||||
public class Model {
|
|
||||||
private TimeSeries originalTimeSeries;
|
|
||||||
private TimeSeries modelTimeSeries;
|
|
||||||
|
|
||||||
public Model(TimeSeries originalTimeSeries) {
|
|
||||||
this.originalTimeSeries = originalTimeSeries;
|
|
||||||
this.modelTimeSeries = new TimeSeries("Model time series of '" + originalTimeSeries.getName() + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSeries getOriginalTimeSeries() {
|
|
||||||
return originalTimeSeries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimeSeries getModelTimeSeries() {
|
|
||||||
return modelTimeSeries;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addValue(TimeSeriesValue timeSeriesValue) {
|
|
||||||
modelTimeSeries.addValue(timeSeriesValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addValue(TimeSeriesValue basedOnValue, double value) {
|
|
||||||
modelTimeSeries.getValues().add(new TimeSeriesValue(basedOnValue.getDate(), value));
|
|
||||||
}
|
|
||||||
}
|
|
@ -53,7 +53,7 @@ public class TimeSeries {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addValue(TimeSeriesValue basedOnValue, Double value) {
|
public void addValue(TimeSeriesValue basedOnValue, Double value) {
|
||||||
values.add(new TimeSeriesValue(basedOnValue.getDate().plusDays(1), value));
|
values.add(new TimeSeriesValue(basedOnValue.getDate(), value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeSeriesValue getLastValue() {
|
public TimeSeriesValue getLastValue() {
|
||||||
|
@ -48,7 +48,7 @@ public class IndexView implements Serializable {
|
|||||||
LineChartSeries series2 = new LineChartSeries();
|
LineChartSeries series2 = new LineChartSeries();
|
||||||
series2.setLabel("Сглаженный ряд");
|
series2.setLabel("Сглаженный ряд");
|
||||||
try {
|
try {
|
||||||
for (TimeSeriesValue value : timeSeriesService.getForecast(timeSeries, 10).getModel().getModelTimeSeries().getValues()) {
|
for (TimeSeriesValue value : timeSeriesService.smoothTimeSeries(timeSeries).getValues()) {
|
||||||
series2.set(DateTimeFormatter.ISO_LOCAL_DATE.format(value.getDate()), value.getValue());
|
series2.set(DateTimeFormatter.ISO_LOCAL_DATE.format(value.getDate()), value.getValue());
|
||||||
}
|
}
|
||||||
} catch (ModelingException ex) {
|
} catch (ModelingException ex) {
|
||||||
@ -59,7 +59,7 @@ public class IndexView implements Serializable {
|
|||||||
LineChartSeries series3 = new LineChartSeries();
|
LineChartSeries series3 = new LineChartSeries();
|
||||||
series3.setLabel("Прогноз");
|
series3.setLabel("Прогноз");
|
||||||
try {
|
try {
|
||||||
for (TimeSeriesValue value : timeSeriesService.getForecast(timeSeries, 10).getForecastTimeSeries().getValues()) {
|
for (TimeSeriesValue value : timeSeriesService.getForecast(timeSeries, 5).getValues()) {
|
||||||
series3.set(DateTimeFormatter.ISO_LOCAL_DATE.format(value.getDate()), value.getValue());
|
series3.set(DateTimeFormatter.ISO_LOCAL_DATE.format(value.getDate()), value.getValue());
|
||||||
}
|
}
|
||||||
} catch (ModelingException ex) {
|
} catch (ModelingException ex) {
|
||||||
|
@ -4,19 +4,20 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.ulstu.TimeSeriesUtils;
|
import ru.ulstu.TimeSeriesUtils;
|
||||||
import ru.ulstu.models.Forecast;
|
|
||||||
import ru.ulstu.models.TimeSeries;
|
import ru.ulstu.models.TimeSeries;
|
||||||
import ru.ulstu.models.TimeSeriesValue;
|
import ru.ulstu.models.TimeSeriesValue;
|
||||||
import ru.ulstu.models.exceptions.ModelingException;
|
import ru.ulstu.models.exceptions.ModelingException;
|
||||||
|
import ru.ulstu.tsMethods.exponential.AddTrendNoSeason;
|
||||||
import ru.ulstu.tsMethods.exponential.ExponentialMethodParams;
|
import ru.ulstu.tsMethods.exponential.ExponentialMethodParams;
|
||||||
import ru.ulstu.tsMethods.exponential.ExponentialParamName;
|
|
||||||
import ru.ulstu.tsMethods.exponential.NoTrendNoSeason;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ru.ulstu.tsMethods.exponential.ExponentialParamName.ALPHA;
|
||||||
|
import static ru.ulstu.tsMethods.exponential.ExponentialParamName.BETA;
|
||||||
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TimeSeriesService {
|
public class TimeSeriesService {
|
||||||
@ -32,9 +33,16 @@ public class TimeSeriesService {
|
|||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Forecast getForecast(TimeSeries timeSeries, int countPoints) throws ModelingException {
|
public TimeSeries getForecast(TimeSeries timeSeries, int countPoints) throws ModelingException {
|
||||||
NoTrendNoSeason nn = new NoTrendNoSeason(ExponentialMethodParams.of(ExponentialParamName.ALPHA, 0.8));
|
//NoTrendNoSeason nn = new NoTrendNoSeason(ExponentialMethodParams.of(ExponentialParamName.ALPHA, 0.8));
|
||||||
return nn.getForecast(timeSeries, countPoints);
|
AddTrendNoSeason an = new AddTrendNoSeason(timeSeries, ExponentialMethodParams.of(ALPHA, 0.8, BETA, 0.8));
|
||||||
|
return an.getForecast(countPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeSeries smoothTimeSeries(TimeSeries timeSeries) throws ModelingException {
|
||||||
|
//NoTrendNoSeason nn = new NoTrendNoSeason(timeSeries, ExponentialMethodParams.of(ExponentialParamName.ALPHA, 0.8));
|
||||||
|
AddTrendNoSeason an = new AddTrendNoSeason(timeSeries, ExponentialMethodParams.of(ALPHA, 0.8, BETA, 0.8));
|
||||||
|
return an.getModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeSeries getTimeSeriesFromString(String tsString) {
|
public TimeSeries getTimeSeriesFromString(String tsString) {
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package ru.ulstu.tsMethods;
|
package ru.ulstu.tsMethods;
|
||||||
|
|
||||||
import ru.ulstu.TimeSeriesUtils;
|
import ru.ulstu.TimeSeriesUtils;
|
||||||
import ru.ulstu.models.Forecast;
|
|
||||||
import ru.ulstu.models.Model;
|
|
||||||
import ru.ulstu.models.TimeSeries;
|
import ru.ulstu.models.TimeSeries;
|
||||||
import ru.ulstu.models.TimeSeriesValue;
|
import ru.ulstu.models.TimeSeriesValue;
|
||||||
import ru.ulstu.models.exceptions.ForecastValidateException;
|
import ru.ulstu.models.exceptions.ForecastValidateException;
|
||||||
@ -15,44 +13,44 @@ import java.time.temporal.ChronoUnit;
|
|||||||
* Наиболее общая логика моделировани и прогнозирования временных рядов
|
* Наиболее общая логика моделировани и прогнозирования временных рядов
|
||||||
*/
|
*/
|
||||||
public abstract class TimeSeriesMethod {
|
public abstract class TimeSeriesMethod {
|
||||||
|
protected TimeSeries originalTimeSeries;
|
||||||
|
private TimeSeries model;
|
||||||
|
|
||||||
|
public TimeSeriesMethod(TimeSeries originalTimeSeries) throws ModelingException {
|
||||||
|
this.originalTimeSeries = originalTimeSeries;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает модельное представление временного ряда: для тех же точек времени что и в параметре timeSeries
|
* Возвращает модельное представление временного ряда: для тех же точек времени что и в параметре timeSeries
|
||||||
* строится модель. Количество точек может быть изменено: сокращено при сжатии ряда, увеличено при интерполяции.
|
* строится модель. Количество точек может быть изменено: сокращено при сжатии ряда, увеличено при интерполяции.
|
||||||
* Метод является шаблонным, выполняет операции валидации исходного ряда и потом его моделирование
|
* Метод является шаблонным, выполняет операции валидации исходного ряда и потом его моделирование
|
||||||
*
|
*
|
||||||
* @param timeSeries исходный временной ряд подлежащий моделированию
|
|
||||||
* @return модель временного ряда
|
* @return модель временного ряда
|
||||||
* @throws TimeSeriesValidateException
|
* @throws TimeSeriesValidateException
|
||||||
*/
|
*/
|
||||||
public Model getModel(TimeSeries timeSeries) throws ModelingException {
|
protected void makeModel() throws ModelingException {
|
||||||
validateTimeSeries(timeSeries);
|
validateTimeSeries();
|
||||||
return getModelOfValidTimeSeries(timeSeries);
|
model = getModelOfValidTimeSeries();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает модельное представление валидного временного ряда: для тех же точек времени что и в параметре timeSeries
|
* Возвращает модельное представление валидного временного ряда: для тех же точек времени что и в параметре timeSeries
|
||||||
* строится модель. Количество точек может быть изменено: сокращено при сжатии ряда, увеличено при интерполяции.
|
* строится модель. Количество точек может быть изменено: сокращено при сжатии ряда, увеличено при интерполяции.
|
||||||
*
|
*
|
||||||
* @param timeSeries исходный временной ряд подлежащий моделированию
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected abstract Model getModelOfValidTimeSeries(TimeSeries timeSeries) throws ModelingException;
|
protected abstract TimeSeries getModelOfValidTimeSeries() throws ModelingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Выполняет построение прогноза временного ряда. Даты спрогнозированных точек будут сгенерированы по модельным точкам.
|
* Выполняет построение прогноза временного ряда. Даты спрогнозированных точек будут сгенерированы по модельным точкам.
|
||||||
*
|
*
|
||||||
* @param model модель временного ряда
|
|
||||||
* @param countPoints количество точек для прогнозирования
|
* @param countPoints количество точек для прогнозирования
|
||||||
* @return прогноз временного ряда
|
* @return прогноз временного ряда
|
||||||
*/
|
*/
|
||||||
public Forecast getForecast(Model model, int countPoints) throws ModelingException {
|
public TimeSeries getForecastWithValidParams(int countPoints) throws ModelingException {
|
||||||
Forecast forecast = new Forecast(model);
|
TimeSeries forecast = generateEmptyForecastPoints(originalTimeSeries, countPoints);
|
||||||
forecast = generateEmptyForecastPoints(forecast, countPoints);
|
forecast.getFirstValue().setValue(getModel().getLastValue().getValue());
|
||||||
forecast = makeForecast(forecast);
|
forecast = makeForecast(forecast);
|
||||||
if (!forecast.getForecastTimeSeries().getFirstValue()
|
|
||||||
.equals(forecast.getModel().getModelTimeSeries().getLastValue())) {
|
|
||||||
throw new ForecastValidateException("Первая точка прогноза должна совпадать с последней модельной точкой");
|
|
||||||
}
|
|
||||||
return forecast;
|
return forecast;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,15 +60,14 @@ public abstract class TimeSeriesMethod {
|
|||||||
* @param forecast Заготовка прогноза временного ряда с пустыми значениями
|
* @param forecast Заготовка прогноза временного ряда с пустыми значениями
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected abstract Forecast makeForecast(Forecast forecast);
|
protected abstract TimeSeries makeForecast(TimeSeries forecast) throws ModelingException;
|
||||||
|
|
||||||
protected Forecast generateEmptyForecastPoints(Forecast forecast, int countPointForecast) {
|
protected TimeSeries generateEmptyForecastPoints(TimeSeries modelTimeSeries, int countPointForecast) {
|
||||||
long diffMilliseconds = TimeSeriesUtils.getTimeDifferenceInMilliseconds(forecast.getModel().getOriginalTimeSeries());
|
long diffMilliseconds = TimeSeriesUtils.getTimeDifferenceInMilliseconds(originalTimeSeries);
|
||||||
forecast.getForecastTimeSeries()
|
TimeSeries forecast = new TimeSeries("Forecast of " + originalTimeSeries.getName());
|
||||||
.addValue(new TimeSeriesValue(forecast.getModel().getModelTimeSeries().getLastValue().getDate()));
|
forecast.addValue(new TimeSeriesValue(modelTimeSeries.getLastValue().getDate()));
|
||||||
for (int i = 1; i < countPointForecast + 1; i++) {
|
for (int i = 1; i < countPointForecast + 1; i++) {
|
||||||
forecast.getForecastTimeSeries()
|
forecast.addValue(new TimeSeriesValue(forecast.getValues().get(i - 1).getDate().plus(diffMilliseconds, ChronoUnit.MILLIS)));
|
||||||
.addValue(new TimeSeriesValue(forecast.getForecastTimeSeries().getValues().get(i - 1).getDate().plus(diffMilliseconds, ChronoUnit.MILLIS)));
|
|
||||||
}
|
}
|
||||||
return forecast;
|
return forecast;
|
||||||
}
|
}
|
||||||
@ -79,13 +76,12 @@ public abstract class TimeSeriesMethod {
|
|||||||
* Выполняет построение модели и прогноза временного ряда. Даты спрогнозированных точек будут сгенерированы
|
* Выполняет построение модели и прогноза временного ряда. Даты спрогнозированных точек будут сгенерированы
|
||||||
* по модельным точкам.
|
* по модельным точкам.
|
||||||
*
|
*
|
||||||
* @param timeSeries временной ряда
|
|
||||||
* @param countPoints количество точек для прогнозирования
|
* @param countPoints количество точек для прогнозирования
|
||||||
* @return прогноз временного ряда
|
* @return прогноз временного ряда
|
||||||
*/
|
*/
|
||||||
public Forecast getForecast(TimeSeries timeSeries, int countPoints) throws ModelingException {
|
public TimeSeries getForecast(int countPoints) throws ModelingException {
|
||||||
validateForecastParams(countPoints);
|
validateForecastParams(countPoints);
|
||||||
return getForecast(getModel(timeSeries), countPoints);
|
return getForecastWithValidParams(countPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateForecastParams(int countPoints) throws ForecastValidateException {
|
private void validateForecastParams(int countPoints) throws ForecastValidateException {
|
||||||
@ -94,18 +90,25 @@ public abstract class TimeSeriesMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateTimeSeries(TimeSeries timeSeries) throws TimeSeriesValidateException {
|
private void validateTimeSeries() throws TimeSeriesValidateException {
|
||||||
if (timeSeries == null || timeSeries.isEmpty()) {
|
if (originalTimeSeries == null || originalTimeSeries.isEmpty()) {
|
||||||
throw new TimeSeriesValidateException("Временной ряд должен быть не пустым");
|
throw new TimeSeriesValidateException("Временной ряд должен быть не пустым");
|
||||||
}
|
}
|
||||||
if (timeSeries.getLength() < 2) {
|
if (originalTimeSeries.getLength() < 2) {
|
||||||
throw new TimeSeriesValidateException("Временной ряд должен содержать хотя бы 2 точки");
|
throw new TimeSeriesValidateException("Временной ряд должен содержать хотя бы 2 точки");
|
||||||
}
|
}
|
||||||
if (timeSeries.getValues().stream().anyMatch(val -> val == null || val.getValue() == null)) {
|
if (originalTimeSeries.getValues().stream().anyMatch(val -> val == null || val.getValue() == null)) {
|
||||||
throw new TimeSeriesValidateException("Временной ряд содержит пустые значения");
|
throw new TimeSeriesValidateException("Временной ряд содержит пустые значения");
|
||||||
}
|
}
|
||||||
if (timeSeries.getValues().stream().anyMatch(val -> val.getDate() == null)) {
|
if (originalTimeSeries.getValues().stream().anyMatch(val -> val.getDate() == null)) {
|
||||||
throw new TimeSeriesValidateException("Временной ряд должен иметь отметки времени");
|
throw new TimeSeriesValidateException("Временной ряд должен иметь отметки времени");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TimeSeries getModel() throws ModelingException {
|
||||||
|
if (model == null) {
|
||||||
|
makeModel();
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
package ru.ulstu.tsMethods.exponential;
|
||||||
|
|
||||||
|
import ru.ulstu.models.TimeSeries;
|
||||||
|
import ru.ulstu.models.exceptions.ModelingException;
|
||||||
|
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static ru.ulstu.tsMethods.exponential.ExponentialParamName.ALPHA;
|
||||||
|
import static ru.ulstu.tsMethods.exponential.ExponentialParamName.BETA;
|
||||||
|
|
||||||
|
public class AddTrendNoSeason extends TimeSeriesMethod {
|
||||||
|
private final ExponentialMethodParams exponentialMethodParams;
|
||||||
|
private final List<Double> sComponent = new ArrayList<>();
|
||||||
|
private final List<Double> tComponent = new ArrayList<>();
|
||||||
|
|
||||||
|
public AddTrendNoSeason(TimeSeries timeSeries, ExponentialMethodParams exponentialMethodParams) throws ModelingException {
|
||||||
|
super(timeSeries);
|
||||||
|
this.exponentialMethodParams = exponentialMethodParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TimeSeries getModelOfValidTimeSeries() throws ModelingException {
|
||||||
|
sComponent.clear();
|
||||||
|
tComponent.clear();
|
||||||
|
sComponent.add(originalTimeSeries.getFirstValue().getValue());
|
||||||
|
tComponent.add(originalTimeSeries.getValues().get(1).getValue() - originalTimeSeries.getValues().get(0).getValue());
|
||||||
|
TimeSeries model = new TimeSeries("Model of " + originalTimeSeries.getName());
|
||||||
|
model.addValue(originalTimeSeries.getFirstValue());
|
||||||
|
//выполняется проход модели по сглаживанию
|
||||||
|
for (int t = 1; t < originalTimeSeries.getValues().size(); t++) {
|
||||||
|
sComponent.add(exponentialMethodParams.getValue(ALPHA) * originalTimeSeries.getNumericValue(t)
|
||||||
|
+ (1 - exponentialMethodParams.getValue(ALPHA))
|
||||||
|
* (sComponent.get(t - 1) - tComponent.get(t - 1)));
|
||||||
|
|
||||||
|
tComponent.add(exponentialMethodParams.getValue(BETA)
|
||||||
|
* (sComponent.get(t) - sComponent.get(t - 1))
|
||||||
|
+ (1 - exponentialMethodParams.getValue(BETA)) * tComponent.get(t - 1));
|
||||||
|
model.addValue(originalTimeSeries.getValues().get(t), sComponent.get(sComponent.size() - 1));
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TimeSeries makeForecast(TimeSeries forecast) throws ModelingException {
|
||||||
|
for (int t = 1; t < forecast.getLength(); t++) {
|
||||||
|
/*int indexOffsetForModel = t + getModel().getLength() - 2;
|
||||||
|
sComponent.add(exponentialMethodParams.getValue(ALPHA) * forecast.getNumericValue(t-1)
|
||||||
|
+ (1 - exponentialMethodParams.getValue(ALPHA))
|
||||||
|
* (sComponent.get(indexOffsetForModel) - tComponent.get(indexOffsetForModel - 1)));
|
||||||
|
|
||||||
|
tComponent.add(exponentialMethodParams.getValue(BETA)
|
||||||
|
* (sComponent.get(indexOffsetForModel) - sComponent.get(indexOffsetForModel - 1))
|
||||||
|
+ (1 - exponentialMethodParams.getValue(BETA)) * tComponent.get(indexOffsetForModel - 1));*/
|
||||||
|
|
||||||
|
forecast.getValues().get(t).setValue(sComponent.get(sComponent.size() - 1) + tComponent.get(tComponent.size() - 1) * t);
|
||||||
|
}
|
||||||
|
return forecast;
|
||||||
|
}
|
||||||
|
}
|
@ -23,4 +23,8 @@ public class ExponentialMethodParams {
|
|||||||
public static ExponentialMethodParams of(ExponentialParamName param1, Double value1) {
|
public static ExponentialMethodParams of(ExponentialParamName param1, Double value1) {
|
||||||
return new ExponentialMethodParams(ImmutableMap.of(param1, value1));
|
return new ExponentialMethodParams(ImmutableMap.of(param1, value1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ExponentialMethodParams of(ExponentialParamName param1, Double value1, ExponentialParamName param2, Double value2) {
|
||||||
|
return new ExponentialMethodParams(ImmutableMap.of(param1, value1, param2, value2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,43 @@
|
|||||||
package ru.ulstu.tsMethods.exponential;
|
package ru.ulstu.tsMethods.exponential;
|
||||||
|
|
||||||
import ru.ulstu.models.Forecast;
|
|
||||||
import ru.ulstu.models.Model;
|
|
||||||
import ru.ulstu.models.TimeSeries;
|
import ru.ulstu.models.TimeSeries;
|
||||||
import ru.ulstu.models.exceptions.ModelingException;
|
import ru.ulstu.models.exceptions.ModelingException;
|
||||||
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
import ru.ulstu.tsMethods.TimeSeriesMethod;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static ru.ulstu.tsMethods.exponential.ExponentialParamName.ALPHA;
|
import static ru.ulstu.tsMethods.exponential.ExponentialParamName.ALPHA;
|
||||||
|
|
||||||
public class NoTrendNoSeason extends TimeSeriesMethod {
|
public class NoTrendNoSeason extends TimeSeriesMethod {
|
||||||
private ExponentialMethodParams exponentialMethodParams;
|
private final ExponentialMethodParams exponentialMethodParams;
|
||||||
|
private final List<Double> sComponent = new ArrayList<>();
|
||||||
|
|
||||||
public NoTrendNoSeason(ExponentialMethodParams exponentialMethodParams) {
|
public NoTrendNoSeason(TimeSeries timeSeries, ExponentialMethodParams exponentialMethodParams) throws ModelingException {
|
||||||
|
super(timeSeries);
|
||||||
this.exponentialMethodParams = exponentialMethodParams;
|
this.exponentialMethodParams = exponentialMethodParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Model getModelOfValidTimeSeries(TimeSeries timeSeries) throws ModelingException {
|
protected TimeSeries getModelOfValidTimeSeries() throws ModelingException {
|
||||||
Model model = new Model(timeSeries);
|
sComponent.clear();
|
||||||
model.addValue(timeSeries.getFirstValue());
|
sComponent.add(originalTimeSeries.getFirstValue().getValue());
|
||||||
|
TimeSeries model = new TimeSeries("Model of " + originalTimeSeries.getName());
|
||||||
|
model.addValue(originalTimeSeries.getFirstValue());
|
||||||
//выполняется проход модели по сглаживанию
|
//выполняется проход модели по сглаживанию
|
||||||
for (int t = 1; t < timeSeries.getValues().size(); t++) {
|
for (int t = 1; t < originalTimeSeries.getValues().size(); t++) {
|
||||||
model.addValue(timeSeries.getValues().get(t),
|
sComponent.add(sComponent.get(t - 1)
|
||||||
(1 - exponentialMethodParams.getValue(ALPHA)) * timeSeries.getNumericValue(t)
|
+ exponentialMethodParams.getValue(ALPHA)
|
||||||
+ exponentialMethodParams.getValue(ALPHA) * model.getModelTimeSeries().getValues().get(t - 1).getValue());
|
* (originalTimeSeries.getNumericValue(t) - sComponent.get(t - 1)));
|
||||||
|
model.addValue(originalTimeSeries.getValues().get(t), sComponent.get(sComponent.size() - 1));
|
||||||
}
|
}
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Forecast makeForecast(Forecast forecast) {
|
protected TimeSeries makeForecast(TimeSeries forecast) {
|
||||||
forecast.getForecastTimeSeries()
|
for (int t = 1; t < forecast.getLength(); t++) {
|
||||||
.getFirstValue()
|
forecast.getValues().get(t).setValue(forecast.getValues().get(t - 1).getValue());
|
||||||
.setValue(forecast.getModel().getModelTimeSeries().getLastValue().getValue());
|
|
||||||
for (int t = 1; t < forecast.getForecastTimeSeries().getLength(); t++) {
|
|
||||||
forecast.getForecastTimeSeries()
|
|
||||||
.getValues()
|
|
||||||
.get(t)
|
|
||||||
.setValue(forecast.getForecastTimeSeries().getValues().get(t - 1).getValue());
|
|
||||||
}
|
}
|
||||||
return forecast;
|
return forecast;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user