【ML】隐马尔可夫模型(HMM)——前向后向算法(C++实现)

最近在看“统计学习方法”,第十章讲的“隐马尔可夫模型”,方法理论比较基础,但是应用很广泛。

具体理论知识可以参考: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中例子的测试:

猜你喜欢

转载自blog.csdn.net/biongbiongdou/article/details/81272596