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 in csminwel.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.estimateFunction
estimate(m, data; verbose=:low, proposal_covariance=Matrix())

Estimate the DSGE parameter posterior distribution.

Arguments:

  • m::AbstractDSGEModel or m::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 as Matrix or DataFrame. If this is not provided, the load_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 setting sampling_method in m.
  • 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 (with data 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 both old_data and old_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 both old_data and old_cloud. If running a bridge estimation and no old_cloud is provided, then it will be loaded using the filepaths in m. If no old_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 given old_data and the current draw of parameters. This may be nontrivial if, for example, new parameters have been added to m 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 (see continue_intermediate)
  • save_intermediate::Bool = true: set to true to save intermediate stages when using SMC
  • intermediate_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 to false 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.
source

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

DSGE.likelihoodFunction
likelihood(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 object
  • data: matrix of data for observables

Optional Arguments

  • sampler: Whether metropolis_hastings or smc is the caller. If sampler=true, the transition matrices for the zero-lower-bound period are returned in a dictionary.
  • catch_errors: If sampler = true, GensysErrors should always be caught.
source
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 object
  • data: matrix of data for observables

Optional Arguments

  • sampler: Whether metropolis_hastings or smc is the caller. If sampler=true, the transition matrices for the zero-lower-bound period are returned in a dictionary.
  • catch_errors: If sampler = true, GensysErrors should always be caught.
source
ModelConstructors.posteriorFunction
posterior(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 object
  • data: 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 typeGensysErrororParamBoundsError`

  • φ_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.
source
ModelConstructors.posterior!Function
posterior!(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 object
  • parameters: New values for the model parameters
  • data: Matrix of input data for observables

Optional Arguments

  • sampler: Whether metropolis_hastings or smc is the caller. If sampler=true, the log likelihood and the transition matrices for the zero-lower-bound period are also returned.
  • catch_errors: Whether to catch errors of type GensysError or ParamBoundsError If sampler = 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 call ModelConstructors.toggle_regime!(values) before updating any values to ensure the value field of the parameters in values correspond to regime 1 values.
source

Optimization

See Optimization

Full Estimation Routine

See estimate

Output Analysis

DSGE.compute_EλMethod
compute_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 object
  • h::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 t
  • parallel::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]

```

source
DSGE.find_density_bandsMethod
find_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: if true, choose shortest interval, otherwise just chop off lowest and highest (percent/2)
source
DSGE.find_density_bandsMethod
find_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 by nperiods 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: if true, choose shortest interval, otherwise just chop off lowest and highest (percent/2)
source
DSGE.load_posterior_momentsMethod
function 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 labels
  • load_bands::Bool: Optionally include the 5% and 95% percentiles for the sample of parameters in the returned df
  • include_fixed::Bool: Optionally include the fixed parameters in the returned df
  • excl_list::Vector{Symbol}: List parameters by their key that you want to exclude from

loading

Outputs

  • df: A dataframe containing the aforementioned moments/bands
source
DSGE.moment_tablesMethod
moment_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 use
  • subset_string::String: short string identifying the subset to be appended to the output filenames. If subset_inds is nonempty but subset_string is empty, an error is thrown
  • groupings::Dict{String, Vector{Parameter}}: see ?parameter_groupings
  • use_mode::Bool: use the modal parameters instead of the mean in the priorposteriormeans table
  • tables::Vector{Symbol}: which tables to produce
  • caption::Bool: whether to include table captions
  • outdir::String: where to save output tables
  • verbose::Symbol: desired frequency of function progress messages printed to standard out. One of :none, :low, or :high
source
DSGE.sample_λMethod
sample_λ(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 object
  • pred_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

```

source
DSGE.momentsMethod
moments(θ::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).

source
DSGE.posterior_tableMethod
posterior_table(m, post_means, post_bands; percent = 0.9, subset_string = "",
    groupings = Dict{String, Vector{Parameter}}(), caption = true, outdir = "")
source
DSGE.prior_posterior_moments_tableMethod
prior_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.

source
DSGE.prior_posterior_tableMethod
prior_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.

source
DSGE.prior_tableMethod
prior_table(m; subset_string = "", groupings = Dict{String, Vector{Parameter}}(),
    caption = true, outdir = "")
source
DSGE.propagate_λMethod
propgate_λ(λvec, h, m, θvec) where T<:AbstractFloat

Propagates a λ particle h periods forward.

Inputs

  • λ::T: λ sample from (θ,λ) joint distribution
  • h::Int64: forecast horizon
  • m::PoolModel: PoolModel object
  • θvec::Vector{T}: optional vector of parameters to update PoolModel

```

source

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)
  • 1We document the details of implementing adaptive proposal densities and parameter blocking in SMC.jl.