Отрицательная биномиальная смесь в PyMC

#python #statistics #modeling #pymc #markov-chains

#python #Статистика #моделирование #pymc #марковские цепи

Вопрос:

Я пытаюсь совместить отрицательную биномиальную смесь с PyMC. Кажется, я делаю что-то не так, потому что прогноз совсем не похож на входные данные. Проблема, вероятно, в предшествующих отрицательных биномиальных параметрах. Есть предложения?

     from sklearn.cluster import KMeans
    import pymc as mc
    n = 3 #Number of components of the mixture
    ndata = len(data)

    dd = mc.Dirichlet('dd', theta=(1,)*n)
    category = mc.Categorical('category', p=dd, size=ndata)

    kme = KMeans(n) # This is not needed but it is to help convergence
    kme.fit(data[:,newaxis])
    alphas = mc.TruncatedNormal('alphas', kme.cluster_centers_[:,0], 0.1, a=0. ,b=100000 ,size=n)
    means = mc.TruncatedNormal('means', kme.cluster_centers_[:,0],0.1,a=0.0 ,b=100000, size=n)

    @mc.deterministic
    def mean(category=category, means=means):
        return means[category]

    @mc.deterministic
    def alpha(category=category, alphas=alphas):
        return alphas[category]

    obs = mc.NegativeBinomial('obs', mean, alpha, value=data, observed = True)

    predictive = mc.NegativeBinomial('predictive', mean, alpha)

    model = mc.Model({'dd': dd,
                  'category': category,
                  'alphas': alphas,
                  'means': means,
                  'predictive':predictive,
                  'obs': obs})

    mcmc = mc.MCMC( model )
    mcmc.sample( iter=n_samples, burn=int(n_samples*0.7))
  

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

1. Я смоделировал некоторые данные data = list(mc.rnegative_binomial(100., 1000., size=10)) list(mc.rnegative_binomial(200., 1000., size=10)) list(mc.rnegative_binomial(300., 1000., size=10)) . Соответствует ли это вашим намерениям с такой моделью?

Ответ №1:

Вы правильно реализовали байесовскую оценку смеси трех распределений, но модель MCMC дает неправильные значения.

Проблема в том, что category она недостаточно быстро сходится, и параметры в means , alphas , и dd убегают от хороших значений, прежде category чем решить, какие точки принадлежат какому распределению.

 data = np.atleast_2d(list(mc.rnegative_binomial(100., 10., size=s))  
    list(mc.rnegative_binomial(200., 1000., size=s))  
    list(mc.rnegative_binomial(300., 1000., size=s))).T
nsamples = 10000
  

Вы можете видеть, что последующее значение for category неверно, визуализируя его:

 G = [data[np.nonzero(np.round(mcmc.trace("category")[:].mean(axis=0)) == i)]
    for i in range(0,3) ]
plt.hist(G, bins=30, stacked = True)
  

категория после входных данных, без инициализации

Максимизация ожиданий — это классический подход к стабилизации скрытых переменных, но вы также можете использовать результаты быстрой и грязной подгонки k-средних для получения начальных значений для MCMC:

 category = mc.Categorical('category', p=dd, size=ndata, value=kme.labels_)
  

Тогда оценки сходятся к разумным значениям.

категория апостериоров, использующих kmeans для инициализации

Для вашего предыдущего варианта alpha вы можете просто использовать один и тот же дистрибутив для всех из них:

 alphas = mc.Gamma('alphas', alpha=1, beta=.0001 ,size=n)
  

Эта проблема не специфична для отрицательного биномиального распределения; Дирихле-смеси нормальных распределений терпят неудачу таким же образом; это связано с наличием многомерного категориального распределения, которое MCMC неэффективно при оптимизации.

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

1. Большое вам спасибо! Это звучит так, что стоит попробовать! О EM dou вы знаете какую-нибудь хорошую реализацию ip? Мне не удалось ее реализовать: трудности, которые я нахожу, заключаются в том, что NB является дискретным и, используя обязанности для каждого значения, я бы получил float, и тот факт, что для экстимуляции его параметров не существует закрытой формы (я могу использовать оптимизацию для получения MLE, но это делает все менее стабильным)