Длина тензора Теано неизвестна для деления, но подходит для добавления в иерархической модели pymc3

#python #theano #pymc3 #hierarchical-bayesian

#python #теано #pymc3 #иерархический-байесовский

Вопрос:

Я пытаюсь запустить иерархическую модель с помощью pymc3 в среде Win10 с использованием Spyder. У меня есть некоторые глобальные параметры модели (тета, омега, сигма) и один конкретный параметр (Ci).

В качестве входных данных используется фрейм данных pd, содержащий соответствующие данные. Первый столбец называется «Когорта», второй столбец называется «Период», третий столбец содержит наблюдения.

Количество наблюдений различается между когортами.

Код выглядит следующим образом:

 import pymc3 as pm
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import theano.tensor as tt 

cohorts_idx, cohorts = pd.factorize(inputs['Cohort'], sort = True)
periods_idx, periods = pd.factorize(inputs['Period'], sort = True)

coords = {
    "cohort": cohorts,
    "period": periods,
    "collections": np.arange(len(cohorts_idx))
    }

with pm.Model(coords = coords) as model:
    
    # global model parameters
    omega = pm.HalfNormal("omega", sigma = 3)
    theta = pm.HalfNormal("theta", sigma = 5)
    sigma = pm.HalfNormal("sigma", sigma = 20)
            
    # cohort specific parameter
    Ci = pm.TruncatedNormal("Ci", mu = 60, sigma = 10, lower = 10, upper = 110, dims = "cohort")
    

    mu_i_t = Ci[cohorts_idx] * (1 - tt.exp(- (periods[periods_idx] / theta) ** omega))
    sigma_i_t = sigma * mu_i_t ** 0.5
    
    _ = pm.Normal("Collections_i_t",
                                mu = mu_i_t,
                                sigma = sigma_i_t,            
                                observed = inputs['Collections'],
                                dims = "collections")
         
    results = pm.sample(draws = 1000, tune = 1000, cores = 8)
 
    return pm.summary(results)
  

Результирующее сообщение об ошибке:

 mu_i_t = Ci[cohorts_idx] * (1 - tt.exp(- (periods[periods_idx] / theta) ** omega))

File "C:UsersalexiAnaconda3libsite-packagespandascoreindexesbase.py", line 139, in 
index_arithmetic_method
result = op(Series(self), other)

File "C:UsersalexiAnaconda3libsite-packagespandascoreopscommon.py", line 64, in new_method
return method(self, other)

File "C:UsersalexiAnaconda3libsite-packagespandascoreops__init__.py", line 505, in wrapper
return _construct_result(left, result, index=left.index, name=res_name)

File "C:UsersalexiAnaconda3libsite-packagespandascoreops__init__.py", line 478, in _ 
construct_result
out = left._constructor(result, index=index)

File "C:UsersalexiAnaconda3libsite-packagespandascoreseries.py", line 279, in __init__
data = com.maybe_iterable_to_list(data)

File "C:UsersalexiAnaconda3libsite-packagespandascorecommon.py", line 280, in 
maybe_iterable_to_list
return list(obj)

File "C:UsersalexiAnaconda3libsite-packagestheanotensorvar.py", line 640, in __iter__
for i in xrange(theano.tensor.basic.get_vector_length(self)):

File "C:UsersalexiAnaconda3libsite-packagestheanotensorbasic.py", line 4828, in 
get_vector_length
raise ValueError("length not known: %s" % msg)

ValueError: length not known: Elemwise{true_div,no_inplace} [id A] ''   
|TensorConstant{[ 1  2  3 ..  1  2  1]} [id B]
|InplaceDimShuffle{x} [id C] ''   
|ViewOp [id D] 'theta'   
 |Elemwise{exp,no_inplace} [id E] ''   
   |theta_log__ [id F]
  

Я понятия не имею, почему. Обратите внимание, что если вместо деления на Тету в строке, которая вызывает ошибку, я делаю сложение вместо этого, тогда это работает (очевидно, это не то, что я хочу, хотя).

Как я могу решить эту проблему и заставить это разделение работать?

Ответ №1:

Хорошо, я узнал. Я недостаточно хорош, чтобы объяснить, почему, но работает следующее. Нужно заменить строку:

mu_i_t = Ci[cohorts_idx] * (1 — tt.exp(- (периоды [periods_idx] / тета) ** омега))

Автор::

mu_i_t = Ci[cohorts_idx] * (1 — tt.exp(- (периоды [periods_idx].to_numpy() / тета) ** омега))