隐马尔可夫模型_基于hmm模型外汇预测

隐马尔可夫模型_基于hmm模型外汇预测隐马尔科夫模型,HiddenMarcovModel,是可用于标注问题的统计学习模型,描述由隐藏的马尔科夫链随机生成观测序列的过程,属于生成模型,是一种比较重要的机器学习方法,在语音识别等领域有重要的应用。 本文不打算使用书面的一大堆公式来说明,本人对公式无感,能用例子说明的根本不想碰公式,不知道是不是霍金说过,多加一条公式就会损失一大片读者。PS:不管有没有说过了,是这个意思,what

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

隐马尔科夫模型,Hidden Marcov Model是可用于标注问题的统计学习模型,描述由隐藏的马尔科夫链随机生成观测序列的过程,属于生成模型,是一种比较重要的机器学习方法,在语音识别等领域有重要的应用。

 

本文不打算使用书面的一大堆公式来说明,本人对公式无感,能用例子说明的根本不想碰公式,不知道是不是霍金说过,多加一条公式就会损失一大片读者。PS:不管有没有说过了,是这个意思,whatever

 

首先说明一下基本概念,概念来自李航《统计学习方法》第十章【1】

                                           隐马尔可夫模型_基于hmm模型外汇预测
 

   然后根据书中的例子,来具体说明一下HMM的三要素功能

                                              隐马尔可夫模型_基于hmm模型外汇预测
 

 
                                                   隐马尔可夫模型_基于hmm模型外汇预测

 

 书中的例子举得很明白,所以现在应该也了解了隐马尔科夫模型的三个要素了

 

下面通过博客园博主Skyme的博文《一文搞懂HMM》【2】的例子对HMM做一个代码上的解释,需要说明的是,我无意侵犯其知识产权,只是觉得该文举得例子比较好,所以就想拿过来用,毕竟自己画图举例什么的太过麻烦,博文原地址我也给出来了,算是论文里面的引用吧。

 

好的言归正传,我们来看一下HMM需要解决的基本的三个问题,仍然是使用【1】书的内容:

                                         隐马尔可夫模型_基于hmm模型外汇预测

 结合具体的问题,来看一下这三个问题究竟是什么。

 

假设我手里有三个不同的骰子。第一个骰子是我们平常见的骰子(称这个骰子为D6),6个面,每个面(1,2,3,4,5,6)出现的概率是1/6。第二个骰子是个四面体(称这个骰子为D4),每个面(1,2,3,4)出现的概率是1/4。第三个骰子有八个面(称这个骰子为D8),每个面(1,2,3,4,5,6,7,8)出现的概率是1/8。

                                    隐马尔可夫模型_基于hmm模型外汇预测

我们假设开始掷骰子的时候的初始概率是一样的也就是1/3,则初始状态是        PI={1/3,1/3,1/3} 分别对应于D6,D4,D8, 为了方便阐述,我们假设每个状态的转移概率都是1/3,则转移矩阵(也就是上文提到的A矩阵)是
 
                                                   隐马尔可夫模型_基于hmm模型外汇预测
 
                               

 

然后观测结果集合是{1,2, 3, 4,5, 6, 7, 8}

 

每个状态的观测概率矩阵,也就是上文提到的B矩阵

                                                   隐马尔可夫模型_基于hmm模型外汇预测
 到此,PI,A,B 这HMM三要素都到齐了,至于观测序列,则根据具体的问题具体说明

现在模型已经给出了,让我们看一下HMM的三个问题对于这个问题的具体实现

 

[1],概率计算问题:我们已知上面的HMM模型参数,也知道现在的观测序列,现在我们想知道从原始模型到这个观测序列的概率是多少。

现在我们假设现在的观测序列是 1-6-3

                                                                      隐马尔可夫模型_基于hmm模型外汇预测

我现在想知道从之前的模型参数值(PI,A,B)掷骰子到1-6-3的概率有多大

 

解决办法:

如果使用最原始的首先枚举出每个可能的状态集然后分别求概率,然后把这些概率想加,这种办法的效率太低,因此需要使用一种更加好的算法来计算

 

