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};
};