hmmlearn之MultinomialHMM 离散隐马尔科夫模型

hmmlearn之MultinomialHMM 离散隐马尔科夫模型

1. 安装:pip3 install hmmlearn

2. 模型参数:

hmmlearn.hmm.MultinomialHMM(
    n_components=1,   # 隐藏状态的种类
    # 以下参数用于模型训练:
    n_trials=None, 
    startprob_prior=1.0, # 由模型本身对初始概率分布随机初始化
    transmat_prior=1.0,  # 由模型本身对状态转移概率随机初始化
    algorithm='viterbi',  # 解码方法
    n_iter=10, # 训练迭代的次数
    tol=0.01,  # 训练结束的阈值
    verbose=False,  # 训练过程是否可见
    params='ste',  # 训练过程中更新的参数,默认为所有的参数
    init_params='ste',  # 由模型进行随机初始化的参数,默认为所有的参数
    implementation='log')  # 选择对数/缩放进行前向或后向算法

s: 初始概率分布
t: 状态转移概率
e: 发射概率

3. 建模

(1)初始化全部的模型参数

(2)初始化部分的模型参数

# 1. 初始化全部模型参数,建立模型
# 例1:
import numpy as np
from hmmlearn import hmm

states = ["box1", "box2", "box3"]  # 隐藏状态
n_states = len(states)

observations = ["red", "white"]  # 观测状态
n_observations = len(observations)

start_probability = np.array([0.2, 0.4, 0.4])

transition_probability = np.array([
  [0.5, 0.2, 0.3],
  [0.3, 0.5, 0.2],
  [0.2, 0.3, 0.5]
])

emission_probability = np.array([
  [0.5, 0.5],
  [0.4, 0.6],
  [0.7, 0.3]
])

model_1 = hmm.MultinomialHMM(n_components=n_states)
model_1.startprob_=start_probability
model_1.transmat_=transition_probability
model_1.emissionprob_=emission_probability
model_1.n_features = n_observations  # 观测序列的种类

# 使用viterbi进行预测
se = np.array([[0, 1, 0, 0, 1]]).T
logprob, box_index = model_1.decode(se, algorithm='viterbi')
print("颜色:", end="")
print(" ".join(map(lambda t: observations[t], [0, 1, 0, 0, 1])))
print("盒子:", end="")
print(" ".join(map(lambda t: states[t], box_index)))
print("概率值:", end="")
print(np.exp(logprob)) # 这个是因为在hmmlearn底层将概率进行了对数化,防止出现乘积为0的情况


# 例2:
import numpy as np
from hmmlearn import hmm

n_components = 3
# 初始概率分布都为1/3
pi = np.ones(n_components)/n_components  
# 状态转移矩阵
A = np.array([ [0.4, 0.3, 0.3],
               [0.3, 0.4, 0.3],
               [0.3, 0.3, 0.4], ])

# 发射矩阵                   
M_O2S = np.zeros([3,8])
M_O2S[0,:6]=1/6.0
M_O2S[1,:4]=1/4.0
M_O2S[2,:8]=1/8.0

n_features = 8 # 样本种类

model_2 = hmm.MultinomialHMM(n_components=n_components)
model_2.startprob_ = pi
model_2.transmat_ = A
model_2.emissionprob_ = M_O2S
model_2.n_features = n_features

# 计算观测的概率: evaluation问题-给定λ、O, 求 P(O|λ)
data = np.array([3,4,5])
data = np.expand_dims(data,axis=1)
prob = model_2.score(data)
print("log_prob:",prob)

# 求最有可能的状态序列:解码问题-viterbi-给定λ、O, 求I
decode = model_2.predict(data)
print("decode:",decode)

# 生成一组训练、测试数据
train_data = []
for i in range(200):
    data_m2,_ = model_2.sample(100)
    train_data.append(data_m2)

test_data = []
for i in range(30):
    data_m2,_ = model_2.sample(100)
    test_data.append(data_m2)
    
length_train_data = []
for data in train_data:
    length_train_data.append(np.shape(data)[0])
    
# (2) 不初始化参数,使用模型和观测序列训练模型参数
# 例1:
import numpy as np
import hmmlearn.hmm as hmm

states = ['盒子1', '盒子2', '盒子3']
obs = ['白球', '黑球']
n_states = len(states)
n_obs = len(obs)

model_3 = hmm.MultinomialHMM(n_components=n_states, n_iter=20, tol=0.001)
X3 = np.array([
    [0, 1, 0, 0, 1],
    [0, 0, 0, 1, 1],
    [1, 1, 0, 1, 0],
    [0, 1, 0, 1, 1],
    [0, 0, 0, 1, 0]
])
model_3.fit(X3)
print("输出根据数据训练出来的π")
print(model_3.startprob_)
print("输出根据数据训练出来的A")
print(model_3.transmat_)
print("输出根据数据训练出来的B")
print(model_3.emissionprob_)


# (3) 指定部分参数建立模型,由观测序列重新训练模型参数
import numpy as np
from hmmlearn import hmm

n_components = 3

pi_4 = np.array([0.2,0.7,0.1]) 

A_4 = np.array([ [0.8, 0.2, 0],
               [0, 0.8, 0.2],
               [0, 0, 1], ])

# 发射矩阵                   
M_O2S_4 = np.zeros([3,8])
M_O2S_4[0,:6]=0.8,0.04,0.04,0.04,0.04,0.04
M_O2S_4[1,:4]=1/4.0
M_O2S_4[2,:8]=1/8.0

model_4 = hmm.MultinomialHMM(n_components=n_components,n_iter=50,tol=0.001,verbose=True,params='te',init_params='')
# 训练转移矩阵和发射矩阵
model_4.startprob_ = pi_4
model_4.transmat_ = A_4
model_4.emissionprob_ = M_O2S_4

model_4.fit(np.concatenate(train_data,axis=0),np.array(length_train_data))
print(model_4.startprob_)
print(model_4.transmat_)
print(model_4.emissionprob_)


# 进行测试
'''
N_test1 = len(test_datas_hmm1)
N_test2 = len(test_datas_hmm2)
labs = [0 for i in range(N_test1)] + [1 for i in range(N_test2)]
test_datas = test_datas_hmm1 + test_datas_hmm2

for i,test_data in  enumerate(test_datas):
    
    score1 = trained_model_1.score(test_data)
    score2 = trained_model_2.score(test_data)
    det_lab = np.argmax([score1,score2])
    
    print("%f  %f  det_lab=%d  true_lab = %d"%(score1,score2,det_lab,labs[i])) 
'''

参考链接:
B站bugyu_ld
https://www.jianshu.com/p/0f175b9781de

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值