这里使用的是前向算法,计算理论推导在【1】书中有详细的过程,这里使用【2】举得例子

 
隐马尔可夫模型_基于hmm模型外汇预测
 

 

隐马尔可夫模型_基于hmm模型外汇预测
 
 

需要说明的是原文的计算结果似乎是有错误,所以这里讲原文的求和数据省去了,但是方法还是一样计算,这下应该是很明了的的计算方法,就像一条计算链条,多长的结果都能计算出来,下面是代码实现过程:

package com.luchi.hmm;

import com.luchi.hmm.problem1.status;

/*
 * @description
 * 隐马尔科夫模型主要解决的是三个问题
 * 1,预测问题,也就是解码问题,已知模型lambda=(A,B,PI)和观测序列,其给定观测序列条件概率P(I|O)最大的状态序列I
 * 2,概率计算问题:给定模型lambda=(A,B,PI)和观测序列O,计算在该模型lambda下观测序列O出现的概率P(O|lambda)
 * 3,学习问题,已知观测序列O,估计模型lambda=(A,B,PI)的参数
 * 
 * 这里解决的是第二个问题,也就是计算概率问题,这里使用了前向算法
 * @author:luchi 
*/
public class problem2 {
	
	//定义状态转移矩阵
	double [][]trans=new double[][]{
		{0.33,0.33,0.33},
		{0.33,0.33,0.33},
		{0.33,0.33,0.33},
	};
	//状态名称
	enum status{
		D6,
		D4,
		D8
	};
	//总状态数
	int status_length=3;
	//掷骰子事件分别是1,2,3,4,5,6
	
	
	//每个状态下掷骰子事件发生概率
	 double[][] emission_probability = new double[][]{
         {0.167, 0.167, 0.167,0.167,0.167,0.167,0,0},
         {0.250,0.250,0.250,0.250,0,0,0,0},
         {0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125}
         
	 };
	 int activity_length=emission_probability[0].length;
	 //观察序列为
	 int []observation=new int[]{1,6,3};
	 //初始序列
	 double[]start=new double[]{0.33,0.33,0.33};
	 
	 
	 
	//计算出现的概率
	 public void calcuProb(){
		 double[][]midStore=new double[observation.length][status_length];
		 double totalProb=0.0;
		 //初始化第一个概率
		 for(int i=0;i<status_length;i++){
			 double temp=start[i]*emission_probability[i][observation[0]-1];
			 midStore[0][i]=temp;
			 totalProb+=temp;
		 }
		
		 if(observation.length>=1){
			 for(int i=1;i<observation.length;i++){
				 
				 totalProb=0.0;
				 int desPos=observation[i]-1;
				 for(int j=0;j<status_length;j++){
					 double temp=0.0;
					 for(int t=0;t<status_length;t++){
						 temp+=midStore[i-1][t]*trans[t][j]*emission_probability[j][desPos];
					 }
					 midStore[i][j]=temp;
					 totalProb+=temp;
					
				 }
				 System.out.println(totalProb);
				
				 
			 }
			 
		 }
		
	 }
	 
	 public static void main(String[]args){
		 
		 problem2 p=new problem2();
		 p.calcuProb();
	 }

}

 算出来的结果是:0.003082643085456001

 

 

[2],学习问题:知道骰子有几种(隐含状态数量),不知道每种骰子是什么(转换概率),观测到很多次掷骰子的结果(可见状态链),我想反推出每种骰子是什么(转换概率)。

 

也就是不知道上面所描述的HMM模型参数(PI,A,B),现在需根据观测结果O 来反推HMM的参数,这是一个学习过程,也是一个比较重要的问题,一般使用E-M算法进行推导,因为可以把HMM的状态模型看作是未知参数,因此就有了E步和M步,因为本人对EM算法的理解还处于高斯混合模型GMM阶段,并不算很熟悉,所以不打算详细介绍,有兴趣的话可以看【1】的第181-184的推导

 

[3].预测问题:知道HMM的参数(PI,A,B)也已知观测掷骰子的结果O(o1,o2,o3,o4…),现在想知道o1,o2,o3…是由哪些骰子(D6,D4,D8)掷出来的

 

