機器學習筆記 - 24. 隱馬爾科夫模型實踐(講師:鄒博)

主要內(nèi)容

2019-04-18 18_09_57-機器學習第七期升級版.png

需要熟悉:UTF-8, GBK編碼使用方式
如果需要使用隱馬爾科夫模型,首先狀態(tài)一定是離散的,觀測值不一定要求是離散的,可以做觀測值是連續(xù)的隱馬爾科夫模型

中文分詞

如下圖:A矩陣是4x4的矩陣(Begin Middle End Single), B矩陣是4x65536的矩陣,π是4個元素的矩陣


2019-04-18 18_38_09-機器學習第七期升級版.png

用Viterbi算法做文檔的切詞,現(xiàn)在比較常用是直接用jieba組件做分詞

import jieba.posseg

if __name__ == "__main__":
    f = open('.\\novel.txt', encoding='utf-8')
    str = f.read()#.decode('utf-8')
    f.close()

    seg = jieba.posseg.cut(str)
    for word, pos in seg:
        print(word, pos, '|', end=' ')

分詞結(jié)果:


2019-04-23 19_47_56-Start.png

Hmmlearn的安裝

# pip install hmmlearn
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: hmmlearn in c:\python3.6\lib\site-packages (0.2.1)
Requirement already satisfied: numpy in c:\python3.6\lib\site-packages (from hmmlearn) (1.16.2+mkl)
Requirement already satisfied: scikit-learn>=0.16 in c:\python3.6\lib\site-packages (from hmmlearn) (0.20.3)
Requirement already satisfied: scipy>=0.13.3 in c:\python3.6\lib\site-packages (from scikit-learn>=0.16->hmmlearn) (1.0.0)

hmmlearn實現(xiàn)了三種HMM模型類,按照觀測狀態(tài)是連續(xù)狀態(tài)還是離散狀態(tài),可以分為兩類。GaussianHMM和GMMHMM是連續(xù)觀測狀態(tài)的HMM模型,而MultinomialHMM是離散觀測狀態(tài)的模型,也是我們在HMM原理系列篇里面使用的模型。
對于MultinomialHMM的模型,使用比較簡單,"startprob_"參數(shù)對應(yīng)我們的隱藏狀態(tài)初始分布Π, "transmat_"對應(yīng)我們的狀態(tài)轉(zhuǎn)移矩陣A, "emissionprob_"對應(yīng)我們的觀測狀態(tài)概率矩陣B。
對于連續(xù)觀測狀態(tài)的HMM模型,GaussianHMM類假設(shè)觀測狀態(tài)符合高斯分布,而GMMHMM類則假設(shè)觀測狀態(tài)符合混合高斯分布。一般情況下我們使用GaussianHMM即高斯分布的觀測狀態(tài)即可。以下對于連續(xù)觀測狀態(tài)的HMM模型,我們只討論GaussianHMM類。
在GaussianHMM類中,"startprob_"參數(shù)對應(yīng)我們的隱藏狀態(tài)初始分布Π, "transmat_"對應(yīng)我們的狀態(tài)轉(zhuǎn)移矩陣A, 比較特殊的是觀測狀態(tài)概率的表示方法,此時由于觀測狀態(tài)是連續(xù)值,我們無法像MultinomialHMM一樣直接給出矩陣B。而是采用給出各個隱藏狀態(tài)對應(yīng)的觀測狀態(tài)高斯分布的概率密度函數(shù)的參數(shù)。
如果觀測序列是一維的,則觀測狀態(tài)的概率密度函數(shù)是一維的普通高斯分布。如果觀測序列是N維的,則隱藏狀態(tài)對應(yīng)的觀測狀態(tài)的概率密度函數(shù)是N維高斯分布。高斯分布的概率密度函數(shù)參數(shù)可以用μ表示高斯分布的期望向量,Σ表示高斯分布的協(xié)方差矩陣。在GaussianHMM類中,“means”用來表示各個隱藏狀態(tài)對應(yīng)的高斯分布期望向量μ形成的矩陣,而“covars”用來表示各個隱藏狀態(tài)對應(yīng)的高斯分布協(xié)方差矩陣Σ形成的三維張量。

GMHMM

2019-04-23 19_51_39-機器學習第七期升級版.png

這個例子,給定任何一個樣本點,將其作為高斯分布的采樣,即直接使用隱馬爾科夫模型。從5個高斯分布,隨機選出一個高斯分布,并從中選擇一個樣本來,通過高斯分布,以某種狀態(tài)轉(zhuǎn)移概率矩陣方式,轉(zhuǎn)移到另外的可能的高斯分布上面去。再在這個高斯分布采取一個樣本點,然后繼續(xù)轉(zhuǎn)移。。。不斷做狀態(tài)轉(zhuǎn)移,以及選擇樣本點,只把采樣的狀態(tài)樣本值取出來,這個即是高斯混合模型的樣子。


2019-04-23 19_56_48-機器學習第七期升級版.png

代碼如下:

# !/usr/bin/python
import numpy as np
from hmmlearn import hmm
import matplotlib.pyplot as plt
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from sklearn.metrics.pairwise import pairwise_distances_argmin
import warnings


def expand(a, b):
    return 1.05*a-0.05*b, 1.05*b-0.05*a


if __name__ == "__main__":
    warnings.filterwarnings("ignore")   # hmmlearn(0.2.0) < sklearn(0.18)
    np.random.seed(0)

    n = 5   # 隱狀態(tài)數(shù)目
    n_samples = 500
    pi = np.random.rand(n)
    pi /= pi.sum()
    print('初始概率:', pi)

    A = np.random.rand(n, n)
    mask = np.zeros((n, n), dtype=np.bool)
    mask[0][1] = mask[0][4] = True
    mask[1][0] = mask[1][2] = True
    mask[2][1] = mask[2][3] = True
    mask[3][2] = mask[3][4] = True
    mask[4][0] = mask[4][3] = True
    A[mask] = 0
    for i in range(n):
        A[i] /= A[i].sum()
    print('轉(zhuǎn)移概率:\n', A)

    means = np.array(((30, 30, 30), (0, 50, 20), (-25, 30, 10), (-15, 0, 25), (15, 0, 40)), dtype=np.float)
    # means = np.random.rand(5, 3)
    print(means)
    for i in range(n):
        means[i,:] /= np.sqrt(np.sum(means ** 2, axis=1))[i]
    print('均值:\n', means)

    covars = np.empty((n, 3, 3))
    for i in range(n):
        # covars[i] = np.diag(np.random.randint(1, 5, size=2))
        covars[i] = np.diag(np.random.rand(3)*0.03+0.001)    # np.random.rand ∈[0,1)
    print('方差:\n', covars)

    model = hmm.GaussianHMM(n_components=n, covariance_type='full')
    model.startprob_ = pi
    model.transmat_ = A
    model.means_ = means
    model.covars_ = covars
    sample, labels = model.sample(n_samples=n_samples, random_state=0)

    # 估計參數(shù)
    model = hmm.GaussianHMM(n_components=n, covariance_type='spherical', n_iter=10)
    model.fit(sample)
    y = model.predict(sample)
    np.set_printoptions(suppress=True)
    print('##估計初始概率:', model.startprob_)
    print('##估計轉(zhuǎn)移概率:\n', model.transmat_)
    print('##估計均值:\n', model.means_)
    print('##估計方差:\n', model.covars_)

    # 類別
    order = pairwise_distances_argmin(means, model.means_, metric='euclidean')
    print(order)
    pi_hat = model.startprob_[order]
    A_hat = model.transmat_[order]
    A_hat = A_hat[:, order]
    means_hat = model.means_[order]
    covars_hat = model.covars_[order]
    change = np.empty((n, n_samples), dtype=np.bool)
    for i in range(n):
        change[i] = y == order[i]
    for i in range(n):
        y[change[i]] = i
    print('估計初始概率:', pi_hat)
    print('估計轉(zhuǎn)移概率:\n', A_hat)
    print('估計均值:\n', means_hat)
    print('估計方差:\n', covars_hat)
    print(labels)
    print(y)
    acc = np.mean(labels == y) * 100
    print('準確率:%.2f%%' % acc)

    mpl.rcParams['font.sans-serif'] = ['SimHei']
    mpl.rcParams['axes.unicode_minus'] = False
    fig = plt.figure(figsize=(8, 8), facecolor='w')
    ax = fig.add_subplot(111, projection='3d')
    colors = plt.cm.Spectral(np.linspace(0,1,n))
    ax.scatter(sample[:, 0], sample[:, 1], sample[:, 2], s=10, c=labels, cmap=plt.cm.Spectral, marker='o', label='觀測值', depthshade=True)
    # plt.plot(sample[:, 0], sample[:, 1], sample[:, 2], lw=0.4, color='#A07070')
    colors = plt.cm.Spectral(np.linspace(0, 1, n))
    ax.scatter(means[:, 0], means[:, 1], means[:, 2], s=600, c=colors, edgecolor='r', linewidths=1, marker='*', label='中心')

    x_min, y_min, z_min = sample.min(axis=0)
    x_max, y_max, z_max = sample.max(axis=0)
    x_min, x_max = expand(x_min, x_max)
    y_min, y_max = expand(y_min, y_max)
    z_min, z_max = expand(z_min, z_max)
    ax.set_xlim((x_min, x_max))
    ax.set_ylim((y_min, y_max))
    ax.set_zlim((z_min, z_max))
    plt.legend(loc='upper left')
    plt.grid(True)
    plt.tight_layout(1)
    plt.title('GMHMM參數(shù)估計和類別判定', fontsize=18)
    plt.show()
2019-04-23 19_58_51-Start.png

問:
問題:π中的M, E概率不是應(yīng)該為0么,取對數(shù)以后應(yīng)該是一一個很大的負數(shù),老師的pi.txt里面好像不是這樣的么?
答:是的,可能代碼有bug

To be continued...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容