IRIS-Solutions-Team / IRIS-Toolbox

[IrisToolbox] for Macroeconomic Modeling
Other
92 stars 41 forks source link

Exogenous variables in structural models #165

Open michaelkirker opened 5 years ago

michaelkirker commented 5 years ago

I have a general question (rather than a bug report) on the "best practice" for modelling exogenous variables within and IRIS model file for a (semi-)structural model.

I am look at replicating the model of r-star by Holston, Laubach, and Williams (https://www.frbsf.org/economic-research/files/wp2016-11.pdf). They solve the model by treating the path of (real) interest rates as exogenous in the state space form of the model (there is no policy rule closing the model). In the notation of Hamilton's 1994 textbook (http://web.pdx.edu/~crkl/readings/Hamilton94.pdf), the state space of the model is y = A'x + H'xi + w (y= measurement variables, x=observed variables that are exogenous or predetermined, xi=states), where x = [r{t-1} r{t-2} y{t-1} y{t-2} pi{t-1} pi{t-2,4}] is the only place in the model that interest rates, r, enter.

What is the best way to include an exogenous series within the IRIS model file? My current approach is to model the series as a random walk inside the transition equations, and then have a simple observable equation like r_=r. But is there a better approach I should be adopting?

jaromir-benes commented 5 years ago

Hi Michael

Your approach is perfectly alright. The only problem may potentially arise when estimating the parameters of the system. Because r is now an observable, its prediction errors (which will depend on the particular process you assume for r in the transition equations) will enter the likelihood function and may thus affect the estimates. I recommend that you run a few experiments to see how serious the problem is. My hunch is that setting a fixed relatively large(r) std dev for the shock in the r equation may minimize the problem.

If you still need to get around the problem, you may resort to an alternative (yet less elegant) approach. Keep in mind though that this approach only works in backward-looking models. Remove r_ from the measurement variables/equations, and set up the following transition equation for the real rate: r = ss_r + eps_r where eps_r is a shock and ss_r is a constant parameter that is only introduced if you care about the steady state of the model; otherwise it can be zero. Make sure you set the std deviation for eps_r to 0. Then, when running the Kalman filter, supply the path for eps_r (and hence also for r) through the option 'Vary=' (this option can be used to supply time-varying paths for std deviations and/or means of shocks to allow them to temporarily deviate from their default values assigned in the model object).

exog = struct( ); exog.eps_r = some time series defined on the entire filter range

m.std_eps_r = 0;

[ ... ] = filter(m, d, range, 'Vary=', exog);

Setting std_eps_r=0 is important here so that this shocks is not treated stochastically and is not used to explain the variability in the other observables.

Hope this helps. Let me know if you need any clarification...

Best Jaromir

On Wed, Dec 5, 2018 at 9:39 PM Michael Kirker notifications@github.com wrote:

I have a general question (rather than a bug report) on the "best practice" for modelling exogenous variables within and IRIS model file for a (semi-)structural model.

I am look at replicating the model of r-star by Holston, Laubach, and Williams (https://www.frbsf.org/economic-research/files/wp2016-11.pdf). They solve the model by treating the path of (real) interest rates as exogenous in the state space form of the model (there is no policy rule closing the model). In the notation of Hamilton's 1994 textbook ( http://web.pdx.edu/~crkl/readings/Hamilton94.pdf), the state space of the model is y = A'x + H'xi + w (y= measurement variables, x=observed variables that are exogenous or predetermined, xi=states), where x = [r{t-1} r{t-2} y{t-1} y{t-2} pi{t-1} pi{t-2,4}] is the only place in the model that interest rates, r, enter.

What is the best way to include an exogenous series within the IRIS model file? My current approach is to model the series as a random walk inside the transition equations, and then have a simple observable equation like r_=r. But is there a better approach I should be adopting?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/IRIS-Solutions-Team/IRIS-Toolbox/issues/165, or mute the thread https://github.com/notifications/unsubscribe-auth/AYVVKrf2zILoC13HiZmqy8OtE3CtAaW0ks5u2ATTgaJpZM4ZDZOr .

michaelkirker commented 5 years ago

Hi Jaromir

Thanks for the advice. I see Bayesian estimation is now built into the toolbox (very nice). I am going to use this project as a way to learn the new built-in Bayesian estimation (following along in notes in the "Tutorial-Simple-SPBC-Model").

In this case, I take it the alternative/less elegant approach your mentioned is the best way to go here. If I pass the 'Vary=', exog as an optional argument into the Bayesian estimation code, will the code handle it in such a way it gets correctly to the filter function? Or will there be a bit of work to be able to estimate the model using Bayesian techniques, while tuning the exogenous path for the shocks to the interest rate series?

jaromir-benes commented 5 years ago

Hi Michael

You simply pass the Vary= option as a Filter= suboption to the estimate command, e.g.

[...] = estimate(m, d, range, estimStruct, 'Filter=', {'Vary=', xxx}, ...)

This is a way to pass in any options for the underlying kalman filter which is executed as part of the likelihood evaluation.

Let me know if you encounter any problems.

Best Jaromir

On Tue, Dec 11, 2018 at 7:03 PM Michael Kirker notifications@github.com wrote:

Hi Jaromir

Thanks for the advice. I see Bayesian estimation is now built into the toolbox (very nice). I am going to use this project as a way to learn the new built-in Bayesian estimation (following along in notes in the "Tutorial-Simple-SPBC-Model").

In this case, I take it the alternative/less elegant approach your mentioned is the best way to go here. If I pass the "'Vary=', exog" as an optional argument into the Bayesian estimation code, will the code handle it in such a way it gets correctly to the filter function? Or will there be a bit of work to be able to estimate the model using Bayesian techniques, while tuning the exogenous path for the shocks to the interest rate series?

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/IRIS-Solutions-Team/IRIS-Toolbox/issues/165#issuecomment-446301016, or mute the thread https://github.com/notifications/unsubscribe-auth/AYVVKmggHTbceVbQoYRuHaKQ4B5QSr6kks5u3_OHgaJpZM4ZDZOr .

michaelkirker commented 5 years ago

Hi Jaromir

I have run into one issue while estimating this model. But it is a more general issue. When the parameter set implies the model is not stable, the estimation function crashes.

I have paired back the model to a MWE that is a single AR(2) process: i.e. a transition equation y_gap = a_y1 * y_gap{-1} + a_y2 * y_gap{-2} + e_y; and a measurement equation y_gap_ = y_gap

By the properties of the AR(2) process, the output gap is stable if abs(a_y1)<1 AND a_y1 +/- a_y2 < 1.

If I fix a_y2 = 0.25, and estimate a_y1 using the prior p.a_y1 = {0.25, -0.74, 0.74, distribution.Normal.fromMeanStd(0.25, 0.5)}; the estimation code runes fine.

If I increase the upper bound to a value that violates stability, e.g. p.a_y1 = {0.25, -0.74, 0.76, distribution.Normal.fromMeanStd(0.25, 0.5)}; the code crashes with the error message

Error using model/estimate (line 324) IRIS Toolbox Error @ Model:Failed. *** The model failed to update parameters and solution

Type x = model.failed( ) to retrieve the model object that failed to solve

IRIS Toolbox Error @ Model:Failed. *** Solution not available for some parameter variant(s) No stable solution [Parameter Variant(s) #1] [Bkw variables, Unit roots, Stable roots]: Parameter Variant(s) #1[2 0 1]

Error in batch (line 272) estimate(m, dd, startHist:endHist, estimSpecs, ...

Tracing back through the debugger, when it crashes the code is trying to assign a_y1=0.76 and solve the model.

Picking the bounds so the code is stable is easy when estimating just the single parameter, but will be much harder when trying to estimate a_y1 and a_y2 jointly as the range of values of one parameter that will ensure stability of the system will be a function of the value of the other parameter.

I could possibly re-write a_y2 as a function of a_y1 to ensure stability. But I was hoping that I could ignore the issue, and rely on the estimation code returning a NaN or -Inf for the value of the likelihood at points in the parameter space where no solution to the model exists.

Any thoughts on the best way to proceed when estimating both parameters within the model?

jaromir-benes commented 5 years ago

Hi Michael

There is an option in the estimate( ) command to control what happens if the model fails to solve in an iteration. By default, 'NoSolution=', 'Error', hence causing the estimation procedure to stop and throw an error. You can set 'NoSolution=', 'Penalty' in which case the log-likelihood value will be increased by a very large number (1e10 by default) to discourage to solver from going into that region. You can also set 'NoSolution=', someNumber where someNumber is your own value of the penalty should the default 1e10 be insufficient.

Also notice the little advice in the error message above prompting yo to do

x = model.failed( ) immediately after the unsuccessful run of the estimate command to retrieve the model object with the parameters that failed to solve (so you don't have to set up a debugger to do this).

Hope this helps. Jaromir

On Wed, Dec 12, 2018 at 11:37 AM Michael Kirker notifications@github.com wrote:

Hi Jaromir

I have run into one issue while estimating this model. But it is a more general issue. When the parameter set implies the model is not stable, the estimation function crashes.

I have paired back the model to a MWE that is a single AR(2) process: i.e. a transition equation y_gap = a_y1 y_gap{-1} + a_y2 y_gap{-2} + e_y; and a measurement equation ygap = y_gap

By the properties of the AR(2) process, the output gap is stable if abs(a_y1)<1 AND a_y1 +/- a_y2 < 1.

If I fix a_y2 = 0.25, and estimate a_y1 using the prior p.a_y1 = {0.25, -0.74, 0.74, distribution.Normal.fromMeanStd(0.25, 0.5)}; the estimation code runes fine.

If I increase the upper bound to a value that violates stability, e.g. p.a_y1 = {0.25, -0.74, 0.76, distribution.Normal.fromMeanStd(0.25, 0.5)}; the code crashes with the error message

Error using model/estimate (line 324) IRIS Toolbox Error @ Model:Failed. *** The model failed to update parameters and solution

Type x = model.failed( ) to retrieve the model object that failed to solve

IRIS Toolbox Error @ Model:Failed. *** Solution not available for some parameter variant(s) No stable solution [Parameter Variant(s) #1 https://github.com/IRIS-Solutions-Team/IRIS-Toolbox/issues/1] [Bkw variables, Unit roots, Stable roots]: Parameter Variant(s) #1 https://github.com/IRIS-Solutions-Team/IRIS-Toolbox/issues/1[2 0 1]

Error in batch (line 272) estimate(m, dd, startHist:endHist, estimSpecs, ...

Tracing back through the debugger, when it crashes the code is trying to assign a_y1=0.76 and solve the model.

Picking the bounds so the code is stable is easy when estimating just the single parameter, but will be much harder when trying to estimate a_y1 and a_y2 jointly as the range of values of one parameter that will ensure stability of the system will be a function of the value of the other parameter.

I could possibly re-write a_y2 as a function of a_y1 to ensure stability. But I was hoping that I could ignore the issue, and rely on the estimation code returning a NaN or -Inf for the value of the likelihood at points in the parameter space where no solution to the model exists.

Any thoughts on the best way to proceed when estimating both parameters within the model?

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/IRIS-Solutions-Team/IRIS-Toolbox/issues/165#issuecomment-446541316, or mute the thread https://github.com/notifications/unsubscribe-auth/AYVVKitM-qoIT6SAQCPY-YnRISKFQbHNks5u4Nx3gaJpZM4ZDZOr .