Estimation
Procedure
The goal of the estimation step is to sample from the posterior distribution of the model parameters. DSGE.jl provides two estimation routines. The default is a Metropolis-Hastings sampler to do this, which requires as a proposal covariance matrix and the Hessian matrix corresponding to the posterior mode. The second routine is a Sequential Monte Carlo sampler, which is called from the SMC.jl package. Both routines implement adaptive proposal densities and parameter blocking.[1]
The function estimate
implements the entire procedure for either routine. Below, we explain the MH algorithm. For documentation of the SMC algorithm, see here.
Main Steps:
Initialization: Read in and transform raw data from
save/input_data/
. See Input Data for more details.Reoptimize parameter vector: The main program will call the
csminwel
optimization routine (located incsminwel.jl
) to find modal parameter estimates.Compute Hessian matrix: Computing the Hessian matrix to scale the proposal distribution in the Metropolis-Hastings algorithm.
Sample from Posterior: Posterior sampling is performed using the Metropolis-Hastings algorithm. A proposal distribution is constructed centered at the posterior mode and with proposal covariance scaled by the inverse of the Hessian matrix. Settings for the number of sampling blocks and the size of those blocks can be altered as described in Editing or Extending a Model.
Remark: For the MH sampler, in addition to saving each mh_thin
-th draw of the parameter vector, the estimation program also saves the resulting posterior value and transition equation matrices implied by each draw of the parameter vector. This is to save time in the forecasting step since that code can avoid recomputing those matrices.
For the SMC sampler, we save a jld2
file containing a Cloud
object which holds any relevant information about the particles approximating the posterior, the normalized weights of the particles, and the unnormalized weights of particles. We also save a draw of parameters to an h5
file.
To run the entire procedure, the user simply calls the estimate
routine:
DSGE.estimate
— Functionestimate(m, data; verbose=:low, proposal_covariance=Matrix())
Estimate the DSGE parameter posterior distribution.
Arguments:
m::AbstractDSGEModel
orm::AbstractVARModel
: model object
Estimation Settings
Please see the section on 'Estimation Settings' on the 'Advanced Usage' page of the online documentation or src/defaults.jl for a full description of all the estimation settings for both the Metropolis-Hastings (MH) and Sequential Monte Carlo (SMC) algorithms. For the latter, also see ?DSGE.smc2
. Most of the optional and keyword arguments described below are not directly related to the behavior of the sampling algorithms (e.g. tuning, number of samples).
Optional Arguments:
data
: well-formed data asMatrix
orDataFrame
. If this is not provided, theload_data
routine will be executed.
Keyword Arguments:
verbose::Symbol
: The desired frequency of function progress messages printed to standard out.:none
: No status updates will be reported.:low
(default): Status updates will be provided in csminwel and at each block in Metropolis-Hastings. For SMC's verbosity settings, see?smc2
.:high
: Status updates provided at each iteration in Metropolis-Hastings.
proposal_covariance::Matrix = []
: Used to test the metropolis_hastings algorithm with a precomputed covariance matrix for the proposal distribution. When the Hessian is singular, eigenvectors corresponding to zero eigenvectors are not well defined, so eigenvalue decomposition can cause problems. Passing a precomputed matrix allows us to ensure that the rest of the routine has not broken.method::Symbol
: The method to use when sampling from the posterior distribution. Can be either:MH
for standard Metropolis Hastings Markov Chain Monte Carlo, or:SMC
for Sequential Monte Carlo. This should be specified by the settingsampling_method
inm
.mle = false
: Set to true if parameters should be estimated by maximum likelihood directly. If this is set to true, this function will return after estimating parameters.sampling = true
: Set to false to disable sampling from the posterior.old_data::Matrix{Float64}
= []: A matrix containing the time series of observables of previous data (withdata
being the new data) for the purposes of a time tempered estimation (that is, using the posterior draws from a previous estimation as the initial set of draws for an estimation with new data). Running a bridge estimation requires bothold_data
andold_cloud
.old_cloud::Union{DSGE.ParticleCloud, DSGE.Cloud, SMC.Cloud} = DSGE.Cloud(m, 0)
: old Cloud object used to describe particles from a previous estimation with old data. Running a bridge estimation requires bothold_data
andold_cloud
. If running a bridge estimation and noold_cloud
is provided, then it will be loaded using the filepaths inm
. If noold_cloud
exists, then the bridge estimation will not run.old_model::Union{AbstractDSGEModel, AbstractVARModel} = m
: model object from which we can build the old log-likelihood function for a time tempered SMC estimation. It should be possible to evaluate the old log-likelihood givenold_data
and the current draw of parameters. This may be nontrivial if, for example, new parameters have been added tom
since the old estimation. In this case,old_model
should include the new parameters but still return the old log-likelihood as the original estimation if given the same old parameters. By default, we assume the log-likelihood function has not changed and therefore coincides with the current one.filestring_addl::Vector{String} = []
: Additional strings to add to the file name of estimation output as a way to distinguish output from each other.continue_intermediate::Bool = false
: set to true if the estimation is starting from an intermediate stage that has been previously saved.intermediate_stage_start::Int = 0
: number of the stage from which the user wants to continue the estimation (seecontinue_intermediate
)save_intermediate::Bool = true
: set to true to save intermediate stages when using SMCintermediate_stage_increment::Int = 10
: number of stages that must pass before saving another intermediate stage.run_csminwel::Bool = true
: by default, csminwel is run after a SMC estimation finishes to recover the true mode of the posterior. Set to false to avoid this step (csminwel can take hours for medium-scale DSGE models).toggle::Bool = true
: when regime-switching, several functions assume regimes are toggled to regime 1. If the likelihood function is not written to toggle to regime 1 when done, then regime-switching estimation will not work properly. Set tofalse
to reduce computation time if the user is certain that the likelihood is written properly.log_prob_old_data::Float64 = 0.0
:Log p( ilde y) which is the log marginal data density of the bridge estimation.
Metropolis-Hastings Sampler
Computing the Posterior
In DSGE.jl, the function posterior
computes the value of the posterior distribution at a given parameter vector. It calls the likelihood
function, which in turn calls the filter
routine. See Estimation routines for more details on these functions.
We implement the Kalman Filter via the filter
function to compute the log-likelihood, and add this to the log prior to obtain the log posterior. See StateSpaceRoutines.jl for a model-independent implementation of the Kalman filter.
Optimizing or Reoptimizing
Generally, the user will want to reoptimize the parameter vector (and consequently, calculate the Hessian at this new mode) every time they conduct posterior sampling; that is, when:
- the input data are updated with a new quarter of observations or revised
- the model sub-specification is changed
- the model is derived from an existing model with different equilibrium conditions or measurement equation.
This behavior can be controlled more finely.
Reoptimize from a Specified Starting Vector
Reoptimize the model starting from the parameter values supplied in a specified file. Ensure that you supply an HDF5 file with a variable named params
that is the correct dimension and data type.
m = Model990()
params = load_parameters_from_file(m, "path/to/parameter/file.h5")
update!(m, params)
estimate(m)
Skip Reoptimization Entirely
You can provide a modal parameter vector and optionally a Hessian matrix calculated at that mode to skip the reoptimization entirely. These values are usually computed by the user previously.
You can skip reoptimization of the parameter vector entirely.
m = Model990()
specify_mode!(m, "path/to/parameter/mode/file.h5")
estimate(m)
The specify_mode!
function will update the parameter vector to the mode and skip reoptimization by setting the reoptimize
model setting. Ensure that you supply an HDF5 file with a variable named params
that is the correct dimension and data type. (See also the utility function load_parameters_from_file
.)
Random Walk Metropolis-Hastings
For relatively simple problems, a random walk MH sampler is sufficient and avoids unnecessary computations like calculating the Hessian. Suppose we want to estimate all the parameters of a DSGE model m
. The following code implements RWMH for m
.
m = Model990()
m <= Setting(:hessian_path, "path/to//matrix/with/right/dimensions/saved/as/mh_hessian.h5")
estimate(m; proposal_covariance = Matrix{Float64}(I,size(m.parameters)))
The saved Hessian needs to have the same dimensions as the number of parameters. The simplest option is save an identity matrix. The proposal covariance also needs to have the same dimensions as the number of parameters. If the user does not want to estimate every parameter (i.e. some parameters are fixed), then the user needs to zero out the rows of the proposal covariance that correspond to fixed parameters.
Calculating the Hessian
By default, estimate
will recompute the Hessian matrix. You can skip calculation of the Hessian matrix entirely if you provide a file with a Hessian that has been pre-computed.
m = Model990()
specify_mode!(m, "path/to/parameter/mode/file.h5")
specify_hessian(m, "path/to/Hessian/matrix/file.h5")
estimate(m)
The specify_hessian
function will cause estimate
to read in the Hessian matrix rather than calculating it directly. Ensure that you supply an HDF5 file with a variable named hessian
that is the correct dimension and data type. Specifying the Hessian matrix but not the parameter mode results in undefined behavior.
See [Hessian Approximation] for more details on the Hessian computation.
Estimation routines
Prior, Likelihood and Posterior calculations
ModelConstructors.prior
— Functionprior(m::AbstractDSGEModel{T})
Calculates log joint prior density of m.parameters.
DSGE.likelihood
— Functionlikelihood(m::AbstractDSGEModel, data::Matrix{T};
sampler::Bool = false, catch_errors::Bool = false) where {T<:AbstractFloat}
Evaluate the DSGE log-likelihood function. Can handle two-part estimation where the observed sample contains both a normal stretch of time (in which interest rates are positive) and a stretch of time in which interest rates reach the zero lower bound. If there is a zero-lower-bound period, then we filter over the 2 periods separately. Otherwise, we filter over the main sample all at once.
Arguments
m
: The model objectdata
: matrix of data for observables
Optional Arguments
sampler
: Whether metropolis_hastings or smc is the caller. Ifsampler=true
, the transition matrices for the zero-lower-bound period are returned in a dictionary.catch_errors
: Ifsampler = true
,GensysErrors
should always be caught.
likelihood(m::AbstractVARModel, data::Matrix{T};
sampler::Bool = false, catch_errors::Bool = false,
verbose::Symbol = :high) where {T<:AbstractFloat}
Evaluate a VAR likelihood function.
Arguments
m
: The model objectdata
: matrix of data for observables
Optional Arguments
sampler
: Whether metropolis_hastings or smc is the caller. Ifsampler=true
, the transition matrices for the zero-lower-bound period are returned in a dictionary.catch_errors
: Ifsampler = true
,GensysErrors
should always be caught.
ModelConstructors.posterior
— Functionposterior(m::Union{AbstractDSGEModel{T},AbstractVARModel{T}}, data::Matrix{T};
sampler::Bool = false, catch_errors::Bool = false,
φ_smc::Float64 = 1) where {T<:AbstractFloat}
Calculates and returns the log of the posterior distribution for m.parameters
:
log posterior = log likelihood + log prior + const
log Pr(Θ|data) = log Pr(data|Θ) + log Pr(Θ) + const
Arguments
m
: the model objectdata
: matrix of data for observables
Optional Arguments
-sampler
: Whether metropolishastings or smc is the caller. If sampler=true
, the log likelihood and the transition matrices for the zero-lower-bound period are also returned. -`catcherrors: Whether to catch errors of type
GensysErroror
ParamBoundsError`
φ_smc
: a tempering factor to change the relative weighting of the prior and the likelihood when calculating the posterior. It is used primarily in SMC.
ModelConstructors.posterior!
— Functionposterior!(m::Union{AbstractDSGEModel{T},AbstractVARModel{T}},
parameters::Vector{T}, data::Matrix{T};
sampler::Bool = false, catch_errors::Bool = false,
ϕ_smc::Float64 = 1., toggle::Bool = true) where {T<:AbstractFloat}
Evaluates the log posterior density at parameters
.
Arguments
m
: The model objectparameters
: New values for the model parametersdata
: Matrix of input data for observables
Optional Arguments
sampler
: Whether metropolis_hastings or smc is the caller. Ifsampler=true
, the log likelihood and the transition matrices for the zero-lower-bound period are also returned.catch_errors
: Whether to catch errors of typeGensysError
orParamBoundsError
Ifsampler = true
, both should always be caught.ϕ_smc
: a tempering factor to change the relative weighting of the prior and the likelihood when calculating the posterior. It is used primarily in SMC.toggle
: if true, we callModelConstructors.toggle_regime!(values)
before updating any values to ensure thevalue
field of the parameters invalues
correspond to regime 1 values.
Optimization
See Optimization
Full Estimation Routine
See estimate
Output Analysis
DSGE.compute_Eλ
— Methodcompute_Eλ(m, h, λvec, θmat = [], weights = [];
current_period = true, parallel = true) where T<:AbstractFloat
Computes and samples from the conditional density p(λt|θ, It, P) for particle in θs
, which represents the posterior distribution.
Inputs
m::PoolModel{T}
:PoolModel
objecth::Int64
: forecast horizonλvec::Vector{T}
: vector of particles of λ samples from (θ,λ) joint distribution- `θmat::Matrix{T}': matrix of posterior parameter samples
weights::Vector{T}
: weights of λ particles, defaults to equal weights
Keyword Argument
current_period::Bool
: compute Eλ for current period tparallel::Bool
: use parallel computing to compute and sample λget_dpp_pred_dens::Bool
: compute predictive densities according to dynamic prediction pools
Outputs
λhat_tplush::Float64
: E[λ{t+h|t} | It^P, P]λhat_t::Float64
: E[λ{t|t} | It^P, P]
```
DSGE.find_density_bands
— Methodfind_density_bands(draws::Matrix, percents::Vector{T}; minimize::Bool=true) where T<:AbstractFloat
Returns a 2
x cols(draws)
matrix bands
such that percent
of the mass of draws[:,i]
is above bands[1,i]
and below bands[2,i]
.
Arguments
draws
: Matrix of parameter draws (from Metropolis-Hastings, for example)percent
: percent of data within bands (e.g. .9 to get 90% of mass within bands)
Optional Arguments
minimize
: iftrue
, choose shortest interval, otherwise just chop off lowest and highest (percent/2)
DSGE.find_density_bands
— Methodfind_density_bands(draws::Matrix, percent::AbstractFloat; minimize::Bool=true)
Returns a 2
x cols(draws)
matrix bands
such that percent
of the mass of draws[:,i]
is above bands[1,i]
and below bands[2,i]
.
Arguments
draws
:ndraws
bynperiods
matrix of parameter draws (from Metropolis-Hastings, for example)percent
: percent of data within bands (e.g. .9 to get 90% of mass within bands)
Optional Arguments
minimize
: iftrue
, choose shortest interval, otherwise just chop off lowest and highest (percent/2)
DSGE.load_posterior_moments
— Methodfunction load_posterior_moments(m; load_bands = true, include_fixed = false)
Load posterior moments (mean, std) of parameters for a particular sample, and optionally also load 5% and 95% lower and upper bands.
Keyword Arguments
cloud::ParticleCloud
: Optionally pass in a cloud that you want to load the sample from. If the cloud is non-empty then the model object will only be used to find fixed indices and parameter tex labelsload_bands::Bool
: Optionally include the 5% and 95% percentiles for the sample of parameters in the returned dfinclude_fixed::Bool
: Optionally include the fixed parameters in the returned dfexcl_list::Vector{Symbol}
: List parameters by their key that you want to exclude from
loading
Outputs
df
: A dataframe containing the aforementioned moments/bands
DSGE.moment_tables
— Methodmoment_tables(m; percent = 0.90, subset_inds = 1:0, subset_string = "",
groupings = Dict{String, Vector{Parameter}}(), use_mode = false,
tables = [:prior_posterior_means, :moments, :prior, :posterior],
caption = true, outdir = "", verbose = :none)
Computes prior and posterior parameter moments. Tabulates prior mean, posterior mean, and bands in various LaTeX tables. These tables will be saved in outdir
if it is nonempty, or else in tablespath(m, "estimate")
.
Inputs
m::AbstractDSGEModel
: model object
Keyword Arguments
percent::AbstractFloat
: the percentage of the mass of draws from Metropolis-Hastings included between the bands displayed in output tables.subset_inds::AbstractRange{Int64}
: indices specifying the draws we want to usesubset_string::String
: short string identifying the subset to be appended to the output filenames. Ifsubset_inds
is nonempty butsubset_string
is empty, an error is throwngroupings::Dict{String, Vector{Parameter}}
: see?parameter_groupings
use_mode::Bool
: use the modal parameters instead of the mean in the priorposteriormeans tabletables::Vector{Symbol}
: which tables to producecaption::Bool
: whether to include table captionsoutdir::String
: where to save output tablesverbose::Symbol
: desired frequency of function progress messages printed to standard out. One of:none
,:low
, or:high
DSGE.sample_λ
— Methodsample_λ(m, pred_dens, θs, T = -1; parallel = true) where S<:AbstractFloat
sample_λ(m, pred_dens, T = -1; parallel = true) where S<:AbstractFloat
Computes and samples from the conditional density p(λt|θ, It, P) for particle in θs
, which represents the posterior distribution. The sampled λ particles represent the posterior distribution p(λ{t|t} | It, P).
If no posterior distribution is passed in, then the function computes the distribution of λ_{t|t} for a static pool.
Inputs
m::PoolModel{S}
:PoolModel
objectpred_dens::Matrix{S}
: matrix of predictive densitiesθs::Matrix{S}
: matrix of particles representing posterior distribution of θT::Int64
: final period for tempered particle filter
where S<:AbstractFloat
.
Keyword Argument
parallel::Bool
: use parallel computing to compute and sample draws of λ
Outputs
λ_sample::Vector{Float64}
: sample of draws of λs; together with (θ,λ) represents a joint density
```
DSGE.moments
— Methodmoments(θ::Parameter)
If θ's prior is a RootInverseGamma
, τ and ν. Otherwise, returns the mean and standard deviation of the prior. If θ is fixed, returns (θ.value, 0.0)
.
DSGE.posterior_table
— Methodposterior_table(m, post_means, post_bands; percent = 0.9, subset_string = "",
groupings = Dict{String, Vector{Parameter}}(), caption = true, outdir = "")
DSGE.prior_posterior_moments_table
— Methodprior_posterior_moments_table(m, post_means, post_bands; percent = 0.9,
subset_string = "", groupings = Dict{String, Vector{Parameter}}(),
caption = true, outdir = "")
Produces a table of prior means, prior standard deviations, posterior means, and 90% bands for posterior draws.
DSGE.prior_posterior_table
— Methodprior_posterior_table(m, post_values; subset_string = "",
groupings = Dict{String, Vector{Parameter}}(), use_mode = false,
caption = true, outdir = "")
Produce a table of prior means and posterior means or mode.
DSGE.prior_table
— Methodprior_table(m; subset_string = "", groupings = Dict{String, Vector{Parameter}}(),
caption = true, outdir = "")
DSGE.propagate_λ
— Methodpropgate_λ(λvec, h, m, θvec) where T<:AbstractFloat
Propagates a λ particle h periods forward.
Inputs
λ::T
: λ sample from (θ,λ) joint distributionh::Int64
: forecast horizonm::PoolModel
: PoolModel objectθvec::Vector{T}
: optional vector of parameters to update PoolModel
```
SMC Sampler
See here for the settings adjusting the SMC algorithm. To use these with a DSGE model object, either add them after the definition of a model object as a Setting
or add them directly in the definition of the model type. For example, the following code sets the sampler as SMC and the number of particles used by SMC as 10,000:
m = Model990()
m <= Setting(:sampling_method, :SMC)
m <= Setting(:n_particles, 10000)