Это интересный вопрос!Значение по умолчанию 'advi'
в PyMC3 - это средний вариационный вывод поля, который не очень хорошо справляется с захватом корреляций.Оказывается, что настроенная вами модель имеет интересную структуру корреляции, которую можно увидеть с помощью этого:
import arviz as az
az.plot_pair(trace, figsize=(5, 5))
PyMC3 имеет встроенную- проверка сходимости - выполнение оптимизации на длинные или слишком короткие может привести к забавным результатам:
from pymc3.variational.callbacks import CheckParametersConvergence
with model:
fit = pm.fit(100_000, method='advi', callbacks=[CheckParametersConvergence()])
draws = fit.sample(2_000)
Это останавливается после примерно 60 000 итераций для меня.Теперь мы можем проверить корреляции и увидеть, что, как и ожидалось, ADVI соответствует гауссианам, выровненным по оси:
az.plot_pair(draws, figsize=(5, 5))
Наконец, мы можем сравнитьподходит от NUTS и (среднее поле) ADVI:
az.plot_forest([draws, trace])
Обратите внимание, что ADVI недооценивает дисперсию, но достаточно близко для среднего значения каждого параметра,Кроме того, вы можете установить method='fullrank_advi'
, чтобы фиксировать корреляции, которые вы видите немного лучше.
(примечание: arviz
скоро станет библиотекой черчения для PyMC3)