这里使用的是维特比算法,维特比算法实际上是用动态规划求解隐马尔科夫预测问题,也就是使用动态规划求解概率最大路径,这个时候一条路径对应的一个状态序列。下面通过一个例题说明:

 

 
隐马尔可夫模型_基于hmm模型外汇预测

 

 

由此可见,维特比算是其实是一个类似回溯算法一样的计算过程,每个阶段都储存上一个阶段到这个阶段概率最大的状态,然后到达最终态的时候回溯找到状态序列

 

还是以文章的掷骰子为题为例,HMM的模型(PI,A,B)都不变,现在观察到的点数(观测序列)是1 6 3 5 2 7 3 5 2 4),然后我们根据维特比算法来求解最大概率的掷到这个点数序列的状态集

(也就是是哪个筛子掷的的集合),根据上图例10.3的维特比算法的说明可以将这个问题用以下代码实现

package com.luchi.hmm;

/*
 * @description
 * 隐马尔科夫模型主要解决的是三个问题
 * 1,预测问题,也就是解码问题,已知模型lambda=(A,B,PI)和观测序列,其给定观测序列条件概率P(I|O)最大的状态序列I
 * 2,概率计算问题:给定模型lambda=(A,B,PI)和观测序列O,计算在该模型lambda下观测序列O出现的概率P(O|lambda)
 * 3,学习问题,已知观测序列O,估计模型lambda=(A,B,PI)的参数
 * 
 * 这个首先解决的是第一个问题,也就是预测问题,主要有两种算法,一个是近似算法,一个是维特比算法,这里使用了viterbi算法
   @author:luchi
 * */
public class problem1 {
	
	//定义状态转移矩阵
	double [][]trans=new double[][]{
		{0.33,0.33,0.33},
		{0.33,0.33,0.33},
		{0.33,0.33,0.33},
	};
	//状态名称
	enum status{
		D6,
		D4,
		D8
	};
	//总状态数
	int status_length=3;
	//掷骰子事件分别是1,2,3,4,5,6
	
	
	//每个状态下掷骰子事件发生概率
	 double[][] emission_probability = new double[][]{
         {0.167, 0.167, 0.167,0.167,0.167,0.167,0,0},
         {0.250,0.250,0.250,0.250,0,0,0,0},
         {0.125,0.125,0.125,0.125,0.125,0.125,0.125,0.125}
         
	 };
	 int activity_length=emission_probability[0].length;
	 //观察序列为
	 int []observation=new int[]{1,6,3,5,2,7,3,5,2,4};
	 //初始序列
	 double[]start=new double[]{0.33,0.33,0.33};
	 
	 
	 
	 //维特比算法求解
	 public void viterbi(){
		 //初始化存储中间矩阵
		 double[][]midStore=new double[observation.length][status_length];
		 int[][]traceBack=new int[observation.length][status_length];
		 //初始化第一个数据
		 for(int i=0,desPos=observation[0]-1;i<status_length;i++){
			 
			 midStore[0][i]=start[0]*emission_probability[i][desPos];
		 }
		 //从第二个观测序列开始计算
		 for(int i=1;i<observation.length;i++){
			 
			 int desPos=observation[i]-1; //注意数组是从0开始的,而不是1
			 for(int j=0;j<status_length;j++){

				 double maxProb=-1;
				 int traceStatus=0;
				 //比较前面的序列
				 for(int t=0;t<status_length;t++){
					 double tempProb=midStore[i-1][t]*trans[t][j]*emission_probability[j][desPos];
					 if(tempProb>maxProb){
						 maxProb=tempProb;
						 traceStatus=t;
					 }
					 
				 }
				 midStore[i][j]=maxProb;
				 traceBack[i][j]=traceStatus;
			 }
		 }
		 //比较最后一个阶段的最大概率
		 int max_end_status=0;
		 double max_end_prob=-1;
		 for(int end_status=0;end_status<status_length;end_status++){
			 
			 double prob=midStore[observation.length-1][end_status];
			 if(prob>max_end_prob){
				 
				 max_end_prob=prob;
				 max_end_status=end_status;
			 }
		 }
		 //回溯输出最大概率状态模型
		 int []path=new int[observation.length];
		 path[observation.length-1]=max_end_status;
		 int curStatus=max_end_status;
		 for(int i=observation.length-1;i>=1;i--){
			 
			 int preStatus=traceBack[i][curStatus];
			 path[i-1]=preStatus;
			 curStatus=preStatus;
		 }
		 for(int i=0;i<path.length;i++){
			 System.out.println(status.values()[path[i]]);
		 }
		 
	 }
	 
