什么是马尔可夫性质?
“……一个随机过程,在这个过程中,鉴于现在,未来独立于过去。”
假设一个带有公平硬币的简化抛硬币游戏。暂停怀疑并假设马尔可夫性质尚不清楚,我们想预测 10 次翻转后翻转正面的概率。在条件依赖的假设下(硬币具有过去状态的记忆,未来状态取决于过去状态的顺序),我们必须记录导致第 11 次翻转的特定顺序以及这些翻转的联合概率。所以想象在 10 次翻转后,我们有一个随机的正面和反面序列。该序列的联合概率为 0.5^10 = 0.0009765625。在条件依赖下,下一次翻转的概率为 0.0009765625 * 0.5 = 0.00048828125。
这是第 11 次翻转的真实概率吗?一定不行!
我们知道,抛硬币的事件并不取决于之前抛硬币的结果。硬币没有记忆。连续翻转的过程不会对先前的结果进行编码。每次翻转都是一个独特的事件,正面或反面的概率相等,也就是有条件地独立于过去的状态。这就是马尔可夫性质。
什么是马尔科夫模型?
马尔可夫链(模型)描述了一个随机过程,其中未来状态的假设概率仅取决于当前过程状态,而不取决于它之前的任何状态(shocker)。
让我们进入一个简单的例子。假设您想对给定当前状态的狗处于三种状态之一的未来概率进行建模。为此,我们需要指定状态空间、初始概率和转移概率。
想象一下你有一只非常懒惰的胖狗,所以我们将状态空间定义为睡觉、吃饭或大便。我们将初始概率分别设置为 35%、35% 和 30%。
1 | import numpy as np |
下一步是定义转移概率。它们只是在给定当前状态的情况下保持相同状态或移动到不同状态的概率。
1 | q_df = pd.DataFrame(columns=states, index=states) |
现在我们已经设置了初始和转移概率,我们可以使用Networkx 包创建一个马尔可夫图。
要做到这一点,需要一点灵活的思维。Networkx 创建 由节点和边组成的图。在我们的玩具示例中,狗的可能状态是节点,边是连接节点的线。转移概率是权重。它们表示在给定当前状态的情况下转换到某个状态的概率。
需要注意的是 networkx 主要处理字典对象。话虽如此,我们需要创建一个字典对象来保存我们的边及其权重。
不错。如果你沿着任何节点的边走,它会告诉你狗转换到另一个状态的概率。例如,如果狗在睡觉,我们可以看到狗有 40% 的机会继续睡觉,40% 的机会狗醒来并拉屎,20% 的机会狗醒来吃东西。
什么是马克可夫隐藏状态
考虑这样一种情况,您的狗行为异常,并且您想对狗的行为是由于疾病或其他方面健康时的古怪行为进行建模的可能性。
在这种情况下,狗的真实状态是未知的,因此 对您隐藏。对此进行建模的一种方法是假设 狗具有 代表真实隐藏状态的可观察行为。让我们来看一个例子。
首先,我们创建我们的状态空间——健康或生病。我们假设它们是等概率的。
1 |
|
这是它变得更有趣的地方。现在我们创建发射或观测 概率矩阵。该矩阵的大小为 M x O,其中 M 是隐藏状态的数量,O 是可能的可观察状态的数量。
给定当前的可观察状态,发射矩阵告诉我们狗处于隐藏状态之一的概率。
让我们保持与上一个示例相同的可观察状态。狗可以睡觉、吃东西或大便。现在我们做出最好的猜测来填充概率。
看这个图时,将healthy和sick作为同一level,从sleeping,pooping, eating到healthy和sick的边就是发射概率。
隐马尔可夫图稍微复杂一些,但原理是相同的。例如,您会预期,如果您的狗正在进食,那么它健康的可能性很高 (60%),而生病的可能性非常低 (10%)。
现在,如果您需要根据一系列观察结果随着时间的推移辨别您的狗的健康状况怎么办?
使用Viterbi 算法,我们可以根据观察序列确定最可能的隐藏状态序列。
高的水平,在每个时间步长Viterbi算法的增量,寻找最大 的是得到陈述的任何路径的概率我在时间牛逼,那也 有序列最多时间正确的观察牛逼。
该算法还跟踪每个阶段概率最高的状态。在序列的末尾,算法将向后迭代,选择每个时间步“获胜”的状态,从而创建最可能的路径,或可能导致观察序列的隐藏状态序列。
最终代码:
1 |
|
结果:
1 |
|
相关代码: https://github.com/geasyheart/algo/commit/6cf0beca368d6c94f4a19c87f43b31e63306e0a3