简单说维特比算法 - python实现
动态规划求最短路径算法,与穷举法相比优点在于大大降低了时间复杂度;
- 假如从起点A到终点S的最短路径Road经过点B1,那么从起点A到B1的最短路径的终点就是B1,否则如果存在一个B2使得A到B2的距离小于B1,那么起点A到终点S的最短路径Road就不应该经过B1,而应该经过B2,这显示是矛盾的,证明了满足最优性原理;
- 假设从A到S需要经过N个时刻,每个时刻有M个状态(B1,B2...BM),那么我们只需要记录对应每个状态的最短路径即可,这样在任意时刻,只需要考虑非常有限的几种最短路径即可(取决于该时刻对应的状态个数),且不需要向上考虑之前的时刻,也就是不存在多维条件问题;
- 结合以上两点,假设当前我们需要从时刻i到i+1时,从起始点S到时刻i的所有最短路径已经找出并记录到时刻i的所有状态上了,那么我们只需要考虑没时刻i的所有状态的最短路径连接到时刻i+1的所有状态上后得到的对应每个状态的最短路径并记录到状态中即可(后续计算与时刻i已无关);
- 循环3,知道终点时刻为止,此时终点的所有状态中都保存了一个最短路径,取其中最短即可(或者说最大概率);
import sys
states = ('Rainy', 'Sunny', 'Snowy', 'Thunder')
observations = ('walk', 'playSnow', 'clean', 'clean', 'shop', 'clean', 'walk', 'shop', 'clean', 'playSnow', 'scare', 'walk')
start_probability = {'Rainy': 0.4, 'Sunny': 0.3, 'Snowy': 0.2, 'Thunder': 0.1}
transition_probability = {
'Rainy' : {'Rainy': 0.5, 'Sunny': 0.2, 'Snowy': 0.15, 'Thunder': 0.15},
'Sunny' : {'Rainy': 0.1, 'Sunny': 0.5, 'Snowy': 0.3, 'Thunder': 0.1},
'Snowy' : {'Rainy': 0.4, 'Sunny': 0.2, 'Snowy': 0.3, 'Thunder': 0.1},
'Thunder' : {'Rainy': 0.4, 'Sunny': 0.2, 'Snowy': 0.1, 'Thunder': 0.3},
}
emission_probability = {
'Rainy' : {'walk': 0.1, 'shop': 0.3, 'clean': 0.4, 'playSnow':0.1, 'scare':0.1},
'Sunny' : {'walk': 0.4, 'shop': 0.2, 'clean': 0.1, 'playSnow':0.1, 'scare':0.1},
'Snowy' : {'walk': 0.2, 'shop': 0.1, 'clean': 0.2, 'playSnow':0.4, 'scare':0.1},
'Thunder' : {'walk': 0.1, 'shop': 0.1, 'clean': 0.4, 'playSnow':0.1, 'scare':0.3},
}
def viterbi_output(states,observations,start_probability,transition_probability,emission_probability):
"""
states:隐状态
observations:观察状态
start_probability:初始概率
transition_probability:转换概率(某个隐状态转换到某个隐状态)
emission_probability:发射概率(某个隐状态转换到某个观察状态)
算法思路:
目的:根据三天的观察状态,计算最有可能的三天天气隐状态
根据:得到最后一天的概率后,其中概率最大的即表示该条状态链是最有可能的隐状态链
方法:
第一天概率:隐状态的初始概率*该状态到第一天的观察状态的发射概率
其他天概率:前一天隐状态的概率*前一天隐状态到当天隐状态的转换概率*当天隐状态到当天观察状态的发射概率
关键:
1.并不需要保存每一天的状态,实际上每天的循环计算中只会用到前一天的数据即可(因此V这个变量实际上长度为2即可)
2.路径的保存
"""
V = [{}]#V[时间][天气]=概率
path = {}#保存路径
#第一天
for state in states:
V[0][state]=start_probability[state]*emission_probability[state][observations[0]]
path[state]=[state]
print "第一天概率估计:(天气:%s,概率:%f)" % (state,V[0][state])
#其他时间
for day in range(1,len(observations)):
print "第%d天概率估计:" % (day+1)
V.append({})
newPath = {}
for day_s in states:
(prop,state) = max([V[day-1][s]*transition_probability[s][day_s]*emission_probability[day_s][observations[day]],s]for s in states)
V[day][day_s]=prop
newPath[day_s] = path[state]+[day_s]
print "\t假设当前隐状态为:%s,得到最大概率:%f,对应前一天隐状态:%s" % (day_s,prop,state)
path = newPath
return max([(V[len(observations)-1][prop],path[prop])for prop in V[len(observations)-1]])
if __name__ == '__main__':
#argv[1]表示计算观察的天数
print viterbi_output(states,observations[:int(sys.argv[1])],start_probability,transition_probability,emission_probability)
时间长度为5天时的运行结果图:

简单说维特比算法 - python实现的更多相关文章
- 维特比算法Python实现
前言 维特比算法是隐马尔科夫问题的一个基本问题算法.维特比算法解决的问题是已知观察序列,求最可能的标注序列. 什么是维特比算法? 维特比算法尽管是基于严格的数学模型的算法,但是维特比算法毕竟是算法,因 ...
- 维特比算法(Viterbi)及python实现样例
维特比算法(Viterbi) 维特比算法 维特比算法shiyizhong 动态规划算法用于最可能产生观测时间序列的-维特比路径-隐含状态序列,特别是在马尔可夫信息源上下文和隐马尔科夫模型中.术语“维特 ...
- 【机器学习】【条件随机场CRF-2】CRF的预测算法之维特比算法(viterbi alg) 详解 + 示例讲解 + Python实现
1.CRF的预测算法条件随机场的预测算法是给定条件随机场P(Y|X)和输入序列(观测序列)x,求条件概率最大的输出序列(标记序列)y*,即对观测序列进行标注.条件随机场的预测算法是著名的维特比算法(V ...
- Java实现:抛开jieba等工具,写HMM+维特比算法进行词性标注
一.前言:词性标注 二.经典维特比算法(Viterbi) 三.算法实现 四.完整代码 五.效果演示: 六.总结 一.前言:词性标注 词性标注(Part-Of-Speech tagging, POS t ...
- Viterbi 算法 Python实现 [NLP学习一]
最近思考了一下未来,结合老师的意见,还是决定挑一个方向开始研究了,虽然个人更喜欢鼓捣.深思熟虑后,结合自己的兴趣点,选择了NLP方向,感觉比纯粹的人工智能.大数据之类的方向有趣多了,个人还是不适合纯粹 ...
- 维特比算法(Viterbi Algorithm)
寻找最可能的隐藏状态序列(Finding most probable sequence of hidden states) 对于一个特殊的隐马尔科夫模型(HMM)及一个相应的观察序列,我们常常希望 ...
- 三种排序算法python源码——冒泡排序、插入排序、选择排序
最近在学习python,用python实现几个简单的排序算法,一方面巩固一下数据结构的知识,另一方面加深一下python的简单语法. 冒泡排序算法的思路是对任意两个相邻的数据进行比较,每次将最小和最大 ...
- 简单易学的机器学习算法——EM算法
简单易学的机器学习算法——EM算法 一.机器学习中的参数估计问题 在前面的博文中,如“简单易学的机器学习算法——Logistic回归”中,采用了极大似然函数对其模型中的参数进行估计,简单来讲即对于一系 ...
- pageRank算法 python实现
一.什么是pagerank PageRank的Page可是认为是网页,表示网页排名,也可以认为是Larry Page(google 产品经理),因为他是这个算法的发明者之一,还是google CEO( ...
随机推荐
- mysql+redis缓存策略常见的错误
什么时候应该更新缓存 应该是从数据库读取数据后,再更新缓存,从缓存读取到数据,就不需要再重新写缓存了,一个常见的错误是,每次访问接口都更新缓存,这样的话,如果接口一直有流量,那么db中的数据,就一直没 ...
- class.getFields和class.getDeclareFields的区别
class.getFields的定义 返回类提供的public域包括超类的共有变量; 注: 是public,我们平时定义变量一般用的private,如果用getFields是不会获得. class.g ...
- AJAX二
二.简单的dom操作 2.使用js的dom获取页面数据 由于ajax不使用form 而form具有自动收集数据的功能. 不使用form,就需要使用dom手写代码收集数据 ①获得承载数据的元素对象 &l ...
- mysql小白系列_07 锁与事务
1.MySQL参数autocommit生产环境设1还是0?为什么? 2.MySQL参数tx_isolation生产环境上大多数是设什么值,为什么? 3.与MySQL锁相关的有哪些因素? 1.MySQL ...
- mysql日志体系大盘点
MySql日志文件主要包含:错误日志.慢查询日志.事务日志.二进制日志等 Mysql的日志配置可以通过命令 show global variables like '%log%'; 执行的结果如下 &q ...
- A+B Coming(hdu1720)
思考:十六进制的输入->%x,定义时用int.要变成十进制输出,直接在输出时用->%d. #include<stdio.h> int main() { int A,B; cha ...
- 换个角度学习ASP.NET Core中间件
中间件真面目 关于ASP.NET Core中间件是啥,简单一句话描述就是:用来处理HTTP请求和响应的一段逻辑,并且可以决定是否把请求传递到管道中的下一个中间件! 上面只是概念上的一种文字描述,那问题 ...
- 【转】Mac系统常用快捷键大全
Mac系统常用快捷键大全 通用 Command是Mac里最重要的修饰键,在大多数情况下相当于Windows下的Ctrl.所以以下最基本操作很好理解: Command + Z 撤销 Command + ...
- httppost的用法
一,案例一 定义了一个list,该list的数据类型是NameValuePair(简单名称值对节点类型),这个代码多处用于Java像url发送Post请求.在发送post请求时用该list来存放参数. ...
- Druid数据库连接池的使用
Druid 阿里提供的数据库连接池,集以上连接池优点于一身,开发使用此连接池 使用配置文件方式获取Druid数据库连接池 TestDruid package com.aff.connection; ...