pymc-devs / pymc2

THIS IS THE **OLD** PYMC PROJECT (VERSION 2). PLEASE USE PYMC INSTEAD:
http://pymc-devs.github.com/pymc/
Other
879 stars 229 forks source link

Delayed Rejection Metropolis sampler #155

Closed jasonmhite closed 6 years ago

jasonmhite commented 7 years ago

I'm working on implementing the DRAM sampler due to Haario et al. (see also this page).

The AM is for Adaptive Metropolis, which is obviously already there. To implement the full DRAM algorithm I just need to add a delayed rejection phase. I wanted to ask for opinions on how I should do this in a way that is most likely to be accepted in a PR. To me it seems most natural to implement this as part of the existing AdaptiveMetropolis algorithm, since the two algorithms are almost always used together and share the same provenance via Heikki Haario. This however will require a bit of refactoring of the current AdaptiveMetropolis class because the current implementation is only really designed to propose a single candidate. Alternatively I could implement it as a subclass of AdaptiveMetropolis, but I will end up duplicating a ton of code because I have to reimplement the step method even though it'll still be doing everything that AdaptiveMetropolis.step is doing.

I already have a prototype implemented that I can work into either approach (currently it's modifying AdaptiveMetropolis). In most of the problems I've looked at the delayed rejection portion of the algorithm is much more important than the adaptive covariance when it comes to improving the acceptance ratio. In the toy problem I have been testing with I got a factor of two improvement using DR+AM versus just using AM, so it's a clear improvement.

Also, in principle delayed rejection can proceed for as many rounds as you want (see the original paper). However in practice most people only use a single round and that's what I implemented. Laine's MATLAB implementation that I linked (the de facto standard implementation) only uses a single round.

PS: I personally need this implemented in PyMC 2, but I'm open to working on an implementation in PyMC 3 later if desired. I'll implement/update unit tests too of course. I should also be able to provide some validation studies too.

fonnesbeck commented 7 years ago

Hi Jason,

We happily accept pull requests for new PyMC 2.3 functionality despite not having a roadmap for further development of the package. If you happen to refactor AdaptiveMetropolis in a way that makes it more general or extendable, all the better. It sounds like what you propose is a logical subclass of AdatpiveMetropolis, but don't feel constrained by this if that presents hurdles that make subclassing difficult or artificial.

This would probably be useful in PyMC3 as well. Although PyMC3 focuses on gradient-based methods, we still have to fall back on Metropolis-type algorithms for models that include discrete latent variables that cannot be integrated out.

jasonmhite commented 7 years ago

I was leaning towards refactoring AdaptiveMetropolis, as you say DRAM makes sense as a subclass but the problem is that most of the changes are in the step method. DRAM needs to basically do everything that Adaptive Metropolis is already doing in step, but then do a few more things. So if I subclass AdaptiveMetropolis I have to duplicate all that code in step in my class.

I will get to work on tidying it up. I should have something within a couple weeks.

fonnesbeck commented 6 years ago

If this is something you are still working on, please submit a PR when it is ready.