HMM动态手势识别4——HMM训练算法1

训练的主方法

package HMM_test01;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.Iterator;

import HMM_test02.HMM;
import MySQL.ChaZhao;

//HMM训练的主方法
public class HMM_main {

	public static void main(String[] args) {
		
		//得到训练数据
		ArrayList<float[]> dataSet;  
		Connection conn1 = ChaZhao.getconn();
		dataSet = ChaZhao.select(conn1);
        ChaZhao.close();
		
        Iterator it = dataSet.iterator();
        int num =0;
        
        float[] data1 = new float[3];
        int[] data = new int[2100];//30*70 = 2100 训练70组手势数据 每组手势数据中有30帧数据
        
        while(it.hasNext()){
        	data1 = (float[]) it.next();
        	data[num] = (int) data1[0];
        	num++;
        }
        

		//pi为第一个隐状态为个个隐状态的概率 本项目状态数为6,取对数后的概率
		
		//先验转移概率矩阵A,概率取对数
		
		//先验状态下的观测分布概率B,概率取对数
		
		//HMM_test hmm = new HMM_test(6, 16);//状态集合大小  观测集合大小,特征向量1
        //HMM_test hmm = new HMM_test(6, 14);//特征向量2
        HMM_test hmm = new HMM_test(6, 10);//特征向量3,4
		//开始训练
        hmm.randomInitAllParameters();//对pi、A、B进行随机赋值
        //输出训练前的pi A B的值
        System.out.println("pi:");
        for(int i=0;i<hmm.pi.length;i++){
        	System.out.print(hmm.pi[i]+",");
        }
        
        System.out.println("\nA:");
        for(int i=0;i<hmm.transferProbability1.length;i++){
        	for(int j=0;j<hmm.transferProbability1[i].length;j++){
        		System.out.print(hmm.transferProbability1[i][j]+",");
        	}
        	System.out.println();
        }
        System.out.println("B:");
        for(int i=0;i<hmm.emissionProbability.length;i++){
        	for(int j=0;j<hmm.emissionProbability[i].length;j++){
        		System.out.print(hmm.emissionProbability[i][j]+",");
        	}
        	System.out.println();
        }
        //训练
		hmm.train(data, -1, 0.5);
		
		
		System.out.println("训练之后");
		System.out.println("pi:");
        for(int i=0;i<hmm.pi.length;i++){
        	System.out.print(hmm.pi[i]+",");
        }
        System.out.println("\nA:");
        for(int i=0;i<hmm.transferProbability1.length;i++){
        	for(int j=0;j<hmm.transferProbability1[i].length;j++){
        		System.out.print(hmm.transferProbability1[i][j]+",");
        	}
        	System.out.println();
        }
        System.out.println("B:");
        for(int i=0;i<hmm.emissionProbability.length;i++){
        	for(int j=0;j<hmm.emissionProbability[i].length;j++){
        		System.out.print(hmm.emissionProbability[i][j]+",");
        	}
        	System.out.println();
        }
		
		
		
		/*验证pi A B的随机初始化情况,初始化成功
		System.out.println("pi:");
		for(int i=0;i<hmm.stateNum;i++){
			System.out.print(hmm.pi[i]+" ");
		}
		System.out.println("\nA:");
		for(int i = 0; i < hmm.stateNum; i++) {
			for(int j = 0; j < hmm.stateNum; j++) {
				System.out.print(hmm.transferProbability1[i][j]+" ");
			}
			System.out.println();
		}
		System.out.println("\nB:");
		for(int i = 0; i < hmm.stateNum; i++) {
			for(int j = 0; j < hmm.observationNum; j++) {
				System.out.println(hmm.emissionProbability[i][j]);
			}
			System.out.println();
		}
		*/
	}

}

HMM算法的实现方法

package HMM_test01;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Logger;

public class HMM_test {
	private double precision = 1e-7;
	/**
	 * 训练数据长度
	 */
	private int sequenceLen;
	public Logger logger = Logger.getLogger(UnsupervisedFirstOrderGeneralHMM.class.getName());
	/**初始状态概率**/
	protected double[] pi;
	/**转移概率**/
	protected double[][] transferProbability1;
	/**发射概率**/
	protected double[][] emissionProbability;
	/**定义无穷大**/
	public static final double INFINITY = (double) -Math.pow(2, 31);
	/**状态值集合的大小**/
	protected int stateNum;
	/**观测值集合的大小**/
	protected int observationNum;
	//构造函数
	public HMM_test() {
		super();
	}
	public HMM_test(int stateNum, int observationNum) {
		this.stateNum = stateNum;
		this.observationNum = observationNum;
		initParameters();
	}
	
	public void initParameters() {//初始化赋0,还未赋值
		//初始概率随机初始化
		pi = new double[stateNum];
		transferProbability1 = new double[stateNum][stateNum];//A[状态数][状态数]
		emissionProbability = new double[stateNum][observationNum];//B[状态数][观测序列数]
		//概率初始化为0
		for(int i = 0; i < stateNum; i++) {
			pi[i] = INFINITY;
			for(int j = 0; j < stateNum; j++) {
				transferProbability1[i][j] = INFINITY;
			}
			for(int k = 0; k < observationNum; k++) {
				emissionProbability[i][k] = INFINITY;
			}
		}
	}
	
