Как я могу включить категориальные распределения в качестве наблюдаемых данных в PyMC3?

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

Необработанные наблюдаемые данные у:

[[  1.93542253e-01   1.39657327e-04   7.53918636e-01   5.23994535e-02]
 [  6.44964587e-02   8.50087384e-01   1.09894665e-02   7.44266910e-02]
 [  1.68387463e-02   5.38121456e-01   6.98554551e-02   3.75184342e-01]
 ..., 
 [  5.79786789e-01   1.47417427e-02   3.15395731e-01   9.00757372e-02]
 [  8.66796124e-02   8.66999904e-02   4.47848127e-02   7.81835584e-01]
 [  8.18765043e-01   3.23448859e-03   5.61247840e-04   1.77439220e-01]]

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

Выборка из исходных данных y_choice:

[ 2.  3.  3.  1.  2.  2.  2.  2.  3.  3.  1.  2.  3.  0.  2.  0.  3.  1.
  3.  0.  2.  0.  3.  0.  2.  0.  1.  0.  3.  0.  2.  0.  0.  0.  3.  0.
  2.  0.  0.  3.  3.  1. ...

Однако, похоже, что я теряю информацию, потому что мой выборочный сэмплер находится за пределами модели PyMC. Как я могу предоставить фактические данные наблюдений y непосредственно в модель? Я предполагаю, что это как-то связано с другим параметром модели, основанным на Дирихле, но я не смог обернуть голову, как это работает.

Пример кода, с которым я работаю, приведен ниже. Я хочу быть в состоянии предоставить y модели и вернуть true_probs, но пока мне удалось заставить его работать только с y_choice.

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


def generate_noisy_observations():
    y = np.ones((sample_size,k))
    for i in range(sample_size):
        #print("Iteration %d" % i)
        true_category = np.random.choice(k, size=1, p=true_probs)
        true_distribution = np.zeros(k)
        true_distribution[true_category] = 1
        noise_distribution = np.random.dirichlet(np.ones(k))

        noise = np.random.normal(0,1,k)

        distribution_weights = [0.9, 0.1]
        raw_distribution = (true_distribution*distribution_weights[0] + noise**2*distribution_weights[1] )/\       (np.sum(true_distribution*distribution_weights[0])+np.sum(noise**2*distribution_weights[1]))
        y[i] = raw_distribution
return y

def generate_choices_from_noisy_observations(y):
    y_choice = np.ones(sample_size)
    for i in range(sample_size):
        y_choice[i] = np.random.choice(k, size=1, p=y[i])
    return y_choice

sample_size = 1000

true_probs = [0.2, 0.1, 0.3, 0.4]
k = len(true_probs)


y = generate_noisy_observations()

y_choice = generate_choices_from_noisy_observations(y)

with pm.Model() as multinom_test:
    probs = pm.Dirichlet('a', a=np.ones(k))
    #data = Categorical('data',p = probs, observed = y)
    data = Categorical('data',p = probs, observed = y_choice)
    start = pm.find_MAP()
    trace = pm.sample(50000, pm.Metropolis())

pm.traceplot(trace[500:])

0 ответов

Другие вопросы по тегам