展开

马尔科链与隐马尔科夫链

最后发布时间 : 2024-01-28 17:41:43 浏览量 :

假设一家餐厅只有三种食物汉堡、热狗和披萨,他们每天只提供这三种食物的一种,这取决于它们昨天提供的食物。换句话,如果你知道他们今天提供的食物,就可以预测他们明天提供的食物。

下图中箭头源于当前的状态,指向未来的状态

生信小木屋

马尔可夫链最重要的属性是,未来的状态仅取决于当前的状态
生信小木屋

假设餐厅第一天提供披萨、第二天提供汉堡、第三天提供披萨、问第四天提供热狗的概率是多少?

生信小木屋

第四天提供热狗的概率,只与第三天提供披萨的概率有关
生信小木屋

使用线性代数的邻接矩阵表示马尔可夫链

生信小木屋

上面这个矩阵也称为转移矩阵

马尔可夫链的静止状态

对马尔可夫链进行Random Walk,最初从汉堡开始,循环10天,我们可以计算每种食物出现的概率,只是简单的用每个食物出现次数除以总次数。我们是对长期发生的事情感兴趣,这些概率是否收敛于固定的值,或者是一直变化。编写一个python脚本模拟十万步随机工作,我们发现概率收敛于下面的值。我们可以得到该概率不会随着时间发生变化。

生信小木屋

上述这种方法不是很有效,并且我们不知道是否存在其它静止状态,解决这个问题的最好方法是使用线性代数。

马尔可夫链的静止状态(stationary state)指的是在经过足够长时间的转移后,系统的状态分布保持不变的状态。在静止状态下,每个状态的概率分布与其前一时刻的状态无关。

对于离散状态的马尔可夫链,静止状态可以表示为一个概率向量 π = [π₁, π₂, ..., πₙ],其中 πᵢ 表示系统处于状态 i 的概率。静止状态满足以下条件:

  • 静止状态是非负的:πᵢ ≥ 0,对于所有的 i。
  • 静止状态的概率之和为 1:Σᵢ πᵢ = 1。
    在数学上,静止状态可以通过求解方程 πP = π 来获得,其中 P 是状态转移矩阵,π 是静止状态向量。

对于连续状态的马尔可夫链,静止状态可以表示为一个概率密度函数,满足以下条件:

  • 静止状态是非负的:p(x) ≥ 0,对于所有的 x。
  • 静止状态的积分等于 1:∫ p(x) dx = 1。

静止状态在马尔可夫链中具有重要的性质,它表示了系统在长时间内的稳定行为。在静止状态下,马尔可夫链的状态分布不再随时间变化,而是保持固定。这使得静止状态成为对系统行为进行分析和推断的有用工具。

如果静止状态存在,一个向量乘以A还会得到这个向量

生信小木屋

\pi \dot A=\pi这个方程与特征向量方程很相似,只是让\lambda=0,颠倒顺序后\pi是A的左特征向量。特征向量必须满足,加起来等于1。

生信小木屋

因此,在求解这个方程后,我们得到稳态
生信小木屋

生信小木屋

Markov Chains Clearly Explained! Part - 1

隐马尔科夫链(Hidden Markov Model,HMM)和马尔可夫链(Markov Chain)都是描述随机过程的数学模型,但它们之间有一些区别。

马尔可夫链是一个数学模型,用来描述一系列随机事件的演化过程。该过程中,每个事件的概率仅与前一个状态有关,而与过去事件的历史无关。因此,马尔可夫链具有“无记忆性”的特点。在马尔可夫链中,状态转移概率是已知的,每个状态的转移概率只依赖于它的前一个状态,而不依赖于其他的状态或时间。

隐马尔科夫模型是一个统计模型,用于解决预测或识别模型问题。在 HMM 中,系统的状态是隐含的,我们不能直接观察到其状态,但是可以通过观察到的状态序列推断出其隐含状态。HMM 是建立在马尔可夫链基础上的,但是与马尔可夫链不同的是,HMM 的每个状态对应着一个概率分布函数,而不是一个确定的状态。在 HMM 中,观察到的数据由隐含变量(即状态)生成,系统的状态转移和观察结果的分布都是未知的,并且需要通过观察结果的分布来进行参数估计。

因此,隐马尔科夫模型相对于马尔可夫链更加复杂,但也更加灵活和实用。HMM 可以用于语音识别、自然语言处理、生物信息学等领域。

生信小木屋

三个必备:初始概率(Π),隐藏状态转移概率矩阵(A),生成观测状态概率矩阵(B)。

生信小木屋
生信小木屋

北京大学生物信息学:学习方法

python实现马尔科夫链

首先,您需要定义状态空间以及状态之间的转移矩阵。假设我们有三个状态:A、B和C,并且转移矩阵如下:

      A    B    C
  --------------
A | 0.1  0.4  0.5
B | 0.6  0.2  0.2
C | 0.3  0.3  0.4

