统计学习方法 第10章 习题

10.1,2,3

三题我都是用程序求解:hmm.c (该程序没有学习算法)

/**********************************
文件名称:hmm.c 
	
文件功能:统计第10章 例题 

作者:nkenen 
	
时间:2020年5月6日 
***********************************/

#include "hmm.h"

HMM::HMM(int *Oin,int Tin){ 
	this->O = new vector<int>(Oin,Oin+Tin);
	this->T= Tin;
	
	this->Alpha = new double*[T];
	for(int t=0;t<T;t++){
		Alpha[t] = new double[Q_len];
	}
	this->Beta = new double*[T];
	for(int t=0;t<T;t++){
		Beta[t] = new double[Q_len];
	}
	this->Delta = new double*[T];
	for(int t=0;t<T;t++){
		Delta[t] = new double[Q_len];
	}
	this->Psi = new int*[T];
	for(int t=0;t<T;t++){
		Psi[t] = new int[Q_len];
	}
	this->out_q = new int[T];
}

HMM::~HMM(){
	delete []O; 
	for(int t=0;t<T;t++){
		delete []Beta[t];;
	}
	delete []Beta;
	for(int t=0;t<T;t++){
		delete []Alpha[t];;
	}
	delete []Alpha;
	for(int t=0;t<T;t++){
		delete []Delta[t];;
	}
	delete []Delta;
	for(int t=0;t<T;t++){
		delete []Psi[t];;
	}
	delete []Psi;
	
	delete out_q;
}

double HMM::forword(){
	double sum =0.0;
	for(int i =0;i<Q_len;i++){
		Alpha[0][i] = pi[i]*B[i][O->at(0)];
		cout << Alpha[0][i] << " ";
	}
	cout << endl;
	for(int t =1;t<T;t++){	
		for(int j =0;j<Q_len;j++){
			sum = 0.0;
			for(int i =0;i<Q_len;i++){
				sum += Alpha[t-1][i]*A[i][j];
			}	
			Alpha[t][j] = sum*B[j][O->at(t)];
			cout << Alpha[t][j] << " ";
		}
		cout << endl;
	}
	sum = 0.0;
	for(int i =0;i<Q_len;i++){
		sum += Alpha[T-1][i];
	}
	cout << "前向概率为:" << sum << endl;
}

double HMM::backword(){
	double sum = 0.0;
	for(int i =0;i<Q_len;i++){
		Beta[T-1][i] = 1;
		cout << Beta[T-1][i] << " ";
	}
	cout << endl;
	for(int t=T-2;t>=0;t--){	
		for(int i=0;i<Q_len;i++){
			sum = 0.0;
			for(int j=0;j<Q_len;j++){
				sum += Beta[t+1][j]*A[i][j]*B[j][O->at(t+1)];
			}
			Beta[t][i] = sum;	
			cout << Beta[t][i] << " ";
		}
		cout << endl;
	}
	sum = 0.0;
	for(int i =0;i<Q_len;i++){
		sum += Beta[0][i]*pi[i]*B[i][O->at(0)];
	}
	cout << "后向概率为:" << sum << endl;
}

double HMM::Comput_gamma(int t,int qx){
	double sum=0.0;
	for(int i =0;i<Q_len;i++){
		sum += Alpha[t][i]*Beta[t][i];
	}
	return Alpha[t][qx]*Beta[t][qx]/sum;
}

void HMM::vetbipredict(){
	double max_prob = 0.0;
	int q_max = 0; 
	
	for(int q=0;q<Q_len ;q++ ){
		Delta[0][q]= this->pi[q]*this->B[q][O->at(0)];
	}
	for(int t =1;t<T;t++){
		for(int q=0;q<Q_len ;q++){
			max_prob = 0.0;
			q_max = 0;
			for(int q_pre=0;q_pre<Q_len ;q_pre++ ){
				double prob = Delta[t-1][q_pre]*A[q_pre][q];
				q_max = max_prob<prob?q_pre:q_max;
				max_prob = max_prob<prob?prob:max_prob;
			}
			Delta[t][q] = max_prob*B[q][O->at(t)];
			Psi[t-1][q] = q_max;
		}	
	}
	
	max_prob = 0.0;
	q_max = 0;
	for(int q=0;q<Q_len ;q++ ){
		out_q[T-1] = max_prob<Delta[T-1][q]?q:out_q[T-1];
		max_prob = max_prob<Delta[T-1][q]?Delta[T-1][q]:max_prob;
	}
	for(int t =T-1;t>0;t--){
		 out_q[t-1] = Psi[t-1][out_q[t]];
	}
	cout << "最大路径概率:" << max_prob << endl; 
	for(int t=0;t<T;t++){
		cout << "q"<<t+1<<": "<<out_q[t]<< " "; 
	}
}

int main(){
//所有数据都是从0开始
	int O[4] = {0,1,0,1};
	HMM hmm(O,4); 
	hmm.forword();
	hmm.backword();
	hmm.vetbipredict();
	
	
	cout << endl << endl;
    //习题2中将A,B,pi的数值改为书中数据
	int O1[8] = {0,1,0,0,1,0,1,1};
	HMM hmm1(O1,8); 
	hmm1.forword();
	hmm1.backword();
	cout << hmm1.Comput_gamma(3,2)<<endl;
	hmm1.vetbipredict();
	return 0;
}

hmm.h

/**********************************
文件名称:hmm.h 
	
文件功能:统计第10章 例题 

作者:nkenen 
	
时间:2020年5月6日 
***********************************/

#include <iostream>
#include <math.h>
#include <vector>

using namespace std;


class HMM{
public:
	HMM(int *O,int T);
	~HMM();		
	double forword();
	double backword();
	double Comput_gamma(int t,int qx);
	void vetbipredict();

private:
	vector<int> *O;
	int T;
	int Q_len = 3;
	int V_len = 2;
	double **Alpha;
	double **Beta;
	double **Delta;
	int **Psi;
	int *out_q;
	double A[3][3] = {{0.5,0.2,0.3},
	                  {0.3,0.5,0.2},
					  {0.2,0.3,0.5}};
	double B[3][2] = {{0.5,0.5},{0.4,0.6},{0.7,0.3}};
	double pi[3] = {0.2,0.4,0.4};
		
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值