Вопрос или проблема
Я изучаю скрытую модель Маркова и её реализацию для прогнозирования цен на акции. Я пытаюсь реализовать алгоритм прямого прохода в соответствии с этой работой.
Здесь я нашел реализацию алгоритма прямого прохода на Python.
import pandas as pd
import numpy as np
V = np.array([0, 1, 1, 2, 0, 1, 2, 0, 1, 0, 2])
# Вероятности перехода
a = np.array(((0.54, 0.46), (0.49, 0.51)))
# Вероятности эмиссии
b = np.array(((0.16, 0.26, 0.58), (0.25, 0.28, 0.47)))
# Равные вероятности для начального распределения
pi = np.array((0.5, 0.5))
def forward(V, a, b, pi):
alpha = np.zeros((V.shape[0], a.shape[0]))
alpha[0, :] = initial_distribution * b[:, V[0]]
for t in range(1, V.shape[0]):
for j in range(a.shape[0]):
alpha[t, j] = alpha[t - 1].dot(a[:, j]) * b[j, V[t]]
return alpha
alpha = forward(V, a, b, pi)
Но мне кажется, что в этом коде не включены этапы (c) и (d) из алгоритма. Поэтому я их добавил:
def forward(V, a, b, pi):
p = 1
alpha = np.zeros((V.shape[0], a.shape[0]))
alpha[0, :] = pi * b[:, V[0]]
for t in range(1, V.shape[0]):
probability_of_observation = 0 #мой код
for j in range(a.shape[0]):
alpha[t, j] = alpha[t - 1].dot(a[:, j]) * b[j, V[t]]
probability_of_observation += alpha[t, j] #мой код
p = p * probability_of_observation #мой код
return p #изменено
p = forward(V, a, b, pi) #изменено
Совпадает ли мой код с данным алгоритмом?
Может быть, эта библиотека Python могла бы вам помочь: hmmlearn
Когда я пытался построить HMM, я использовал её, и всё работало хорошо.
Ответ или решение
Конечно, давайте рассмотрим полный ответ на ваш вопрос о реализации алгоритма прямого распространения (Forward Algorithm) для скрытой марковской модели (Hidden Markov Model, HMM) на языке Python.
Определение задачи
Алгоритм прямого распространения используется для вычисления вероятности последовательности наблюдений (в данном случае стоимость акций) в рамках данной скрытой марковской модели. Он дает возможность оценить, насколько вероятно, что наблюдаемая последовательность была сгенерирована моделью, учитывая начальные вероятности, вероятности переходов и вероятности эмиссии.
Коды с реализацией
Ваш первоначальный код выглядит почти правильно, но в нем не хватает нескольких важных шагов, включая правильную нормализацию вероятностей, что на самом деле улучшает стабильность численных расчетов и предотвращает переполнение. Давайте рассмотрим ваш код и внесем необходимые изменения.
import pandas as pd
import numpy as np
# Наблюдаемые значения (например, цены акций)
V = np.array([0, 1, 1, 2, 0, 1, 2, 0, 1, 0, 2])
# Вероятности переходов
a = np.array([[0.54, 0.46],
[0.49, 0.51]])
# Вероятности эмиссии
b = np.array([[0.16, 0.26, 0.58],
[0.25, 0.28, 0.47]])
# Начальные вероятности
pi = np.array([0.5, 0.5])
def forward(V, a, b, pi):
n_observations = len(V) # Количество наблюдений
n_states = a.shape[0] # Количество скрытых состояний
# Инициализация матрицы альфа
alpha = np.zeros((n_observations, n_states))
# Базовый случай: вычисление первой строки альфа
alpha[0, :] = pi * b[:, V[0]]
# Основной цикл по времени
for t in range(1, n_observations):
for j in range(n_states):
alpha[t, j] = np.dot(alpha[t - 1], a[:, j]) * b[j, V[t]]
# Суммирование для вычисления полной вероятности результатов
p = np.sum(alpha[-1, :])
return p, alpha
# Запуск функции
p, alpha = forward(V, a, b, pi)
print("Вероятность наблюдаемой последовательности:", p)
print("Матрица альфа:\n", alpha)
Объяснение изменений
-
Инициализация альфа: Вы правильно используете начальные вероятности (pi) умноженные на вероятности эмиссии (b). Это позволяет нам правильно инициализировать первый временной шаг.
-
Основной цикл расчета альфа: Цикл, который обновляет альфа для каждого времени t, в основном остается неизменным. Однако переходы и эмиссии рассчитываются с использованием
np.dot
, что повышает читабельность. -
Подсчет полной вероятности последовательности: После того как вся матрица альфа заполнена, мы суммируем все вероятности в последнем временном шаге для получения общей вероятности наблюдаемой последовательности.
Заключение
Ваши дополнения к коду были довольно близкими к правильному подходу, но важно помнить, что хорошая практика при реализации алгоритма — это проводить нормализацию и избегать переполнения. Также вы можете рассмотреть использование таких библиотек, как hmmlearn
, которые упрощают работу с HMM и предоставляют готовые решения.
Если у вас есть дополнительные вопросы или нужны разъяснения, не стесняйтесь спрашивать!