2016-09-01 9 views
1

Я пытаюсь использовать PyMC3 для решения довольно простого многомерного распределения. Он отлично работает, если у меня есть значение «noise», равное 0.0. Однако, когда я меняю его на что-либо еще, например 0,01, я получаю ошибку в функции find_MAP(), и она зависает, если я не использую find_MAP().Многокомпонентная модель PyMC3 не работает с данными нецелого наблюдения

Есть ли причина, по которой многочлен должен быть разреженным?

import numpy as np 
from pymc3 import * 
import pymc3 as mc 
import pandas as pd 
print 'pymc3 version: ' + mc.__version__ 


sample_size = 10 
number_of_experiments = 1 


true_probs = [0.2, 0.1, 0.3, 0.4] 


k = len(true_probs) 


noise = 0.0 
y = np.random.multinomial(n=number_of_experiments, pvals=true_probs, size=sample_size)+noise 
y_denominator = np.sum(y,axis=1) 
y = y/y_denominator[:,None] 


with Model() as multinom_test: 
    probs = Dirichlet('probs', a = np.ones(k), shape = k) 
    for i in range(sample_size): 
     data = Multinomial('data_%d' % (i), 
          n = y[i].sum(), 
          p = probs, 
          observed = y[i]) 


with multinom_test: 
    start = find_MAP() 
    trace = sample(5000, Slice()) 
trace[probs].mean(0) 

Ошибка:

ValueError: Optimization error: max, logp or dlogp at max have non- 
finite values. Some values may be outside of distribution support. 
max: {'probs_stickbreaking_': array([ 0.00000000e+00, -4.47034834e- 
08, 0.00000000e+00])} logp: array(-inf) dlogp: array([ 
0.00000000e+00, 2.98023221e-08, 0.00000000e+00])Check that 1) you 
don't have hierarchical parameters, these will lead to points with 
infinite density. 2) your distribution logp's are properly specified. 
Specific issues: 
+0

Попробуйте записать вероятность, как: '' 'data_pred = pm.Multinomial ('data_pred' , n = number_of_experiments, p = a, seen = y) '' ' вы также можете попробовать использовать Metropolis вместо Slice – aloctavodia

+0

Привет aloctavodia, я даже не добираюсь до образца, поэтому я не думаю, что это проблема с Metropolis vs. Slice. Можете ли вы уточнить свою функцию правдоподобия? У меня есть несколько столбцов, поэтому я использую нотацию массива [i]. Вы предлагаете другой способ сделать эту операцию? – Chris

+0

Извините, когда я сделал свой комментарий, я предполагал, что, передав '' '' p = a''', а затем '' 'y''', вероятность того, что' '' a''' будет правильно транслироваться. На самом деле модели работают, но образцы, кажется, становятся только из предыдущего, то есть они, похоже, не подвержены влиянию вероятности. – aloctavodia

ответ

2

Это работает для меня

sample_size = 10 
number_of_experiments = 100 

true_probs = [0.2, 0.1, 0.3, 0.4] 
k = len(true_probs) 
noise = 0.01 
y = np.random.multinomial(n=number_of_experiments, pvals=true_probs, size=sample_size)+noise 

with pm.Model() as multinom_test: 
    a = pm.Dirichlet('a', a=np.ones(k)) 
    for i in range(sample_size): 
     data_pred = pm.Multinomial('data_pred_%s'% i, n=number_of_experiments, p=a, observed=y[i]) 
    trace = pm.sample(50000, pm.Metropolis()) 
    #trace = pm.sample(1000) # also works with NUTS 

pm.traceplot(trace[500:]); 

traceplot

+0

Это работает. Кажется, что проблема с моим кодом заключалась в установке n = y [i] .sum(). Я понятия не имею, почему это имеет значение, так как это дает то же значение, что и number_of_experiments, но теперь оно работает. Благодаря! – Chris

+1

Обратите внимание, что '' 'y [i] .sum() = number_of_experiments''' только для' '' noise = 0'''. – aloctavodia