2014-12-02 6 views
1

У меня возникли проблемы с выбором из Дирихле/Многочленного распределения с pymc3. Я попытался создать простой тестовый сценарий, чтобы воссоздать бета/бином, используя Dirichlet/Multinomial с n = 2, но я не могу заставить его работать.Dirichlet vs Binomial in pymc3

Ниже у меня есть код, который работает для Binomial, но не подходит для многочленов. Одним из очевидных отличий является то, что многолинейная модель более ограничена: Чтобы начать, рейтинг устанавливается в 10 в биномиальной модели и [10,10] в многочлене. Код pirc3 Dirichlet говорит: «Только первые k-1 элементов x ожидаются», но в моем коде работают только массивы формы 2.

Результаты показывают, что num_friends и rating отбираются в биномиальном корпусе, но не в многотомном случае. friends_ratings отбирается в обоих. Благодаря!

О, также Dirichlet('d', np.array([1,1])) сбой с «ошибкой с плавающей точкой 8». Похоже, что он проваливается, когда передаются два целых числа значения 1. np.array([1.,1.]) работает.

import pymc as pm 
import numpy as np 

print "TEST BINOMIAL" 
with pm.Model() as model: 
    friends_ratings = pm.Beta('friends_ratings', alpha=1, beta=2) 
    num_friends = pm.DiscreteUniform('num_friends', lower=0, upper=100) 
    rating = pm.Binomial('rating', n=num_friends, p=friends_ratings) 

    step = pm.Metropolis([num_friends, friends_ratings, rating]) 
    start = {"friends_ratings":.5, "num_friends":20, 'rating':10} 

    tr = pm.sample(5, step, start=start, progressbar=False)  
    print "friends", [tr[i]['num_friends'] for i in range(len(tr))] 
    print "friends_ratings", [tr[i]['friends_ratings'] for i in range(len(tr))] 
    print "rating", [tr[i]['rating'] for i in range(len(tr))] 

print "TEST DIRICHLET" 
with pm.Model() as model: 
    friends_ratings = pm.Dirichlet('friends_ratings', np.array([1.,1.]), shape=2) 
    num_friends = pm.DiscreteUniform('num_friends', lower=0, upper=100)  
    rating = pm.Multinomial('rating', n=num_friends, p=friends_ratings, shape=2) 

    step = pm.Metropolis([num_friends, friends_ratings, rating]) 
    start = {'friends_ratings': np.array([0.5,0.5]), 'num_friends': 20, 'rating': [10,10]} 

    tr = pm.sample(5, step, start=start, progressbar=False)  
    print "friends", [tr[i]['num_friends'] for i in range(len(tr))] 
    print "friends_ratings", [tr[i]['friends_ratings'] for i in range(len(tr))] 
    print "rating", [tr[i]['rating'] for i in range(len(tr))] 

Выход:

TEST BINOMIAL 
friends [22.0, 24.0, 24.0, 23.0, 23.0] 
friends_ratings [0.5, 0.5, 0.41, 0.41, 0.41] 
ratingf [10.0, 11.0, 11.0, 11.0, 11.0] 
TEST DIRICHLET 
friends [20.0, 20.0, 20.0, 20.0, 20.0] 
friends_ratings [array([ 0.51369621, 1.490608 ]), ... ] 
rating [array([ 10., 10.]), array([ 10., 10.]), ... ] 

ответ

4

PyMC3 автоматически не нормализует Дирихль. Пока вы должны сделать это явно, используя simplextransform. См. Пример here.

Существует проблема создания этого преобразования автоматической, хотя: https://github.com/pymc-devs/pymc3/issues/315

EDIT (9/14/2015): PyMC3 теперь автоматически преобразует дирихль распределения (как и любой другой дистрибутив). Поэтому вам больше не нужно указывать это вручную.

+0

Ссылки не работают :( –

+0

Я обновил ссылки. – twiecki

+0

Большое спасибо;) –