HMM隐性马可夫模型

来自集智百科 - 复杂系统|人工智能|复杂科学|复杂网络|自组织
思无涯咿呀咿呀讨论 | 贡献2020年10月15日 (四) 15:30的版本
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

原理

Hidden Markov model,隐性马可夫模型,是语音处理和图像识别等领域常常会用到的模型。它的核心原理是假设观测变量是由一些隐变量引起的,通过观测变量的数据去推断隐变量的发生概率。隐性马可夫和传统马可夫链的区别就是,在后者中,系统的状态是可观测的,我们只需要根据数据计算状态之间的转移概率即可。

HMM1.png

在上图中:

x 代表状态 (states)

y 代表观测到的行为 (possible observations)

a 代表状态转移概率 (state transition probabilities)

b 代表状态产生行为的概率 (output probabilities)


Alice和Bob的例子

HMM2.png

Alice和Bob是朋友,Bob每天打电话和Alice说今天做了什么事,Alice从中可以猜测Bob所在地方的天气如何(隐变量)。天气有两种状态,rainy和sunny。前者概率是0.6,后者概率是0.4,从一个状态转到另一个状态的概率如上图所示。Bob的行为有三种可能,散步(walking),购物(shopping)和在家里做家务(cleanning)。显然,下雨的时候比较可能在家做家务,天气晴朗的时候比较可能散步,但也不绝对。天气与行为之间的关系也如上图所示。

这个图里的信息使用python语言可以表达如下:

    from __future__ import division
    import numpy as np
    from sklearn import hmm
    
    states = ["Rainy", "Sunny"]
    n_states = len(states)
    
    observations = ["walk", "shop", "clean"]
    n_observations = len(observations)
    
    start_probability = np.array([0.6, 0.4])
    
    transition_probability = np.array([
      [0.7, 0.3],
      [0.4, 0.6]
    ])
    
    emission_probability = np.array([
      [0.1, 0.4, 0.5],
      [0.6, 0.3, 0.1]
    ])


使用sklearn自带的包来训练这个HMM模型是非常容易的:

    model = hmm.MultinomialHMM(n_components=n_states)
    model._set_startprob(start_probability)
    model._set_transmat(transition_probability)
    model._set_emissionprob(emission_probability)

训练模型完毕之后,我们就可以根据训练得到的模型,来从Bob对他自己行为的描述中推断天气了:

    bob_says = [0, 2, 1, 1, 2, 0]
    logprob, alice_hears = model.decode(bob_says, algorithm="viterbi")
    print "Bob says:", ", ".join(map(lambda x: observations[x], bob_says))
    print "Alice hears:", ", ".join(map(lambda x: states[x], alice_hears))

打印出来的结果是:

“Bob says: walk, clean, shop, shop, clean, walk” “Alice hears: Sunny, Rainy, Rainy, Rainy, Rainy, Sunny”

其实我们这里并不是使用实际数据来训练,而是直接指定了模型的参数。在真实的案例中,需要准备一个训练集,既有Bob行为的数据,也有当地天气的数据,从这里面,使用HMM,估计出各种参数。然后在测试样本中,再根据估计得到的参数和新的Bob行为数据来猜测真实的天气情况。


使用sklearn来制造一个toy model

先import一下包

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn import hmm

然后预设一些参数

    # Initial population probability
    start_prob = np.array([0.6, 0.3, 0.1, 0.0])
    # The transition matrix, note that there are no transitions possible
    # between component 1 and 4
    trans_mat = np.array([[0.7, 0.2, 0.0, 0.1],
                          [0.3, 0.5, 0.2, 0.0],
                          [0.0, 0.3, 0.5, 0.2],
                          [0.2, 0.0, 0.2, 0.6]])
    # The means of each component
    means = np.array([[0.0,  0.0],
                      [0.0, 11.0],
                      [9.0, 10.0],
                      [11.0, -1.0],
                      ])
    # The covariance of each component
    covars = .5 * np.tile(np.identity(2), (4, 1, 1))

使用预定的参数来指定模型

    # Build an HMM instance and set parameters
    model = hmm.GaussianHMM(4, "full", start_prob, trans_mat,
                            random_state=42)
    # Instead of fitting it from the data, we directly set the estimated
    # parameters, the means and covariance of the components
    model.means_ = means
    model.covars_ = covars

最后,把四个component画出来

    # Generate samples
    X, Z = model.sample(500)
    
    # Plot the sampled data
    plt.plot(X[:, 0], X[:, 1], "-o", label="observations", ms=6,
             mfc="orange", alpha=0.7)
    
    # Indicate the component numbers
    for i, m in enumerate(means):
        plt.text(m[0], m[1], 'Component %i' % (i + 1),
                 size=17, horizontalalignment='center',
                 bbox=dict(alpha=.7, facecolor='w'))
    plt.legend(loc='best')

如下图所示:

HMM figure 1.png


相关wiki