	public void train(int[] x, int maxIter, double precision) {
		this.sequenceLen = x.length;
		baumWelch(x, maxIter, precision);
	}
	
	protected void baumWelch(int[] x, int maxIter, double precision) {
		int iter = 0;   //记录迭代次数
		double oldMaxError = 0;
		if(maxIter <= 0) {
			maxIter = Integer.MAX_VALUE;//2147483647
		}
		//初始化各种参数
		double[][] alpha = new double[sequenceLen][stateNum];//训练数据长度   状态集合的大小
		double[][] beta = new double[sequenceLen][stateNum];
		double[][] gamma  = new double[sequenceLen][stateNum];
		double[][][] ksi = new double[sequenceLen][stateNum][stateNum];
		while(iter < maxIter) {
			logger.info("\niter"+iter+"...");
			long start = System.currentTimeMillis();//从1970年1月1日0时到现在的毫秒数
			//计算各种参数,为更新模型参数做准备,对应EM中的E步
			calcAlpha(x, alpha);
			calcBeta(x, beta);
			calcGamma(x, alpha, beta, gamma);
			calcKsi(x, alpha, beta, ksi);
			//更新参数,对应EM中的M步
			double[][] oldA = generateOldA();//保存旧的参数A
			//double[][] oldB = generateOldB();
			//double[] oldPi = pi.clone();
			updateLambda(x, gamma, ksi); //更新λ(pi,A,B)
			//double maxError = calcError(oldA, oldPi, oldB);
			double maxError = calcError(oldA, null, null);
			logger.info("max_error:"+maxError);
			if(maxError < precision || (Math.abs(maxError-oldMaxError)) < this.precision) {
				logger.info("参数已收敛....");
				break;
			}
			oldMaxError = maxError;
			iter++;
			long end = System.currentTimeMillis();
			logger.info("本次迭代结束,耗时:"+(end - start)+"毫秒");
		}
		logger.info("最终参数:");
		logger.info("pi:"+Arrays.toString(pi));
		logger.info("A:");
		for(int i = 0; i < transferProbability1.length; i++) {
			logger.info(Arrays.toString(transferProbability1[i]));
		}
	}
	
	protected void calcAlpha(int[] x, double[][] alpha) {
		logger.info("计算alpha...");
		long start = System.currentTimeMillis();
		//double[][] alpha = new double[sequenceLen][stateNum];
		//alpha t=0初始值
		for(int i = 0; i < stateNum; i++) {
			alpha[0][i] = pi[i] + emissionProbability[i][x[0]];//emission... 发射概率矩阵
		}
		double[] logProbaArr = new double[stateNum];
		for(int t = 1; t < sequenceLen; t++) {
			for(int i = 0; i < stateNum; i++) {
				for(int j = 0; j < stateNum; j++) {
					logProbaArr[j]	= (alpha[t -1][j] + transferProbability1[j][i]);
				}
				alpha[t][i] = logSum(logProbaArr) + emissionProbability[i][x[t]];
			}
		}
		long end = System.currentTimeMillis();
		logger.info("计算结束...耗时:"+ (end - start) +"毫秒");
		//return alpha;
	}
	
	protected void calcBeta(int[] x, double[][] beta) {
		logger.info("计算beta...");
		long start = System.currentTimeMillis();
		//double[][] beta = new double[sequenceLen][stateNum];
		//初始概率beta[T][i] = 1
		for(int i = 0; i < stateNum; i++) {
			beta[sequenceLen-1][i] = 1;
		}
		double[] logProbaArr = new double[stateNum];
		for(int t = sequenceLen -2; t >= 0; t--) {
			for(int i = 0; i < stateNum; i++) {
				for(int j = 0; j < stateNum; j++) {
					logProbaArr[j] = transferProbability1[i][j] + 
							emissionProbability[j][x[t+1]] +
							beta[t + 1][j];
				}
				beta[t][i] = logSum(logProbaArr);
			}
		}
		long end = System.currentTimeMillis();
		logger.info("计算结束...耗时:"+ (end - start) +"毫秒");
		//return beta;
	}
	
	protected void calcGamma(int[] x, double[][] alpha, double[][] beta, double[][] gamma) {
		logger.info("计算gamma...");
		long start = System.currentTimeMillis();
		//double[][] gamma  = new double[sequenceLen][stateNum];
		for(int t = 0; t < sequenceLen; t++) {
			//分母需要求LogSum
			for(int i = 0; i < stateNum; i++) {
				gamma[t][i] = alpha[t][i] + beta[t][i];
			}
			double logSum = logSum(gamma[t]);//分母部分
			for(int j = 0; j < stateNum; j++) {
				gamma[t][j] = gamma[t][j] - logSum;
			}
		}
		long end = System.currentTimeMillis();
		logger.info("计算结束...耗时:"+ (end - start) +"毫秒");
		//return gamma;
	}
	