	 public static void main(String[]args){
		 
		 problem1 p=new problem1();
		 p.viterbi();
	 }

}

 预测的结果是:D4 D6 D4 D6 D4 D8 D4 D6 D4 D4

 

恩,这就是我对Hidden Morcov Model的浅见,不足之处还望指正

 

参考文献:

【1】李航 《统计学习方法》

【2】skyme 《一文搞懂HMM》 http://www.cnblogs.com/skyme/p/4651331.html#commentform
 

  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 55.6 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 135.7 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 50.8 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 68.3 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 82.1 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 7 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 5.4 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 5.4 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 10.1 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 38.1 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 128.9 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 135.4 KB
  • 隐马尔可夫模型_基于hmm模型外汇预测
  • 大小: 203.6 KB
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/187570.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Linux安装Android Sdk「建议收藏」

    Linux安装Android Sdk「建议收藏」在使用Jenkins+Gitlab集成自动化打包时,遇到Linux缺少AndroidSdk环境的问题,单独记录一下安装过程。sdk安装方式常规思路,下载sdk,安装之后修改环境。但是发现,网络上已经没有了sdk的下载资源,有的也只是很老的版本。查看Android开发文档——sdkmanager的使用指南,发现可以使用sdkmanager这个命令行工具进行下载。下载sdkmanager工具包官网下载页最底部-命令行工具下载,找到Linux平台的工具包使用wget下载到服务器wget-P/h

  • linux安装svn服务器的两种方式(转载)「建议收藏」

    linux安装svn服务器的两种方式(转载)「建议收藏」操作环境:CentOS7.264位第一种:采用压缩包安装:比如你们公司服务器上安装软件有自己的规定,一般会采用压缩包安装。第一步:SVN服务器端压缩包下载下载地址:http://mirrors.cnnic.cn/apache/subversion/我下载的是subversion-1.8.19版本,下载好的压缩包置于目录/usr/local/java/svn下(根据大家实际需要自行选择存放目录)。第二步:解压,进入解压后的文件在/usr/local/java/svn目录下执行下面两个命令:

    2022年10月17日
  • CentOS 7 安装 LNMP 环境(PHP7 + MySQL5.7 + Nginx1.10)

    CentOS 7 安装 LNMP 环境(PHP7 + MySQL5.7 + Nginx1.10)

    2021年10月18日
  • pstack命令_压缩命令 linux

    pstack命令_压缩命令 linuxpstack命令可显示每个进程的栈跟踪。pstack命令必须由相应进程的属主或root运行。可以使用pstack来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的PID。pstree以树结构显示进程pstree-proot|grepphp-fpmroot为工作用户,-p为显示进程识别码,ps-Lf父进程号pstackPID号 转载…

  • mysql 删除一条数据sql语句_sql删除语句[通俗易懂]

    mysql 删除一条数据sql语句_sql删除语句[通俗易懂]sql删除语句一般简单的删除数据记录用delete就行了,但是如何要删除复杂的外键就不是一条delete删除来实例的,我们本文章先讲一下delete删除,然后再告诉你利用触发器删除多条记录多个表。删除数据库中的数据sql删除语句一般简单的删除数据记录用delete就行了,但是如何要删除复杂的外键就不是一条delete删除来实例的,我们本文章先讲一下delete删除,然后再告诉你利用触发器删除多…

  • 面试题vue双向绑定原理_vue路由面试题

    面试题vue双向绑定原理_vue路由面试题引言:vue的双向绑定原理简单来说就是:vue内部使用object.defineProperty方法给所有数据加上getter和setter方法,在数据发生改变时发布消息给订阅者Watcher,触发响应的监听回调。object.defineProperty是JS里一个重要的方法,vue的双向绑定ES6里一些方法都是靠它实现的。如图所示zuoerobject.defineProperty…

    2022年10月17日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号