最近在看“统计学习方法”,第十章讲的“隐马尔可夫模型”,方法理论比较基础,但是应用很广泛。
具体理论知识可以参考:https://blog.csdn.net/xmu_jupiter/article/details/50956389
以下是我自己为了方便复习回顾,整理的PPT来讲解这章的内容,下面是前向后向算法:
下面是用C ++实现前向后向算法的代码:
//
// main.cpp
// FB Algorithm
//
// Created by showlo on 2018/7/29.
// Copyright © 2018年 showlo. All rights reserved.
//
#include <iostream>
#include <vector>
#include <map>
#define Maxsize_N 100
#define Maxsize_M 100
#define Maxsize_T 100
using namespace std;
int main(int argc, const char * argv[]) {
map<string,int> Q;
Q["Fair"] = 0;
Q["Loaded"] = 1;
map<string,int> V;
V["Head"] = 0;
V["Tail"] = 1;
//vector<string> Q={"Fair","Loaded"};
//vector<string> V={"Head","Tail"};
vector<string> O;
int N,M;
double p;
cout<<"请输入M N:"<<endl;
cin>>N>>M;
double A[Maxsize_N][Maxsize_N]={.0};
double B[Maxsize_N][Maxsize_M]={.0};
double PI[Maxsize_N]={.0};
double alpha[Maxsize_T][Maxsize_N]={.0};
double beta[Maxsize_T][Maxsize_N]={.0};
cout<<"请输入状态转移概率矩阵A:"<<endl;
for (int i=0; i<N; i++) {
for (int j=0; j<N; j++) {
cin>>p;
A[i][j]=p;
}
}
cout<<"请输入B:"<<endl;
for (int i=0; i<N; i++) {
for (int j=0; j<M; j++) {
cin>>p;
B[i][j]=p;
}
}
cout<<"请输入PI:"<<endl;
for (int i=0; i<N; i++) {
cin>>p;
PI[i]=p;
}
int T;
cout<<"请输入时间序列长度T:"<<endl;
cin>>T;
cout<<"请输入观测序列并以“end”结束:"<<endl;
for (int i=1; i<=T; i++) {
string o;
cin>>o;
O.push_back(o);
}
cout<<"前向算法:计算alpha:"<<endl;
//Initialization
string o1=O[0];
for (int i=0; i<N; i++) {
alpha[1][i]=PI[i]*B[i][V[o1]];
cout<<"alpha1 "<<i<<":"<<alpha[1][i]<<endl;
}
//Induction
for (int t=2; t<=T; t++) {
string o = O[t-1];
for (int i=0; i<N; i++) {
double a=.0;
for (int k=0; k<N; k++)
a+=alpha[t-1][k]*A[k][i];
alpha[t][i]=a*B[i][V[o]];
cout<<"alpha "<<t<<" "<<i<<":"<<alpha[t][i]<<endl;
}
}
//Termination
double P=.0;
for (int i=0; i<N; i++)
P+=alpha[T][i];
cout<<"Result : "<<P<<endl;
/*** *** **** ***** ****** **** **** ***/
cout<<"后向算法:计算beta:"<<endl;
//Initialization
string oT=O[T-1];
for (int i=0; i<N; i++) {
beta[T][i]=1.0;
cout<<"beta1 "<<i<<":"<<beta[T][i]<<endl;
}
//Induction
for (int t=T-1; t>=1; t--) {
string o = O[t];
for (int i=0; i<N; i++) {
double b=.0;
for (int k=0; k<N; k++)
b+=A[i][k]*B[k][V[o]]*beta[t+1][k];
beta[t][i]=b;
cout<<"beta "<<t<<" "<<i<<":"<<beta[t][i]<<endl;
}
}
//Termination
double P1=.0;
string o=O[0];
for (int i=0; i<N; i++)
P1+=PI[i]*B[i][V[o]]*beta[1][i];
cout<<"Result : "<<P1<<endl;
return 0;
}
PPT中例子的测试: