虽然是理工妹子,但仍是数学渣。症状之一就是每次学习算法都能把自己绕成鸡窝头。所以尝试写一篇数学渣眼中的HMM。
我们先看一个让人头疼的HMM定义式(喜欢从公式下手是我多年来应付考试养成的不良习性)
一、HMM五元素
HMM简介 - 碳基体 - 碳基体
N:隐藏状态数 hidden states
M:观测状态数 observed states
A: 状态转移矩阵 transition matrix
B:发射矩阵 emission matrix
pi:初始隐状态向量 initial state vector
好了,接下来我们用数学渣可以理解的语言来解释上面都是些什么鬼
女主:小红 用食物丈量心情
心情状态有三种: 开心、正常、崩溃
上面三种状态的时候吃的食物也有三种: 汉堡、 西瓜、啤酒
男主:小明 面部表情识别障碍
因此对男主而言,
隐藏状态:女主的心情状态
观测状态:女主吃的食物
隐藏状态数 :N=3
观测状态数: M=3
初始隐状态向量pi:
对照下表看:女主处于各种心情状态的概率,例如女主51%的概率是正常的,36%的概率是开心的,13%的概率是崩溃的
开心 正常 崩溃
0.36 0.51 0.13
状态转移矩阵A:
上一个隐状态到下一个隐状态的转化概率矩阵
对照下表看:在女主上一个状态是开心的条件下,则此刻状态是开心的概率为36.5%,正常的概率为50%,崩溃的概率为13.5%
开心 正常 崩溃
开心 0.365 0.500 0.135
正常 0.250 0.125 0.625
崩溃 0.365 0.265 0.370
发射矩阵B:
隐状态对应的观测状态的概率
对照下表看:在女主是开心的状态下,她吃汉堡的概率是10%,西瓜的概率是20%,啤酒的概率是70%
汉堡 西瓜 啤酒
开心 0.1 0.2 0.7
正常 0.5 0.25 0.25
崩溃 0.8 0.1 0.1
一个HMM模型就由上面描述的隐藏状态数N,观测状态数M,初始隐状态向量pi,状态转移矩阵A,混淆矩阵B五个要素组成。
我们知道了什么是HMM,接下来看HMM是干嘛的,用mahout的HMM库来示例HMM解决哪三类问题,仍然用小红和小明的场景
二、HMM解决的三类问题-mahout示例
现在男主小明开始做任务了,我们用现成的工具mahout来示例
安装指南(仅介绍local版)
wget http://archive.apache.org/dist/mahout/0.9/mahout-distribution-0.9.tar.gz
cd mahout-distribution-0.9/
vim bin/mahout
修改
MAHOUT_JAVA_HOME=/usr/lib/jvm/java-6-openjdk-amd64 (修改为你自己的java所在地址)
MAHOUT_LOCAL=true
任务一:学习(本例中根据女主吃的食物序列,推断一个合适的HMM模型)
输入:观测状态序列——女主吃的食物序列,我们用数字表示对应的食物与心情
0:汉堡
1:西瓜
2:啤酒
0 :崩溃
1:开心
2: 正常
输出:生成一个合适的HMM模型
算法:BaumWelch
echo "0 1 2 2 2 1 1 0 0 2 1 2 1 1 1 1 2 2 2 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 1 1 1 1 2 2 2 2 2 0 2 1 2 0 2 1 2 1 1 0 0 0 1 0 1 0 2 1 2 1 2 1 2 1 1 0 0 2 2 0 2 1 1 0" > hmm-input
输入观测序列后,开始生成HMM模型
bin/mahout baumwelch -i hmm-input(观测序列文件) -o hmm-model(hmm模型文件) -nh 3(隐状态数) -no 3(观测状态数) -e .0001 -m 10
我们看结果
Initial probabilities: 初始隐状态向量pi
0 1 2
0.062295949769082204 0.22250521455286396 0.7151988356780538
Transition matrix:状态转移矩阵A:
0 1 2
0 0.3765444789556002 0.5583673988903969 0.06508812215400292
1 0.3759312048603327 0.2560959620304218 0.36797283310924545
2 0.5383787685979908 0.24752553248847228 0.21409569891353694
Emission matrix: 发射矩阵
0 1 2
0 0.4419117509334424 0.3106990713267408 0.2473891777398168
1 0.20948851558479514 0.2830936761513362 0.5074178082638686
2 0.34341499252552676 0.40310175949497634 0.2534832479794969
任务二:预测(根据上一个任务生成的HMM模型来预测女主后续会吃的东西)
输入:HMM模型
输出:预测后续的观测状态,或者计算给定规则状态序列的概率(这个我们在下一个场景中描述)
算法: ForwardBackward
bin/mahout hmmpredict -m hmm-model(hmm模型文件) -o hmm-predictions (预测结果文件)-l 10(预测多少个后续观测状态)
我们看结果
more hmm-predictions
2 2 0 0 1 2 1 2 2 1
预测女主后续会吃的东西依次为 :啤酒,啤酒,汉堡,汉堡,西瓜,啤酒,西瓜,啤酒,啤酒、西瓜
任务三:编码(根据女主吃的东西,判断女主当前的心情,这个也是男主最关心的任务,女孩的心思你别猜。。。)
输入:HMM模型,观测状态序列
输出:观测状态序列对应的隐藏状态序列
算法:viterbi