	protected void calcKsi(int[] x, double[][] alpha, double[][] beta, double[][][] ksi) {
		logger.info("计算ksi...");
		long start = System.currentTimeMillis();
		//double[][][] ksi = new double[sequenceLen][stateNum][stateNum];
		double[] logProbaArr = new double[stateNum * stateNum];
		for(int t = 0; t < sequenceLen -1; t++) {
			int k = 0;
			for(int i = 0; i < stateNum; i++) {
				for(int j = 0; j < stateNum; j++) {
					ksi[t][i][j] = alpha[t][i] + transferProbability1[i][j] +
							emissionProbability[j][x[t+1]]+beta[t+1][j];
					logProbaArr[k++] = ksi[t][i][j];
				}
			}
			double logSum = logSum(logProbaArr);//分母
			for(int i = 0; i < stateNum; i++) {
				for(int j = 0; j < stateNum; j++) {
					ksi[t][i][j] -= logSum;//分子除分母
				}
			}
		}
		long end = System.currentTimeMillis();
		logger.info("计算结束...耗时:"+ (end - start) +"毫秒");
		//return ksi;
	}
	
	protected double[][] generateOldA() {
		double[][] oldA = new double[stateNum][stateNum];
		for(int i = 0; i < stateNum; i++) {
			for(int j = 0; j < stateNum; j++) {
				oldA[i][j] = transferProbability1[i][j];
			}
		}
		return oldA;
	}
	
	protected double calcError(double[][] oldA, double[] oldPi, double[][] oldB) {
		double maxError = 0;
		for(int i =0 ; i < stateNum; i++) {
			/*double tmp1 = Math.abs(pi[i] - oldPi[i]);
			maxError = tmp1 > maxError ? tmp1 : maxError;*/
			for(int j =0; j < stateNum; j++) {
				double tmp = Math.abs(oldA[i][j] - transferProbability1[i][j]);
				maxError = tmp > maxError ? tmp : maxError;
			}
			/*for(int k =0; k < observationNum; k++) {
				double tmp2 = Math.abs(emissionProbability[i][k] - oldB[i][k]);
				maxError = tmp2 > maxError ? tmp2 : maxError;
			}*/
		}
		return maxError;
	}
	
	public double logSum(double[] logProbaArr) {
		if(logProbaArr.length == 0) {
			return INFINITY;
		}
		double max = max(logProbaArr);
		double result = 0;
		for(int i = 0; i < logProbaArr.length; i++) {
			result += Math.exp(logProbaArr[i] - max);
		}
		return max + Math.log(result);
	}
	public static double max(double[] arr) {
		double max = arr[0];
		for(int i = 1; i < arr.length;i++) {
			max = arr[i] > max ? arr[i] : max;
		}
		return max;
	}
	protected void updateLambda(int[] x ,double[][] gamma, double[][][] ksi) {
		//顺序可以颠倒
		updatePi(gamma);
		updateA(ksi, gamma);
		updateB(x, gamma);
	}
	
	public void updatePi(double[][] gamma) {
		//更新HMM中的参数pi
		for(int i = 0; i < stateNum; i++) {
			pi[i] = gamma[0][i];
		}
	}
	
	protected void updateA(double[][][] ksi, double[][] gamma) {
		logger.info("更新参数转移概率A...");
		由于在更新A都要用到对不同状态的前T-1的gamma值求和,所以这里先算
		double[] gammaSum = new double[stateNum];
		double[] tmp = new double[sequenceLen -1];
		for(int i = 0; i < stateNum; i++) {
			for(int t = 0; t < sequenceLen -1; t++) {
				tmp[t] = gamma[t][i];
			}
			gammaSum[i]  = logSum(tmp);
		}
		long start1 = System.currentTimeMillis();
		//更新HMM中的参数A
		double[] ksiLogProbArr = new double[sequenceLen - 1];
		for(int i = 0; i < stateNum; i++) {
			for(int j = 0; j < stateNum; j++) {
				for(int t = 0; t < sequenceLen -1; t++) {
					ksiLogProbArr[t] = ksi[t][i][j];
				}
				transferProbability1[i][j] = logSum(ksiLogProbArr) - gammaSum[i];
			}
		}
		long end1 = System.currentTimeMillis();
		logger.info("更新完毕...耗时:"+(end1 - start1)+"毫秒");
	}
	
	protected void updateB(int[] x, double[][] gamma) {
		//下面需要用到gamma求和为了减少重复计算,这里直接先计算
		//由于在更新B时都要用到对不同状态的所有gamma值求和,所以这里先算
		double[] gammaSum2 = new double[stateNum];
		double[] tmp2 = new double[sequenceLen];
		for(int i = 0; i < stateNum; i++) {
			for(int t = 0; t < sequenceLen; t++) {
				tmp2[t] = gamma[t][i];
			}
			gammaSum2[i]  = logSum(tmp2);
		}
		logger.info("更新状态下分布概率B...");
		long start2 = System.currentTimeMillis();
		ArrayList<Double> valid = new ArrayList<Double>();
		for(int i = 0; i < stateNum; i++) {
			for(int k = 0; k < observationNum; k++) {
				valid.clear();//由于这里没有初始化造成了计算出错的问题
				for(int t = 0; t < sequenceLen; t++) {
					if(x[t] == k) {
						valid.add(gamma[t][i]);
					}
				}
				//B[i][k],i状态下k的分布为概率0,
				if(valid.size() == 0) {
					emissionProbability[i][k] = INFINITY;
					continue;
				}
				//对分子求logSum
				double[] validArr = new double[valid.size()];
				for(int q = 0; q < valid.size(); q++) {
					validArr[q] = valid.get(q);
				}
				double validSum = logSum(validArr);
				//分母的logSum已经在上面做了
				emissionProbability[i][k] = validSum - gammaSum2[i];
			}
		}
		long end2 = System.currentTimeMillis();
		logger.info("更新完毕...耗时:"+(end2 - start2)+"毫秒");
	}
	
