机器学习之HMM:基于hmmlearn的简单示例及说明
本文以iris数据为例,介绍了hmmlearn中实现HMM模型的简单示例。
一、基本流程
1.数据准备
本例采用的是经典的机器学习分类数据集iris。数据的加载比较简单,引入from sklearn.datasets import load_iris
后,再调用iris = load_iris()
即可。
# 加载IRIS数据库
iris = load_iris()
# 按不同类别组织数据集,因为数据有限,每个类别只留最后一个样本来做测试用
x_setosa = [iris['data'][i] for i in range(len(iris['data'])) if iris['target'][i]==0 ]
x_versicolor = [iris['data'][i] for i in range(len(iris['data'])) if iris['target'][i]==1 ]
x_virginica = [iris['data'][i] for i in range(len(iris['data'])) if iris['target'][i]==2 ]
2.基本问题确认
这一步应该是使用隐马尔可夫模型特有的,需要注意。我们知道隐马尔可夫模型有三个基本的问题:即学习问题,解码问题和概率计算问题。其中学习问题是学习模型参数,即训练模型。所以一般的模式识别问题,只需要确认该问题是属于解码问题,还是概率计算问题;回到本文中的数据集来说,我们需要实现不同类别的鸢尾花的识别,可以当作一个概率计算问题来处理。具体来说,我们需要学习三个不同的HMM模型,分别是setosa的HMM ,versicolor的HMM和 virginica 的HMM,然后用一组观测数据,分别输入不同的模型,计算不同模型下该观测数据出现的概率。
# 定义三个HMM模型
hmm_setosa = hmm.GaussianHMM(n_components=1)
hmm_versicolor = hmm.GaussianHMM(n_components=1)
hmm_virginica = hmm.GaussianHMM(n_components=1)
3.模型训练
hmmlearn
下模型的训练也很简单,调用模型的fit
方法即可。
# 训练模型
hmm_setosa.fit(x_setosa[:-1])
hmm_versicolor.fit(x_versicolor[:-1])
hmm_virginica.fit(x_virginica[:-1])
4.模型测试
调用模型的score
方法计算观察数据出现的概率时,注意输入数据需要组织为二维,即每一行表示一个样本,且该方法返回的是对数概率。
# 测试
x_test = [x_setosa[-1],x_versicolor[-1],x_virginica[-1]]
for x in x_test:
prob_se = hmm_setosa.score([x])
prob_ve = hmm_versicolor.score([x])
prob_vi = hmm_virginica.score([x])
log_prob = [prob_se,prob_ve,prob_vi]
print("the target is ",iris['target_names'][np.argmax(log_prob)],",and log_porb of HMMs are ",log_prob)
二、完整代码
#!/user/bin/env python3
# -*- coding : utf-8 -*-
import numpy as np
from sklearn.datasets import load_iris
from hmmlearn import hmm
def main():
# 加载IRIS数据库
iris = load_iris()
# 按不同类别组织数据集,因为数据有限,每个类别只留最后一个样本来做测试用
x_setosa = [iris['data'][i] for i in range(len(iris['data'])) if iris['target'][i]==0 ]
x_versicolor = [iris['data'][i] for i in range(len(iris['data'])) if iris['target'][i]==1 ]
x_virginica = [iris['data'][i] for i in range(len(iris['data'])) if iris['target'][i]==2 ]
# 定义三个HMM模型
hmm_setosa = hmm.GaussianHMM(n_components=1)
hmm_versicolor = hmm.GaussianHMM(n_components=1)
hmm_virginica = hmm.GaussianHMM(n_components=1)
# 训练模型
hmm_setosa.fit(x_setosa[:-1])
hmm_versicolor.fit(x_versicolor[:-1])
hmm_virginica.fit(x_virginica[:-1])
# 测试
x_test = [x_setosa[-1],x_versicolor[-1],x_virginica[-1]]
for x in x_test:
prob_se = hmm_setosa.score([x])
prob_ve = hmm_versicolor.score([x])
prob_vi = hmm_virginica.score([x])
log_prob = [prob_se,prob_ve,prob_vi]
print("the target is ",iris['target_names'][np.argmax(log_prob)],",and log_porb of HMMs are ",log_prob)
if __name__=='__main__':
main()
下图是运行的结果,三个测试样本的标签分别是 setosa ,versicolor 和 virginica,与我们取的测试数据的标签是一致的,图中还打印了各HMM对三个不同样本的对数概率。