Функция PyMC3 sample() не принимает значение «start» для генерации трассировки

#bayesian #pymc3

#байесовская #pymc3

Вопрос:

Я новичок в PyMC3 и байесовских методах вывода. У меня есть простой код, который пытается вывести значение некоторой константы затухания (= 1) из искусственных данных, сгенерированных с использованием усеченного экспоненциального распределения:

 import numpy as np
from scipy import stats
import matplotlib.pyplot as plt 
import pymc3 as pm
import arviz as az


T = stats.truncexpon(b = 10.)
t = T.rvs(1000)

#Bayesian Inference

with pm.Model() as model: 
    #Define Priors
    lam = pm.Gamma('$lambda$', alpha=1, beta=1)

    #Define Likelihood
    time = pm.Exponential('time', lam = lam, observed = t)

    #Inference
    trace = pm.sample(20, start = {'lam': 10.}, 
            step=pm.Metropolis(), chains=1, cores=1, 
            progressbar = True)


az.plot_trace(trace)
plt.show()
  

Этот код создает трассировку, подобную приведенной ниже

введите описание изображения здесь

Я действительно не понимаю, почему начальное значение равно 10. не принимается программой выборки. Приведенная выше трассировка должна начинаться с 10. Я использую python 3.7 для запуска кода.

Спасибо.

Комментарии:

1. Можете ли вы подробнее рассказать, как выглядят ваши входные данные? На данный момент t это выборки из усеченной экспоненты, и нет никаких значений для прогнозирования t . Это все, что у вас есть, или у вас есть x,y пары, которые можно было бы смоделировать с помощью x=np.arange(0,10,0.1) и затем y=np.exp(-x)/(1-np.exp(-lambda) . В последнем случае y будет вашей (смоделированной) наблюдаемой величиной.

2. @balleveryday, я пытаюсь предсказать значение константы затухания (= 1) или масштабный коэффициент усеченного экспоненциального распределения. Массив t содержит искусственные данные. Я применяю правило Байеса к этим данным.

Ответ №1:

Происходит несколько вещей:

  • при первом запуске сэмплера выполняется фаза настройки; выборки во время этой фазы по умолчанию отбрасываются, но этим можно управлять с помощью discard_tuned_samples аргумента
  • ключи в start словаре аргументов должны соответствовать имени, присвоенному случайной переменной ( '$lambda$' ), а не переменной Python

Включив эти два, можно попробовать

 trace = pm.sample(20, start = {'$lambda$': 10.},
            step=pm.Metropolis(), chains=1, cores=1,
            discard_tuned_samples=False)
  

Однако другая возможная проблема заключается в том, что

  • не гарантируется, что начальное значение будет передано при первом розыгрыше; только если первый образец предложения отклонен, что зависит от случая.

Исправляя игру (задавая случайное начальное значение), мы можем получить представление:

 trace = pm.sample(20, start = {'$lambda$': 10.},
            step=pm.Metropolis(), chains=1, cores=1,
            discard_tuned_samples=False, random_seed=1)

...

trace.get_values(varname='$lambda$')[:10]

# array([10.        ,  5.42397358,  3.19841997,  1.09383329,  1.09383329,
#         1.09383329,  1.09383329,  1.09383329,  1.09383329,  1.09383329])
  

Комментарии:

1. Большое вам спасибо. Это очень полезно и почти решило мою проблему. Я просто хочу уточнить, что вы подразумеваете под «начальным значением, которое не гарантируется при первом розыгрыше». Вы имеете в виду, что само начальное значение принимается или отклоняется в зависимости от того, является ли min (1, коэффициент Гастингса) > u истинным или ложным, где u выбирается из равномерного распределения (0,1)?

2. @singularity хороший вопрос. Да, я думаю, это то, что происходит. Начальное значение определяет местоположение в пространстве состояний, из которого генерируется первое предложение. Если это предложение будет отклонено (в соответствии с тем, что вы упомянули для Metropolis-Hastings), то начальное значение будет передано в качестве первого розыгрыша. На более высоком уровне для PyMC3 должно иметь смысл не включать начальное состояние в качестве «draw» по умолчанию, потому что по определению оно включает только предварительную информацию, тогда как точка MCMC предназначена для того, чтобы розыгрыши выполнялись в соответствии с последующими.

3. Если вы пытаетесь «перезапустить» процесс metropolis с trace аргументом, и это не работает, рассмотрите возможность установки не trace , а вместо этого параметра start = <your_old_trace>.point(-1) . Это сработало для меня в pymc3 3.11.4.