	public void setPriorPi(double[] pi){
		this.pi = pi;
	}
	
	public void setPriorTransferProbability1(double[][] trtransferProbability1){
		this.transferProbability1 = trtransferProbability1;
	}
	
	public void setPriorEmissionProbability(double[][] emissionProbability) {
		this.emissionProbability = emissionProbability;
	}
	
	public void randomInitPi() {
		for(int i = 0; i < stateNum; i++) {
			pi[i] = Math.random() * 100;
		}
		//log归一化
		double sum = Math.log(sum(pi));
		for(int i =0; i < stateNum; i++) {
			if(pi[i] == 0) {
				pi[i] = INFINITY;
				continue;
			}
			pi[i] = Math.log(pi[i]) - sum;
		}
	}
	
	public void randomInitA() {
		for(int i = 0; i < stateNum; i++) {
			for(int j = 0; j < stateNum; j++) {
				transferProbability1[i][j] = Math.random()*100;;
			}
			double sum = Math.log(sum(transferProbability1[i]));
			for(int k = 0; k < stateNum; k++) {
				if(transferProbability1[i][k] == 0) {
					transferProbability1[i][k] = INFINITY;
					continue;
				}
				transferProbability1[i][k]  = Math.log(transferProbability1[i][k]) - sum;
			}
		}
	}
	public void randomInitB() {
		for(int i = 0; i < stateNum; i++) {
			for(int j = 0; j < observationNum; j++) {
				emissionProbability[i][j] = Math.random()*100;;
			}
			double sum = Math.log(sum(emissionProbability[i]));
			for(int k = 0; k < observationNum; k++) {
				if(emissionProbability[i][k] == 0) {
					emissionProbability[i][k] = INFINITY;
					continue;
				}
				emissionProbability[i][k]  = Math.log(emissionProbability[i][k]) - sum;
			}
		}
	}
	
	public void randomInitAllParameters() {
		randomInitA();
		randomInitB();
		randomInitPi();
	}
	
	public static double sum(double[] arr) {
		double sum = 0;
		for(int i = 0; i < arr.length;i++) {
			sum += arr[i];
		}
		return sum;
	}
	
}

HMM算法进行测试的主方法

package HMM_test01;

import java.math.BigDecimal;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Iterator;


import MySQL.ChaZhao_train;
//HMM测试的主方法
public class HMM_main_test {

