Skip to content

Commit f9d9fa8

Browse files
Merge pull request #2441 from pymc-devs/stats-add-bfmi
Add estimated Bayesian fraction of missing information
2 parents 9779ba1 + e124ce6 commit f9d9fa8

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

pymc3/stats.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from .backends import tracetab as ttab
1717

1818
__all__ = ['autocorr', 'autocov', 'dic', 'bpic', 'waic', 'loo', 'hpd', 'quantiles',
19-
'mc_error', 'summary', 'df_summary', 'compare']
19+
'mc_error', 'summary', 'df_summary', 'compare', 'bfmi']
2020

2121

2222
def statfunc(f):
@@ -908,3 +908,28 @@ def _groupby_leading_idxs(shape):
908908
"""
909909
idxs = itertools.product(*[range(s) for s in shape])
910910
return itertools.groupby(idxs, lambda x: x[:-1])
911+
912+
913+
def bfmi(trace):
914+
"""
915+
Calculate the estimated Bayesian fraction of missing information (BFMI).
916+
917+
BFMI quantifies how well momentum resampling matches the marginal energy
918+
distribution. For more information on BFMI, see
919+
https://arxiv.org/pdf/1604.00695.pdf. The current advice is that values
920+
smaller than 0.2 indicate poor sampling. However, this threshold is
921+
provisional and may change. See
922+
http://mc-stan.org/users/documentation/case-studies/pystan_workflow.html
923+
for more information.
924+
925+
Parameters
926+
----------
927+
trace : result of an HMC/NUTS run, must contain energy information
928+
929+
Returns
930+
-------
931+
`float` representing the estimated BFMI.
932+
"""
933+
energy = trace['energy']
934+
935+
return np.square(np.diff(energy)).mean() / np.var(energy)

pymc3/tests/test_stats.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from .helpers import SeededTest
77
from ..tests import backend_fixtures as bf
88
from ..backends import ndarray
9-
from ..stats import df_summary, autocorr, hpd, mc_error, quantiles, make_indices
9+
from ..stats import df_summary, autocorr, hpd, mc_error, quantiles, make_indices, bfmi
1010
from ..theanof import floatX_array
1111
import pymc3.stats as pmstats
1212
from numpy.random import random, normal
@@ -359,6 +359,11 @@ def test_groupby_leading_idxs_3d_variable(self):
359359
for key in keys:
360360
assert result[key] == [key + (0,), key + (1,)]
361361

362+
def test_bfmi(self):
363+
trace = {'energy': np.array([1, 2, 3, 4])}
364+
365+
assert_almost_equal(bfmi(trace), 0.8)
366+
362367

363368
class TestDfSummary(bf.ModelBackendSampledTestCase):
364369
backend = ndarray.NDArray

0 commit comments

Comments
 (0)