Skip to content

Commit 64d25d7

Browse files
Add parameters forecast (#100)
* Remove Chi and Chisq, add parameters to forecasting * add forecast * tests working * address sugestions
1 parent 8da36eb commit 64d25d7

File tree

7 files changed

+72
-155
lines changed

7 files changed

+72
-155
lines changed

docs/src/manual.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@ this is handled internally.
9393
| :------- |:---------------:|:--------------------:|
9494
|[`Beta`](@ref)|||
9595
|[`BetaLocationScale`](@ref)|| x |
96-
|[`Chi`](@ref)|||
97-
|[`Chisq`](@ref)|||
9896
|[`Exponential`](@ref)|||
9997
|[`Gamma`](@ref)|||
10098
|[`LogitNormal`](@ref)|||
@@ -110,8 +108,6 @@ this is handled internally.
110108
```@docs
111109
ScoreDrivenModels.Beta
112110
ScoreDrivenModels.BetaLocationScale
113-
ScoreDrivenModels.Chi
114-
ScoreDrivenModels.Chisq
115111
ScoreDrivenModels.Exponential
116112
ScoreDrivenModels.Gamma
117113
ScoreDrivenModels.LogitNormal

src/ScoreDrivenModels.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ include("distributions/non_native_dists.jl")
3333
include("distributions/common_interface.jl")
3434
include("distributions/beta.jl")
3535
include("distributions/betalocationscale.jl")
36-
include("distributions/chi.jl")
37-
include("distributions/chisq.jl")
3836
include("distributions/exponential.jl")
3937
include("distributions/gamma.jl")
4038
include("distributions/logitnormal.jl")

src/distributions/chi.jl

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/distributions/chisq.jl

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/distributions/common_interface.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
const DISTS = [
33
Beta,
44
BetaLocationScale,
5-
Chi,
6-
Chisq,
75
Exponential,
86
Gamma,
97
LogitNormal,

src/simulate.jl

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
export simulate, forecast_quantiles
1+
export simulate, forecast
22

33
mutable struct Forecast{T <: AbstractFloat}
4-
quantiles::Matrix{T}
5-
scenarios::Matrix{T}
4+
observation_quantiles::Matrix{T}
5+
observation_forecast::Vector{T}
6+
observation_scenarios::Matrix{T}
7+
parameter_quantiles::Array{T, 3}
8+
parameter_forecast::Matrix{T}
9+
parameter_scenarios::Array{T, 3}
610
end
711

812
"""
@@ -20,19 +24,29 @@ function simulate(series::Vector{T}, gas::Model{D, T}, H::Int, S::Int;
2024
# Filter params estimated on the time series
2125
params = score_driven_recursion(gas, series; initial_params = initial_params)
2226
biggest_lag = number_of_lags(gas)
23-
params_simulation = params[(end - biggest_lag):(end - 1), :]
27+
n_params = num_params(D)
28+
params_simulation = params[(end - biggest_lag + 1):end, :]
2429
# Create scenarios matrix
25-
scenarios = Matrix{T}(undef, H, S)
30+
observation_scenarios = Matrix{T}(undef, H, S)
31+
parameter_scenarios = Array{T, 3}(undef, H, n_params, S)
2632
for scenario in 1:S
27-
sim, param = simulate_recursion(gas, H + biggest_lag + 1; initial_params = params_simulation)
28-
scenarios[:, scenario] = sim[biggest_lag + 2:end]
33+
# Notice that we know the parameter time_varying parameters for T + 1
34+
# So the last initial_params is already a part of the future simulation
35+
# And we must take the
36+
sim, param = simulate_recursion(gas, H + biggest_lag; initial_params = params_simulation)
37+
observation_scenarios[:, scenario] = sim[biggest_lag+1:end]
38+
# The first param is known
39+
parameter_scenarios[1, :, scenario] = params_simulation[end, :]
40+
# The last param (param[end, :]) is actually in a time step bigger
41+
# than H
42+
parameter_scenarios[2:end, :, scenario] = param[biggest_lag+1:end-1, :]
2943
end
30-
return scenarios
44+
return observation_scenarios, parameter_scenarios
3145
end
3246

3347

3448
"""
35-
forecast_quantiles(series::Vector{T}, gas::Model{D, T}, H::Int; kwargs...) where {D, T}
49+
forecast(series::Vector{T}, gas::Model{D, T}, H::Int; kwargs...) where {D, T}
3650
3751
Forecast quantiles for future values of a time series by updating the GAS recursion `H` times and
3852
using Monte Carlo method as in Blasques, Francisco, Siem Jan Koopman,
@@ -49,17 +63,40 @@ By default this method uses the `stationary_initial_params` method to perform th
4963
score driven recursion. If you estimated the model with a different set of `initial_params`
5064
use them here to maintain the coherence of your estimation.
5165
"""
52-
function forecast_quantiles(series::Vector{T}, gas::Model{D, T}, H::Int;
53-
initial_params::Matrix{T} = stationary_initial_params(gas),
54-
quantiles::Vector{T} = T.([0.025, 0.5, 0.975]), S::Int = 10_000) where {D, T}
66+
function forecast(series::Vector{T}, gas::Model{D, T}, H::Int;
67+
initial_params::Matrix{T} = stationary_initial_params(gas),
68+
quantiles::Vector{T} = T.([0.025, 0.5, 0.975]), S::Int = 10_000) where {D, T}
5569

56-
scenarios = simulate(series, gas, H, S; initial_params = initial_params)
57-
return Forecast(get_quantiles(quantiles, scenarios), scenarios)
70+
observation_scenarios, parameter_scenarios = simulate(series, gas, H, S;
71+
initial_params = initial_params)
72+
return Forecast(
73+
get_quantiles(quantiles, observation_scenarios),
74+
mean(observation_scenarios, dims = 2)[:],
75+
observation_scenarios,
76+
get_quantiles(quantiles, parameter_scenarios),
77+
mean(parameter_scenarios, dims = 3)[:, :, 1],
78+
parameter_scenarios
79+
)
5880
end
5981

60-
function get_quantiles(quantile_probs::Vector{T}, scenarios::Matrix{T}) where T
61-
@assert all((quantile_probs .< 1.0) .& (quantile_probs .> 0.0))
62-
unique!(sort!(quantile_probs))
63-
quantiles = mapslices(x -> quantile(x, quantile_probs), scenarios; dims = 2)
82+
function get_quantiles(quantiles_probs::Vector{T}, scenarios::Matrix{T}) where T
83+
@assert all((quantiles_probs .< 1.0) .& (quantiles_probs .> 0.0))
84+
unique!(sort!(quantiles_probs))
85+
quantiles = mapslices(x -> quantile(x, quantiles_probs), scenarios; dims = 2)
6486
return quantiles
6587
end
88+
89+
function get_quantiles(quantiles_probs::Vector{T}, scenarios::Array{T, 3}) where T
90+
@assert all((quantiles_probs .< 1.0) .& (quantiles_probs .> 0.0))
91+
unique!(sort!(quantiles_probs))
92+
quantiles_per_parameter = Array{T, 3}(undef,
93+
size(scenarios, 1),
94+
size(scenarios, 2),
95+
length(quantiles_probs)
96+
)
97+
for j in 1:size(scenarios, 2)
98+
quantiles_per_parameter[:, j, :] = mapslices(x -> quantile(x, quantiles_probs),
99+
scenarios[:, j, :]; dims = 2)
100+
end
101+
return quantiles_per_parameter
102+
end

test/test_simulate.jl

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,23 @@
1111
gas.B[1] = convert(Matrix{Float64}, Diagonal(3*v))
1212
gas.B[12] = convert(Matrix{Float64}, Diagonal(-3*v))
1313

14-
scenarios = simulate(y, gas, 50, 1000)
15-
@test maximum(scenarios) < 1e5
16-
@test minimum(scenarios) > 0
14+
scenarios_observations, scenarios_params = simulate(y, gas, 50, 1000)
15+
@test maximum(scenarios_observations) < 1e5
16+
@test minimum(scenarios_observations) > 0
1717

18-
forecast = forecast_quantiles(y, gas, 50)
19-
@test all([forecast.quantiles[i, 1] .< forecast.quantiles[i, 2] .< forecast.quantiles[i, 3] for i in 1:50])
20-
@test maximum(forecast.quantiles) < 1e3
21-
@test minimum(forecast.quantiles) > 1e-4
18+
forec = forecast(y, gas, 50)
19+
@test all([forec.observation_quantiles[i, 1] .<
20+
forec.observation_quantiles[i, 2] .<
21+
forec.observation_quantiles[i, 3] for i in 1:50])
22+
@test all([forec.parameter_quantiles[i, 1, 1] <=
23+
forec.parameter_quantiles[i, 1, 2] <=
24+
forec.parameter_quantiles[i, 1, 3] for i in 1:50])
25+
@test all([forec.parameter_quantiles[i, 2, 1] <=
26+
forec.parameter_quantiles[i, 2, 2] <=
27+
forec.parameter_quantiles[i, 2, 3] for i in 1:50])
28+
@test maximum(forec.observation_quantiles) < 1e3
29+
@test minimum(forec.observation_quantiles) > 1e-4
30+
31+
@test minimum(forec.parameter_scenarios[:, 2, :]) > 0.0
2232
end
2333
end

0 commit comments

Comments
 (0)