	public static void main(String[] args) {
		//得到测试数据
		ArrayList<float[]> dataSet;  
		Connection conn1 = ChaZhao_train.getconn();
		dataSet = ChaZhao_train.select(conn1);
        ChaZhao_train.close();
		
        System.out.println(dataSet.size());
        Iterator it = dataSet.iterator();
        
        
        float[] d = new float[4];
        int[][] data = new int[30][30];//30*30 = 900 30组每组30个
        
        int[] data1 = new int[30];
        int[] data2 = new int[30];
        int[] data3 = new int[30];
        int[] data4 = new int[30];
        
        int num =0;
        int n = 0;
        int flag=0;
        double p1;double p2;double p3;double p4;
        
        while(it.hasNext()){
        	d = (float[]) it.next();
        	data1[num] = (int) d[2];
        	data2[num] = (int) d[3];
        	data3[num] = (int) d[4];
        	data4[num] = (int) d[5];
        	num++;
        	if(num%30 == 0){
        		n++;
        		p1 = getP1(data1,data2,data3,data4);//在手势1 HMM模型下的融合概率
        		p2 = getP2(data1,data2,data3,data4);
        		p3 = getP3(data1,data2,data3,data4);
        		p4 = getP4(data1,data2,data3,data4);
        		
        		flag = panDuan(p1,p2,p3,p4);
        		System.out.println(n+"号手势,判断为手势"+flag);
        		
        		data1 = new int[30];
        		data2 = new int[30];
        		data3 = new int[30];
        		data4 = new int[30];
        		num = 0;
        	}
        }
        /*
        while(it.hasNext()){
        	d = (float[]) it.next();
        	data1[num] = (int) d[2];
        	data2[num] = (int) d[3];
        	data3[num] = (int) d[4];
        	data4[num] = (int) d[5];
        	num++;
        	if(num == 30){
        		break;
        	}
        }
       */

        /*
        for(int i=0;i<30;i++){
        	data[0][i] = data1[i];
        }
        for(int i=0;i<30;i++){
        	data[1][i] = data2[i];
        }
        for(int i=0;i<30;i++){
        	data[2][i] = data3[i];
        }
        for(int i=0;i<30;i++){
        	data[3][i] = data4[i];
        }
        */	
        /*
        for(int i=0;i<30;i++){
        	System.out.print(data2[i]+",");
        }
        */
        /*
        HMM_test_train hmm11 = new HMM_test_train(6, 16);
        hmm11.pi = TeZhengZhi.pi11;
        hmm11.transferProbability1 = TeZhengZhi.transferProbability11;
        hmm11.emissionProbability = TeZhengZhi.emissionProbability11;
        HMM_test_train hmm12 = new HMM_test_train(6, 14);
        hmm12.pi = TeZhengZhi.pi12;
        hmm12.transferProbability1 = TeZhengZhi.transferProbability12;
        hmm12.emissionProbability = TeZhengZhi.emissionProbability12;
        HMM_test_train hmm13 = new HMM_test_train(6, 10);
        hmm13.pi = TeZhengZhi.pi13;
        hmm13.transferProbability1 = TeZhengZhi.transferProbability13;
        hmm13.emissionProbability = TeZhengZhi.emissionProbability13;
        HMM_test_train hmm14 = new HMM_test_train(6, 10);
        hmm14.pi = TeZhengZhi.pi14;
        hmm14.transferProbability1 = TeZhengZhi.transferProbability14;
        hmm14.emissionProbability = TeZhengZhi.emissionProbability14;
        
        HMM_test_train hmm21 = new HMM_test_train(6, 16);
        hmm21.pi = TeZhengZhi.pi21;
        hmm21.transferProbability1 = TeZhengZhi.transferProbability21;
        hmm21.emissionProbability = TeZhengZhi.emissionProbability21;
        HMM_test_train hmm22 = new HMM_test_train(6, 14);
        hmm22.pi = TeZhengZhi.pi22;
        hmm22.transferProbability1 = TeZhengZhi.transferProbability22;
        hmm22.emissionProbability = TeZhengZhi.emissionProbability22;
        HMM_test_train hmm23 = new HMM_test_train(6, 10);
        hmm23.pi = TeZhengZhi.pi23;
        hmm23.transferProbability1 = TeZhengZhi.transferProbability23;
        hmm23.emissionProbability = TeZhengZhi.emissionProbability23;
        HMM_test_train hmm24 = new HMM_test_train(6, 10);
        hmm24.pi = TeZhengZhi.pi24;
        hmm24.transferProbability1 = TeZhengZhi.transferProbability24;
        hmm24.emissionProbability = TeZhengZhi.emissionProbability24;
        
        HMM_test_train hmm31 = new HMM_test_train(6, 16);
        hmm31.pi = TeZhengZhi.pi31;
        hmm31.transferProbability1 = TeZhengZhi.transferProbability31;
        hmm31.emissionProbability = TeZhengZhi.emissionProbability31;
        HMM_test_train hmm32 = new HMM_test_train(6, 14);
        hmm32.pi = TeZhengZhi.pi32;
        hmm32.transferProbability1 = TeZhengZhi.transferProbability32;
        hmm32.emissionProbability = TeZhengZhi.emissionProbability32;
        HMM_test_train hmm33 = new HMM_test_train(6, 10);
        hmm33.pi = TeZhengZhi.pi33;
        hmm33.transferProbability1 = TeZhengZhi.transferProbability33;
        hmm33.emissionProbability = TeZhengZhi.emissionProbability33;
        HMM_test_train hmm34 = new HMM_test_train(6, 10);
        hmm34.pi = TeZhengZhi.pi34;
        hmm34.transferProbability1 = TeZhengZhi.transferProbability34;
        hmm34.emissionProbability = TeZhengZhi.emissionProbability34;
       
        HMM_test_train hmm41 = new HMM_test_train(6, 16);
        hmm41.pi = TeZhengZhi.pi41;
        hmm41.transferProbability1 = TeZhengZhi.transferProbability41;
        hmm41.emissionProbability = TeZhengZhi.emissionProbability41;
        HMM_test_train hmm42 = new HMM_test_train(6, 14);
        hmm42.pi = TeZhengZhi.pi42;
        hmm42.transferProbability1 = TeZhengZhi.transferProbability42;
        hmm42.emissionProbability = TeZhengZhi.emissionProbability42;
        HMM_test_train hmm43 = new HMM_test_train(6, 10);
        hmm43.pi = TeZhengZhi.pi43;
        hmm43.transferProbability1 = TeZhengZhi.transferProbability43;
        hmm43.emissionProbability = TeZhengZhi.emissionProbability43;
        HMM_test_train hmm44 = new HMM_test_train(6, 10);
        hmm44.pi = TeZhengZhi.pi44;
        hmm44.transferProbability1 = TeZhengZhi.transferProbability44;
        hmm44.emissionProbability = TeZhengZhi.emissionProbability44;
        
        
        double[][] alpha1;
        double[][] alpha2;
        double[][] alpha3;
        double[][] alpha4;
        
        alpha1 = hmm41.calcAlpha1(data1);
        alpha2 = hmm42.calcAlpha1(data2);
        alpha3 = hmm43.calcAlpha1(data3);
        alpha4 = hmm44.calcAlpha1(data4);
        double p11 = 0;
        double p12 = 0;
        double p13 = 0;
        double p14 = 0;
        
        for(int i=0;i<alpha1[29].length;i++){
        	p11 +=alpha1[29][i];}
        for(int i=0;i<alpha2[29].length;i++){
        	p12 +=alpha2[29][i];}
        for(int i=0;i<alpha3[29].length;i++){
        	p13 +=alpha3[29][i];}
        for(int i=0;i<alpha4[29].length;i++){
        	p14 +=alpha4[29][i];}
        
        double p = rongHe(p11,p12,p13,p14);
        System.out.println("p11"+p11+
        					",p12"+p12+
        					",p13"+p13+
        					",p14"+p14);
        System.out.println("p="+p);
        */
	}
	
	public static double rongHe(double p1,double p2,double p3,double p4){
		double p = new BigDecimal(p1+p2+p4+p4).divide(new BigDecimal(4),5,BigDecimal.ROUND_HALF_DOWN).doubleValue();
		return p;
	}
	
