| 1 | #' @title get Forecast |
| 2 | #' |
| 3 | #' @description Predict time-series curves for the selected days indices (lines in data). |
| 4 | #' Run the forecasting task described by \code{delta_forecaster_name} and |
| 5 | #' \code{shape_forecaster_name} on data obtained with \code{getData} |
| 6 | #' |
| 7 | #' @param data Dataset, object of type \code{Data} output of \code{getData} |
| 8 | #' @param indices Days indices where to forecast (the day after) |
| 9 | #' @param memory Data depth (in days) to be used for prediction |
| 10 | #' @param horizon Number of time steps to predict |
| 11 | #' @param shape_forecaster_name Name of the shape forcaster |
| 12 | #' \itemize{ |
| 13 | #' \item Persistence : use values of last (similar, next) day |
| 14 | #' \item Neighbors : use PM10 from the k closest neighbors' tomorrows |
| 15 | #' \item Average : global average of all the (similar) "tomorrow of past" |
| 16 | #' } |
| 17 | #' @param delta_forecaster_name Name of the delta forecaster |
| 18 | #' \itemize{ |
| 19 | #' \item Persistence : use last (similar) day values |
| 20 | #' \item Neighbors: re-use the weights optimized in corresponding shape forecaster |
| 21 | #' \item Zero: just output 0 (no adjustment) |
| 22 | #' } |
| 23 | #' @param ... Additional parameters for the forecasting models |
| 24 | #' |
| 25 | #' @return An object of class Forecast |
| 26 | #' |
| 27 | #' @examples |
| 28 | #' data = getData(ts_data="data/pm10_mesures_H_loc.csv", exo_data="data/meteo_extra_noNAs.csv", |
| 29 | #' input_tz = "Europe/Paris", working_tz="Europe/Paris", predict_at="07") |
| 30 | #' pred = getForecast(data, 2200:2230, Inf, 12, "Persistence", "Persistence") |
| 31 | #' \dontrun{#Sketch for real-time mode: |
| 32 | #' data = new("Data", ...) |
| 33 | #' repeat { |
| 34 | #' data$append(some_new_data) |
| 35 | #' pred = getForecast(data, ...) |
| 36 | #' #do_something_with_pred |
| 37 | #' }} |
| 38 | #' @export |
| 39 | getForecast = function(data, indices, memory, horizon, |
| 40 | shape_forecaster_name, delta_forecaster_name, ...) |
| 41 | { |
| 42 | horizon = as.integer(horizon)[1] |
| 43 | if (horizon<=0 || horizon>length(data$getCenteredSerie(2))) |
| 44 | stop("Horizon too short or too long") |
| 45 | indices = sapply( seq_along(indices), function(i) dateIndexToInteger(indices[i], data) ) |
| 46 | if (any(indices<=0 | indices>data$getSize())) |
| 47 | stop("Indices out of range") |
| 48 | indices = sapply(indices, dateIndexToInteger, data) |
| 49 | |
| 50 | #NOTE: some assymetry here... |
| 51 | shape_forecaster = new(paste(shape_forecaster_name,"ShapeForecaster",sep=""), data=data) |
| 52 | #A little bit strange, but match.fun() and get() fail |
| 53 | delta_forecaster = getFromNamespace( |
| 54 | paste("get",delta_forecaster_name,"DeltaForecast",sep=""), "talweg") |
| 55 | |
| 56 | pred = list() |
| 57 | for (today in indices) |
| 58 | { |
| 59 | #shape always predicted first (on centered series, no scaling taken into account), |
| 60 | #with side-effect: optimize some parameters (h, weights, ...) |
| 61 | predicted_shape = shape_forecaster$predict(today, memory, horizon, ...) |
| 62 | #then, delta prediction can re-use some variables optimized previously (like neighbors infos) |
| 63 | predicted_delta = delta_forecaster(data, today, memory, horizon, |
| 64 | shape_forecaster$getParameters(), ...) |
| 65 | |
| 66 | #TODO: this way is faster than a call to append(); why ? |
| 67 | pred[[length(pred)+1]] = list( |
| 68 | # Predict shape and align it on end of current day |
| 69 | serie = predicted_shape + tail( data$getSerie(today), 1 ) - predicted_shape[1] + |
| 70 | predicted_delta, #add predicted jump |
| 71 | params = shape_forecaster$getParameters(), |
| 72 | index = today ) |
| 73 | } |
| 74 | new("Forecast",pred=pred) |
| 75 | } |