Две проблемы при написании скрипта для вычисления марковского совместного распределения (на питоне)

Я новичок в Python, недавно я работаю над каким-то проектом, чтобы выполнить вычисление совместного распределения марковского процесса.

Пример стохастического ядра используется в недавнем исследовании Гамильтона (2005), который исследует нелинейную статистическую модель делового цикла на основе данных по безработице в США. В рамках своих расчетов он оценивает ядро

pH :=   0.971 0.029 0
        0.145 0.778 0.077
        0     0.508 0.492

Здесь S = {x1, x2, x3} = {NG, MR, SR}, где NG соответствует нормальному росту, MR — умеренному спаду, а SR — тяжелому спаду. Например, вероятность перехода от тяжелой рецессии к легкой рецессии за один период составляет 0,508. Продолжительность периода составляет один месяц.

упражнение, основанное на вышеупомянутом марковском процессе,

Что касается ядра Гамильтона pH, и используя то же начальное условие ψ = (0,2, 0,2, 0,6), вычислить вероятность того, что экономика начнет рецессию и останется в ней в течение периодов 0, 1, 2 (т. е. что xt = NG fort = 0, 1, 2).

Мой сценарий похож на

import numpy as np
## In this case, X should be a matrix rather than vector
## and we compute w.r.t P rather than merely its element [i][j]
path = []
def path_prob2 (p, psi , x2):  # X a sequence giving the path
     prob = psi                # initial distribution is an row vector
     for t in range(x2.shape[1] -1): # .shape[1] grasp # of columns
        prob = np.dot(prob , p)       # prob[t]: marginal distribution at period t
        ression = np.dot(prob, x2[:,t])
     path.append(ression)
     return path,prob



p = ((0.971, 0.029, 0    ),
      (0.145, 0.778, 0.077),
      (0    , 0.508, 0.492)) 
# p must to be a 2-D numpy array     
p = np.array(p)      

psi = (0.2, 0.2, 0.6)  
psi = np.array(psi)  
x2 = ((0,0,0),
      (1,1,1),
      (1,1,1))
x2 = np.array(x2)      
path_prob2(p,psi,x2)

В процессе выполнения возникают две проблемы. Во-первых, в первом раунде цикла мне не нужно начальное распределение psi для постумножения матрицы транзакций p, поэтому вероятность «остаться в рецессии» должна быть 0,2 + 0,6 = 0,8, но я не знаю как написать условие if. Второе, как вы могли заметить, я использую список под названием path для сбора вероятности «остаться в рецессии» в каждый период. И, наконец, мне нужно умножить каждый элемент в списке один за другим, мне не удается найти метод для реализации такой задачи, например path[0]*path[1]*path[2] (насколько я знаю, np.multiply может принимать только два аргумента). Пожалуйста, дайте мне некоторые подсказки, если такой метод существует. Дополнительный вопрос: пожалуйста, дайте мне любое предложение, которое, по вашему мнению, может сделать код более эффективным. Спасибо.


person zlqs1985    schedule 10.02.2016    source источник
comment
Ты решил свою проблему?   -  person Fanchi    schedule 10.02.2016
comment
@Fanchi Еще нет, к сожалению.   -  person zlqs1985    schedule 10.02.2016
comment
Что касается вашего первого вопроса, я сначала должен спросить, чего именно вы пытаетесь достичь, поскольку это недостаточно ясно? В цикле for внутри функции вы вычисляете ression, но вы добавляете только последнее вычисленное ression каждого цикла, так зачем вообще вычислять его внутри цикла. Что касается вашего второго вопроса, я считаю, что Numpy.prod даст вам умножение между всеми элементами списка/массива. Вы можете использовать prod как таковой: ››› np.prod([15,20,31]) 9300   -  person Fanchi    schedule 10.02.2016
comment
Спасибо за ваш любезный ответ, @Fanchi. Что касается моего первого вопроса, то, что я хочу, находится на начальном этапе, я хочу только рассчитать psi*x2 = (0.2, 0.2, 0.6)*(0,1,1).T = 0.8, то есть вероятность того, что вы не находитесь в состоянии NR (или, в равной степени, в состоянии рецессии) . Для остальных шагов я вычисляю psi * P*x2, и задача обновляет каждый период, поэтому первый подход, который приходит мне на ум, заключается в использовании оператора ·if-else· для разделения начального шага и других шагов. Но как это написать? Если мне не нужно писать if-else , есть ли альтернативный подход для достижения моей цели?   -  person zlqs1985    schedule 10.02.2016


Ответы (1)


Если я вас правильно понял, это должно работать (мне бы хотелось, чтобы некоторые расчеты вручную для некоторых шагов/результатов), обратите внимание на тот факт, что я не использовал оператор if/else, а вместо этого начал итерацию со второго столбца:

import numpy as np

# In this case, X should be a matrix rather than vector
# and we compute w.r.t P rather than merely its element [i][j]
path = []


def path_prob2(p, psi, x2):  # X a sequence giving the path
    path.append(np.dot(psi, x2[:, 0]))  # first step
    prob = psi  # initial distribution is an row vector
    for t in range(1, x2.shape[1]):  # .shape[1] grasp # of columns
        prob = np.dot(prob, p)  # prob[t]: marginal distribution at period t
        path.append(np.prod(np.dot(prob, t)))
    return path, prob


# p must to be a 2-D numpy array
p = np.array([[0.971, 0.029, 0],
              [0.145, 0.778, 0.077],
              [0, 0.508, 0.492]])

psi = np.array([0.2, 0.2, 0.6])
x2 = np.array([[0, 0, 0],
               [1, 1, 1],
               [1, 1, 1]])

print path_prob2(p, psi, x2)

Что касается вашего второго вопроса, я считаю, что Numpy.prod даст вам умножение между всеми элементами списка/массива.

Вы можете использовать продукт как таковой:

>>> np.prod([15,20,31])
9300
person Fanchi    schedule 10.02.2016
comment
Привет, @Fanchi, эта строка path.append(np.dot(psi, x2[:, 0])) # first step выдает мне сообщение об ошибке, например TypeError: list indices must be integers, not tuple , я не знаю, почему - person zlqs1985; 11.02.2016
comment
Скопируйте весь код, как указано, в этой строке нет ничего, что могло бы вызвать эту ошибку. - person Fanchi; 11.02.2016