	public static int panDuan(double p1,double p2,double p3,double p4){
		int flag =0;
		double[] p = new double[4];
		p[0] = p1;
		p[1] = p2;
		p[2] = p3;
		p[3] = p4;
		/*
		System.out.println("排序前:");
		for(int i=0;i<p.length;i++){
			System.out.println(p[i]+",");
		}
		*/
		for(int i=0;i<p.length-1;i++){
			int index = i;
			for(int j=i+1;j<p.length;j++){
				if(p[j]>p[index]){
					index = j;
				}
			}
			double tmp = p[index];
			p[index] = p[i];
			p[i] = tmp;
		}
		/*
		System.out.println("排序后:");
		for(int i=0;i<p.length;i++){
			System.out.println(p[i]+",");
		}
		*/
		if(p[0] == p1){
			flag = 1;
		}else if(p[0] == p2){
			flag = 2;
		}else if(p[0] == p3){
			flag = 3;
		}else if(p[0] == p4){
			flag = 4;
		}
		
		return flag;
	}
	
	public static double getP1(int[] data1,int[] data2,int[] data3,int[] data4){
        HMM_test_train hmm11 = new HMM_test_train(6, 16);
        hmm11.pi = TeZhengZhi.pi11;
        hmm11.transferProbability1 = TeZhengZhi.transferProbability11;
        hmm11.emissionProbability = TeZhengZhi.emissionProbability11;
        HMM_test_train hmm12 = new HMM_test_train(6, 14);
        hmm12.pi = TeZhengZhi.pi12;
        hmm12.transferProbability1 = TeZhengZhi.transferProbability12;
        hmm12.emissionProbability = TeZhengZhi.emissionProbability12;
        HMM_test_train hmm13 = new HMM_test_train(6, 10);
        hmm13.pi = TeZhengZhi.pi13;
        hmm13.transferProbability1 = TeZhengZhi.transferProbability13;
        hmm13.emissionProbability = TeZhengZhi.emissionProbability13;
        HMM_test_train hmm14 = new HMM_test_train(6, 10);
        hmm14.pi = TeZhengZhi.pi14;
        hmm14.transferProbability1 = TeZhengZhi.transferProbability14;
        hmm14.emissionProbability = TeZhengZhi.emissionProbability14;
        
        double[][] alpha1;
        double[][] alpha2;
        double[][] alpha3;
        double[][] alpha4;
        
        alpha1 = hmm11.calcAlpha1(data1);
        alpha2 = hmm12.calcAlpha1(data2);
        alpha3 = hmm13.calcAlpha1(data3);
        alpha4 = hmm14.calcAlpha1(data4);
        double p11 = 0;
        double p12 = 0;
        double p13 = 0;
        double p14 = 0;
        
        for(int i=0;i<alpha1[29].length;i++){
        	p11 +=alpha1[29][i];}
        for(int i=0;i<alpha2[29].length;i++){
        	p12 +=alpha2[29][i];}
        for(int i=0;i<alpha3[29].length;i++){
        	p13 +=alpha3[29][i];}
        for(int i=0;i<alpha4[29].length;i++){
        	p14 +=alpha4[29][i];}
        
        double p = rongHe(p11,p12,p13,p14);
        
        return p;
	}
	public static double getP2(int[] data1,int[] data2,int[] data3,int[] data4){
        HMM_test_train hmm21 = new HMM_test_train(6, 16);
        hmm21.pi = TeZhengZhi.pi21;
        hmm21.transferProbability1 = TeZhengZhi.transferProbability21;
        hmm21.emissionProbability = TeZhengZhi.emissionProbability21;
        HMM_test_train hmm22 = new HMM_test_train(6, 14);
        hmm22.pi = TeZhengZhi.pi22;
        hmm22.transferProbability1 = TeZhengZhi.transferProbability22;
        hmm22.emissionProbability = TeZhengZhi.emissionProbability22;
        HMM_test_train hmm23 = new HMM_test_train(6, 10);
        hmm23.pi = TeZhengZhi.pi23;
        hmm23.transferProbability1 = TeZhengZhi.transferProbability23;
        hmm23.emissionProbability = TeZhengZhi.emissionProbability23;
        HMM_test_train hmm24 = new HMM_test_train(6, 10);
        hmm24.pi = TeZhengZhi.pi24;
        hmm24.transferProbability1 = TeZhengZhi.transferProbability24;
        hmm24.emissionProbability = TeZhengZhi.emissionProbability24;
        
        double[][] alpha1;
        double[][] alpha2;
        double[][] alpha3;
        double[][] alpha4;
        
        alpha1 = hmm21.calcAlpha1(data1);
        alpha2 = hmm22.calcAlpha1(data2);
        alpha3 = hmm23.calcAlpha1(data3);
        alpha4 = hmm24.calcAlpha1(data4);
        double p21 = 0;
        double p22 = 0;
        double p23 = 0;
        double p24 = 0;
        
        for(int i=0;i<alpha1[29].length;i++){
        	p21 +=alpha1[29][i];}
        for(int i=0;i<alpha2[29].length;i++){
        	p22 +=alpha2[29][i];}
        for(int i=0;i<alpha3[29].length;i++){
        	p23 +=alpha3[29][i];}
        for(int i=0;i<alpha4[29].length;i++){
        	p24 +=alpha4[29][i];}
        
        double p = rongHe(p21,p22,p23,p24);
        
        return p;
	}
	public static double getP3(int[] data1,int[] data2,int[] data3,int[] data4){
        HMM_test_train hmm31 = new HMM_test_train(6, 16);
        hmm31.pi = TeZhengZhi.pi31;
        hmm31.transferProbability1 = TeZhengZhi.transferProbability31;
        hmm31.emissionProbability = TeZhengZhi.emissionProbability31;
        HMM_test_train hmm32 = new HMM_test_train(6, 14);
        hmm32.pi = TeZhengZhi.pi32;
        hmm32.transferProbability1 = TeZhengZhi.transferProbability32;
        hmm32.emissionProbability = TeZhengZhi.emissionProbability32;
        HMM_test_train hmm33 = new HMM_test_train(6, 10);
        hmm33.pi = TeZhengZhi.pi33;
        hmm33.transferProbability1 = TeZhengZhi.transferProbability33;
        hmm33.emissionProbability = TeZhengZhi.emissionProbability33;
        HMM_test_train hmm34 = new HMM_test_train(6, 10);
        hmm34.pi = TeZhengZhi.pi34;
        hmm34.transferProbability1 = TeZhengZhi.transferProbability34;
        hmm34.emissionProbability = TeZhengZhi.emissionProbability34;
        
        double[][] alpha1;
        double[][] alpha2;
        double[][] alpha3;
        double[][] alpha4;
        
        alpha1 = hmm31.calcAlpha1(data1);
        alpha2 = hmm32.calcAlpha1(data2);
        alpha3 = hmm33.calcAlpha1(data3);
        alpha4 = hmm34.calcAlpha1(data4);
        double p31 = 0;
        double p32 = 0;
        double p33 = 0;
        double p34 = 0;
        
        for(int i=0;i<alpha1[29].length;i++){
        	p31 +=alpha1[29][i];}
        for(int i=0;i<alpha2[29].length;i++){
        	p32 +=alpha2[29][i];}
        for(int i=0;i<alpha3[29].length;i++){
        	p33 +=alpha3[29][i];}
        for(int i=0;i<alpha4[29].length;i++){
        	p34 +=alpha4[29][i];}
        
        double p = rongHe(p31,p32,p33,p34);
        
        return p;
	}
	public static double getP4(int[] data1,int[] data2,int[] data3,int[] data4){
        HMM_test_train hmm41 = new HMM_test_train(6, 16);
        hmm41.pi = TeZhengZhi.pi41;
        hmm41.transferProbability1 = TeZhengZhi.transferProbability41;
        hmm41.emissionProbability = TeZhengZhi.emissionProbability41;
        HMM_test_train hmm42 = new HMM_test_train(6, 14);
        hmm42.pi = TeZhengZhi.pi42;
        hmm42.transferProbability1 = TeZhengZhi.transferProbability42;
        hmm42.emissionProbability = TeZhengZhi.emissionProbability42;
        HMM_test_train hmm43 = new HMM_test_train(6, 10);
        hmm43.pi = TeZhengZhi.pi43;
        hmm43.transferProbability1 = TeZhengZhi.transferProbability43;
        hmm43.emissionProbability = TeZhengZhi.emissionProbability43;
        HMM_test_train hmm44 = new HMM_test_train(6, 10);
        hmm44.pi = TeZhengZhi.pi44;
        hmm44.transferProbability1 = TeZhengZhi.transferProbability44;
        hmm44.emissionProbability = TeZhengZhi.emissionProbability44;
        
        double[][] alpha1;
        double[][] alpha2;
        double[][] alpha3;
        double[][] alpha4;
        
        alpha1 = hmm41.calcAlpha1(data1);
        alpha2 = hmm42.calcAlpha1(data2);
        alpha3 = hmm43.calcAlpha1(data3);
        alpha4 = hmm44.calcAlpha1(data4);
        double p41 = 0;
        double p42 = 0;
        double p43 = 0;
        double p44 = 0;
        
        for(int i=0;i<alpha1[29].length;i++){
        	p41 +=alpha1[29][i];}
        for(int i=0;i<alpha2[29].length;i++){
        	p42 +=alpha2[29][i];}
        for(int i=0;i<alpha3[29].length;i++){
        	p43 +=alpha3[29][i];}
        for(int i=0;i<alpha4[29].length;i++){
        	p44 +=alpha4[29][i];}
        
        double p = rongHe(p41,p42,p43,p44);
        
        return p;
	}
	
//11,11,11,11,11,11,11,11,11,11,11,11,8,8,8,8,8,8,8,12,5,2,0,0,0,0,0,0,9,9,
//-379.8256140201694
//13,11,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,11,11,13,13,13,13,13,13,13,
//-475.7066616916528
/*
 *
手势一第71组数据测试
p11-379.8256140201694,p12-474.22569887839927,p13-374.0530817585345,p14-317.29295889720527
p=-372.15931

p11-530.8853915282936,p12-433.2418825412326,p13-438.93749536965004,p14-316.1747685048238
p=-399.1192

p11-1.288490271660508E10,p12-383.6469791065424,p13-415.6544273628259,p14-1.288490193235438E11
p=-6.764573543683491E10

p11-1.28849027071083E10,p12-1.2884902481041119E10,p13-951.5811106868755,p14-1.2884901940370097E11
p=-7.086696099888785E10

手势二第71组数据测试
p11-475.7066616916528,p12-506.45376915760755,p13-481.16482723948627,p14-337.23746214296443
p=-414.15884

p11-434.48085973724756,p12-545.7625987296728,p13-409.72792362229774,p14-326.57720674311184
p=-408.34947

p11-560.6563718542866,p12-505.59533333129286,p13-566.1699042362742,p14-1.2884901931354419E11
p=-6.442450992333502E10

p11-616.9942659837048,p12-653.8407136408068,p13-802.2945288472049,p14-1.288490193818364E11
p=-6.442451000862694E10

手势三第71组数据测试
p11-865.4383117385217,p12-429.3989300797176,p13-550.0929260339941,p14-2.0615843049967416E11
p=-1.0307921557354639E11

p11-2.190433323972885E11,p12-914.9286395712235,p13-416.722954842847,p14-810.530966975143
p=-5.476083373331978E10

p11-377.5578814388836,p12-486.1225670419643,p13-367.59862460618905,p14-354.54544963284224
p=-393.19284

p11-441.9979441197495,p12-1.803886268330757E11,p13-732.2912888769096,p14-358.7116723433058
p=-4.509715699812425E10

手势四第71组数据
p11-859.8184165402025,p12-2.061584306917103E11,p13-492.1227651193485,p14-1.5461882300896796E11
p=-1.2884901939236617E11

p11-1.4173392122704718E11,p12-746.8622361462081,p13-463.7257176005111,p14-715.801124512222
p=-3.543348085137791E10

p11-382.2028306913551,p12-3.350074491659079E11,p13-3.8654706237412994E10,p14-415.31050807733953
p=-8.375186259468292E10

p11-334.06802967306606,p12-194.7186282025473,p13-229.31653911787862,p14-394.52455590302617
p=-329.45894

 */
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
HMM是一种常见的统计模型,用于描述随机生成的序列。Viterbi算法是一种在HMM中进行解码的动态规划算法,用于寻找最可能的隐藏状态序列。下面是HMM的MATLAB实现,包括Viterbi算法。 首先,我们需要定义一个HMM模型。我们假设这个模型有3个隐藏状态和2个可见状态。我们使用矩阵A表示隐藏状态之间的转移概率,矩阵B表示每个隐藏状态生成每个可见状态的概率,向量pi表示初始隐藏状态的概率分布。 ```matlab % 定义HMM模型参数 A = [0.5 0.2 0.3; 0.3 0.5 0.2; 0.2 0.3 0.5]; B = [0.5 0.5; 0.4 0.6; 0.7 0.3]; pi = [0.2 0.4 0.4]; ``` 接下来,我们需要生成一个可见序列。我们使用HMM模型中的随机过程生成一个长度为10的可见序列。 ```matlab % 生成可见序列 T = 10; q = zeros(1, T); o = zeros(1, T); q(1) = randsrc(1, 1, [1:3; pi]); o(1) = randsrc(1, 1, [1:2; B(q(1), :)]); for t = 2:T q(t) = randsrc(1, 1, [1:3; A(q(t-1), :)]); o(t) = randsrc(1, 1, [1:2; B(q(t), :)]); end ``` 接下来,我们使用Viterbi算法解码这个可见序列,得到最可能的隐藏状态序列。我们定义一个矩阵V表示每个时间步的最大概率,以及一个矩阵path表示每个时间步的最大概率对应的前一个状态。 ```matlab % Viterbi算法解码 V = zeros(3, T); path = zeros(3, T); V(:, 1) = pi' .* B(:, o(1)); for t = 2:T for j = 1:3 [V(j, t), path(j, t)] = max(V(:, t-1) .* A(:, j)); V(j, t) = V(j, t) * B(j, o(t)); end end ``` 最后,我们找到最可能的隐藏状态序列。我们首先找到最后一个时间步的最大概率对应的隐藏状态,然后从后往前依次寻找每个时间步的最大概率对应的隐藏状态,最终得到整个隐藏状态序列。 ```matlab % 找到最可能的隐藏状态序列 [~, q(T)] = max(V(:, T)); for t = T-1:-1:1 q(t) = path(q(t+1), t+1); end ``` 完整代码如下: ```matlab % 定义HMM模型参数 A = [0.5 0.2 0.3; 0.3 0.5 0.2; 0.2 0.3 0.5]; B = [0.5 0.5; 0.4 0.6; 0.7 0.3]; pi = [0.2 0.4 0.4]; % 生成可见序列 T = 10; q = zeros(1, T); o = zeros(1, T); q(1) = randsrc(1, 1, [1:3; pi]); o(1) = randsrc(1, 1, [1:2; B(q(1), :)]); for t = 2:T q(t) = randsrc(1, 1, [1:3; A(q(t-1), :)]); o(t) = randsrc(1, 1, [1:2; B(q(t), :)]); end % Viterbi算法解码 V = zeros(3, T); path = zeros(3, T); V(:, 1) = pi' .* B(:, o(1)); for t = 2:T for j = 1:3 [V(j, t), path(j, t)] = max(V(:, t-1) .* A(:, j)); V(j, t) = V(j, t) * B(j, o(t)); end end % 找到最可能的隐藏状态序列 [~, q(T)] = max(V(:, T)); for t = T-1:-1:1 q(t) = path(q(t+1), t+1); end ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值