这意味着在状态A下,有10%的概率留在A,40%的概率转移到B,50%的概率转移到C。
接下来,您需要选择一个初始状态。让我们选择状态A作为初始状态。
最后,你需要计算n步后到达每个状态的概率。假设我们要计算2步后到达每个状态的概率。我们可以通过以下代码实现:

import numpy as np
import pandas as pd

# 定义状态空间和转移矩阵
states = ['A', 'B', 'C']
transition_matrix = np.array([[0.1, 0.4, 0.5],
                              [0.6, 0.2, 0.2],
                              [0.3, 0.3, 0.4]])

# 定义初始状态
current_state = 'A'

# 计算2步后到达每个状态的概率
df_result = pd.DataFrame(columns=states)
for i in range(2):
    if i == 0:
        # 第一步
        df_result.loc[i] = np.dot([1, 0, 0], transition_matrix)
    else:
        # 第二步
        df_result.loc[i] = np.dot(df_result.loc[i-1], transition_matrix)

print(df_result)

输出结果如下:

     A    B    C
0  0.1  0.4  0.5
1  0.39  0.29  0.32

这意味着在第一步之后,有10%的概率仍然在状态A,40%的概率转移到了B,50%的概率转移到C。在第二步之后,有39%的概率在状态A,29%的概率在B,32%的概率在C。

python实现隐马尔科夫链

import numpy as np

# 定义隐马尔科夫模型参数
hidden_states = ('S1', 'S2', 'S3')
observations = ('A', 'B', 'C')
start_prob = {'S1': 0.4, 'S2': 0.3, 'S3': 0.3}
transition_prob = {'S1': {'S1': 0.3, 'S2': 0.4, 'S3': 0.3},
                    'S2': {'S1': 0.2, 'S2': 0.5, 'S3': 0.3},
                    'S3': {'S1': 0.1, 'S2': 0.2, 'S3': 0.7}}
emission_prob = {'S1': {'A': 0.2, 'B': 0.4, 'C': 0.4},
                'S2': {'A': 0.5, 'B': 0.4, 'C': 0.1},
                'S3': {'A': 0.1, 'B': 0.3, 'C': 0.6}}
# 隐马尔科夫链函数下面是一个用于执行隐马尔科夫链预测的Python函数:
def forward_algorithm(observations, hidden_states, start_prob, transition_prob, emission_prob):
    # 初始化alpha矩阵
    alpha = np.zeros((len(hidden_states), len(observations)))
    for i, state in enumerate(hidden_states):
        alpha[i, 0] = start_prob[state] * emission_prob[state][observations[0]]
    # 递推计算alpha矩阵
    for t in range(1, len(observations)):
        for j, state in enumerate(hidden_states):
            alpha[j, t] = sum(alpha[i, t-1] * transition_prob[hidden_states[i]][state] * emission_prob[state][observations[t]] for i in range(len(hidden_states)))
    return alpha

# 测试隐马尔科夫链预测
observations = ('A', 'B', 'C', 'B', 'C', 'A')
alpha = forward_algorithm(observations, hidden_states, start_prob, transition_prob, emission_prob)
print("Alpha matrix:")
print(alpha)
print("Log-likelihood:")
print(np.log(sum(alpha[:, -1])))

上述代码中,forward_algorithm函数是执行隐马尔科夫链预测的函数,输入参数包括观测序列、隐状态、模型参数。该函数使用前向算法(forward algorithm)计算给定观测序列下每个隐状态出现的概率,并返回alpha矩阵。在函数中,首先初始化alpha矩阵,并计算第一个观测值下每个隐状态出现的概率。然后,使用递推计算的方式,计算后续观测值下每个隐状态出现的概率。最后,返回alpha矩阵。在测试代码中,我们使用给定的隐马尔科夫模型参数和一个观测序列进行测试,并输出alpha矩阵和对数似然值。可以根据需要调整输入参数,使用不同的隐马尔科夫模型参数和不同的观测序列进行测试。

Alpha matrix:
[[8.00000000e-02 2.28000000e-02 7.43200000e-03 2.13200000e-03
  7.99464000e-04 1.35218384e-04]
 [1.50000000e-01 4.52000000e-02 3.71200000e-03 3.81792000e-03
  3.95271200e-04 6.15909080e-04]
 [3.00000000e-02 2.70000000e-02 2.35800000e-02 5.95476000e-03
  3.57198480e-03 2.85880992e-04]]
Log-likelihood:
-6.871415195476768

在隐马尔科夫模型中,alpha矩阵是前向概率矩阵,用于计算给定观测序列下每个隐状态出现的概率。alpha矩阵的每一列表示一个观测值,每一行表示一个隐状态。具体来说,alpha矩阵中的元素alpha[i,j]表示在时间步j(即第j个观测值)下,隐状态为i的概率。alpha矩阵的计算使用前向算法(forward algorithm)进行,具体来说,首先初始化alpha矩阵的第一列(即第一个观测值下每个隐状态出现的概率),然后使用递推计算的方式计算后续观测值下每个隐状态出现的概率,直到计算出整个alpha矩阵。在隐马尔科夫模型中,alpha矩阵的最后一列的和就是给定观测序列的概率(也称为前向概率)。