Skip to content

Commit 73d44f1

Browse files
Fitted quantiles and SDMForecast (#98)
* added fitted quantiles and SDMforecast * update default verbose * remove fitted quantiles * update
1 parent da07836 commit 73d44f1

File tree

9 files changed

+28
-24
lines changed

9 files changed

+28
-24
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Manifest.toml
22
docs/build/
33
.DS_Store
4-
docs/.DS_Store
4+
docs/.DS_Store
5+
paper_scripts/

examples/cpichg.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ y = readdlm("./test/data/cpichg.csv")[:]
66
gas = Model(1, 1, TDistLocationScale, 0.0, time_varying_params = [1; 2])
77

88
# Estimate the model
9-
@time f = fit!(gas, y)
9+
f = fit!(gas, y)
1010

1111
estimation_stats = fit_stats(f)

src/MLE.jl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export fit, fit!, fit_stats
22

33
const DEFAULT_INITIAL_PARAM = NaN.*ones(1, 1)
44
const DEFAULT_NUM_SEEDS = 3
5-
const DEFAULT_VERBOSE = 0
5+
const DEFAULT_VERBOSE = 1
66
const VARIANCE_ZERO = 1e-10
77

88
struct Fitted{D <: Distribution, T <: AbstractFloat}
@@ -96,6 +96,7 @@ function fit(gas::Model{D, T}, y::Vector{T};
9696
opt_method::AbstractOptimizationMethod = NelderMead(gas, DEFAULT_NUM_SEEDS),
9797
verbose::Int = DEFAULT_VERBOSE) where {D, T}
9898

99+
verbose in [0, 1, 2, 3] || throw(ErrorException, "verbose argument must be in [0, 1, 2, 3]")
99100
# Number of initial_points and number of params to estimate
100101
n_initial_points = length(opt_method.initial_points)
101102
n = length(y)
@@ -114,18 +115,20 @@ function fit(gas::Model{D, T}, y::Vector{T};
114115

115116
for i = 1:n_initial_points
116117
try
117-
func = TwiceDifferentiable(psi_tilde -> log_lik(psi_tilde, y, gas_fit, initial_params, unknowns, n), opt_method.initial_points[i])
118+
func = TwiceDifferentiable(psi_tilde -> log_lik(psi_tilde, y, gas_fit,
119+
initial_params, unknowns, n),
120+
opt_method.initial_points[i])
118121
opt_result = optimize(func, opt_method, verbose, i)
119122
update_aux_estimation!(aux_est, func, opt_result)
120-
println("Round $i of $n_initial_points - Log-likelihood: $(-opt_result.minimum)")
123+
verbose >= 1 && println("Round $i of $n_initial_points - Log-likelihood: $(-opt_result.minimum)")
121124
catch err
122125
println(err)
123-
println("Round $i diverged")
126+
verbose >= 1 && println("Round $i diverged")
124127
end
125128
end
126129

127130
if isempty(aux_est.loglikelihood)
128-
println("No initial point converged.")
131+
verbose >= 1 && println("No initial point converged.")
129132
return
130133
end
131134

@@ -135,12 +138,11 @@ function fit(gas::Model{D, T}, y::Vector{T};
135138
aic = AIC(n_unknowns, best_llk)
136139
bic = BIC(n, n_unknowns, best_llk)
137140

138-
if verbose >= 1
141+
if verbose >= 2
139142
println("\nBest optimization result:")
140143
println(aux_est.opt_result[best_seed])
141144
end
142145

143-
println("Finished!")
144146
return Fitted{D, T}(n, unknowns, aic, bic, best_llk, coefs, num_hessian)
145147
end
146148

src/opt_methods/common_methods.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@ function optimize(func::Optim.TwiceDifferentiable, opt_method::AbstractOptimizat
4747
show_trace = show_trace(verbose) ))
4848
end
4949

50-
show_trace(verbose::Int) = (verbose == 2 ? true : false)
50+
show_trace(verbose::Int) = (verbose == 3 ? true : false)

src/simulate.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
export simulate, forecast_quantiles
22

3+
mutable struct Forecast{T <: AbstractFloat}
4+
quantiles::Matrix{T}
5+
scenarios::Matrix{T}
6+
end
7+
38
"""
49
simulate(series::Vector{T}, gas::Model{D, T}, H::Int, S::Int, kwargs...) where {D, T}
510
@@ -14,17 +19,14 @@ function simulate(series::Vector{T}, gas::Model{D, T}, H::Int, S::Int;
1419
initial_params::Matrix{T} = stationary_initial_params(gas)) where {D, T}
1520
# Filter params estimated on the time series
1621
params = score_driven_recursion(gas, series; initial_params = initial_params)
17-
1822
biggest_lag = number_of_lags(gas)
19-
2023
params_simulation = params[(end - biggest_lag):(end - 1), :]
2124
# Create scenarios matrix
2225
scenarios = Matrix{T}(undef, H, S)
2326
for scenario in 1:S
2427
sim, param = simulate_recursion(gas, H + biggest_lag + 1; initial_params = params_simulation)
2528
scenarios[:, scenario] = sim[biggest_lag + 2:end]
2629
end
27-
2830
return scenarios
2931
end
3032

@@ -52,8 +54,7 @@ function forecast_quantiles(series::Vector{T}, gas::Model{D, T}, H::Int;
5254
quantiles::Vector{T} = T.([0.025, 0.5, 0.975]), S::Int = 10_000) where {D, T}
5355

5456
scenarios = simulate(series, gas, H, S; initial_params = initial_params)
55-
56-
return get_quantiles(quantiles, scenarios)
57+
return Forecast(get_quantiles(quantiles, scenarios), scenarios)
5758
end
5859

5960
function get_quantiles(quantile_probs::Vector{T}, scenarios::Matrix{T}) where T

src/univariate_score_driven_recursion.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export score_driven_recursion, fitted_mean, simulate_recursion
22

33
"""
4-
score_driven_recursion(sd_model::SDM, observations::Vector{T}) where T
4+
score_driven_recursion(sd_model::SDM, observations::Vector{T}) where T
55
66
start with the stationary params for a
77
"""

test/test_estimate.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
@testset "Estimation by passing number of initial_points" begin
88
# LBFGS
99
gas = Model(1, 1, Beta, 0.0)
10-
fit!(gas, simulation; verbose = 1, opt_method = ScoreDrivenModels.LBFGS(gas, 3))
10+
fit!(gas, simulation; verbose = 2, opt_method = ScoreDrivenModels.LBFGS(gas, 3))
1111
test_coefficients_GAS_1_1(gas, ω, A, B)
1212
# NelderMead
1313
gas = Model(1, 1, Beta, 0.0)
14-
fit!(gas, simulation; verbose = 1, opt_method = ScoreDrivenModels.NelderMead(gas, 3))
14+
fit!(gas, simulation; verbose = 2, opt_method = ScoreDrivenModels.NelderMead(gas, 3))
1515
test_coefficients_GAS_1_1(gas, ω, A, B)
1616
# IPNewton
1717
gas = Model(1, 1, Beta, 0.0)
18-
fit!(gas, simulation; verbose = 1, opt_method = ScoreDrivenModels.IPNewton(gas, 3))
18+
fit!(gas, simulation; verbose = 2, opt_method = ScoreDrivenModels.IPNewton(gas, 3))
1919
test_coefficients_GAS_1_1(gas, ω, A, B)
2020
end
2121
@testset "Estimation by passing initial_points" begin

test/test_simulate.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
@test maximum(scenarios) < 1e5
1616
@test minimum(scenarios) > 0
1717

18-
quants = forecast_quantiles(y, gas, 50)
19-
@test all([quants[i, 1] .< quants[i, 2] .< quants[i, 3] for i in 1:50])
20-
@test maximum(quants) < 1e3
21-
@test minimum(quants) > 1e-4
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
2222
end
2323
end

test/utils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ function test_GARCH_1_1(y, seed::Int, optimizer; atol = 1e-4, rtol = 1e-4)
223223
ub = [1.0; 1.0; 1.0; 1.0]
224224
lb = [-1.0; 0.0; 0.0; 0.0]
225225
gas = Model(1, 1, Normal, 1.0, time_varying_params = [2])
226-
f = fit!(gas, y; initial_params = ini, verbose = 1, opt_method = optimizer(gas, 10; ub = ub, lb = lb))
226+
f = fit!(gas, y; initial_params = ini, verbose = 2, opt_method = optimizer(gas, 10; ub = ub, lb = lb))
227227
show(stdout, fit_stats(f))
228228

229229
@test gas.ω[1] - -0.00616637237701241 0 atol = atol rtol = rtol

0 commit comments

Comments
 (0)