HMM示例及Matlab计算

Alice Bob是好朋友,但是他们离得比较远,每天都是通过电话了解对方那天作了什么。Bob仅仅对三种活动感兴趣:公园散步,购物以及清理房间。他选择做什么事情只凭当天天气。Alice对于Bob所住的地方的天气情况并不了解,但是知道总的趋势。在Bob告诉Alice每天所做的事情基础上,Alice想要猜测Bob所在地的天气情况。

  Alice认为天气的运行就像一个马尔可夫链。其有两个状态 “雨”和”晴”,但是无法直接观察它们,也就是说,它们对于Alice是隐藏的。每天,Bob有一定的概率进行下列活动:“散步”,“购物”,或 “清理”。因为Bob会告诉Alice他的活动,所以这些活动就是Alice的观察数据。这整个系统就是一个隐马尔可夫模型HMM

  Alice知道这个地区的总的天气趋势,并且平时知道Bob会做的事情。也就是说这个隐马尔可夫模型的参数是已知的。可以用程序语言(Python)写下来:

   // 状态数目,两个状态:雨或晴

   states = (‘Rainy’, ‘Sunny’)

   // 每个状态下可能的观察值

   observations = (‘walk’, ‘shop’, ‘clean’)

   //初始状态空间的概率分布

   start_probability = {‘Rainy’: 0.6, ‘Sunny’: 0.4}

   // 与时间无关的状态转移概率矩阵

   transition_probability = {

   ’Rainy’ : {‘Rainy’: 0.7, ‘Sunny’: 0.3},

   ’Sunny’ : {‘Rainy’: 0.4, ‘Sunny’: 0.6},

   }

   //给定状态下,观察值概率分布,发射概率

   emission_probability = {

   ’Rainy’ : {‘walk’: 0.1, ‘shop’: 0.4, ‘clean’: 0.5},

   ’Sunny’ : {‘walk’: 0.6, ‘shop’: 0.3, ‘clean’: 0.1},

   }

  在这些代码中,start_probability代表了Alice对于Bob第一次给她打电话时的天气情况的不确定性(Alice知道的只是那个地方平均起来下雨多些)。在这里,这个特定的概率分布并非平衡的,平衡概率应该接近(在给定变迁概率的情况下){‘Rainy’: 0.571, ‘Sunny’: 0.429} transition_probability 表示马尔可夫链下的天气变迁情况,在这个例子中,如果今天下雨,那么明天天晴的概率只有30%。代码emission_probability 表示了Bob每天作某件事的概率。如果下雨,有 50% 的概率他在清理房间;如果天晴,则有60%的概率他在外头散步。

  AliceBob通了三天电话后发现第一天Bob去散步了,第二天他去购物了,第三天他清理房间了。Alice现在有两个问题:这个观察序列“散步、购物、清理”的总的概率是多少?(注:这个问题对应于HMM的基本问题之一:已知HMM模型λ及观察序列O,如何计算P(O|λ)) 最能解释这个观察序列的状态序列(晴/雨)又是什么?(注:这个问题对应HMM基本问题之二:给定观察序列O=O1,O2,OT以及模型λ,如何选择一个对应的状态序列S = q1,q2,qT,使得S能够最为合理的解释观察序列O

  至于HMM的基本问题之三:如何调整模型参数,使得P(O|λ)最大?这个问题事实上就是给出很多个观察序列值,来训练以上几个参数的问题。

 

For illustration, the section uses the example described in A Concrete Example for Hidden Markov Model.

 

First, create the transition and emission matrices by entering the following commands.

%%%%%%%%%%%%%%%%%%%%%

转移矩阵

TRANS=[0.7 0.3;0.4 0.6];

 

发射概率

EMIS=[0.1 0.4 0.5;0.6 0.3 0.1];

 

%%%%%%%%%%%%%%%%%%%%%%%%%%%

Next, generate a random sequence of emissions from the model, seq, of length 1000, using the function hmmgenerate. You can also return the corresponding random sequence of states in the model as the second output, states.

 

Generating Data

%%%%%%%%%%%%%%%%%%%%%%%%%

随机生成状态和概率

[seq, states] = hmmgenerate(1000, TRANS, EMIS);

 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 

得到这么一段东西:

seq=[1, 2, 2, 2, 3, 2,...]

说明朋友最近的行踪:【散步,购物,购物,购物,打扫卫生,购物】,是个购物狂哦!

 

Computing the Most Likely Sequence of States

 

Used the Viterbi algorithm to compute the most likely sequence of states that the model would go through to generate the given sequence of emissions.

 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 

likelystates = hmmviterbi(seq, TRANS, EMIS);

 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 

To test the accuracy of hmmviterbi, you can compute the percentage of the time that the actual sequence states agrees with the sequence likelystates.

 

%%%%%%%%%%%%%%%%%%%%%%%%%%

sum(states==likelystates)/1000

%%%%%%%%%%%%%%%%%%%%%%%%%

 

I got 0.7710 in my computer. 看来对天气的预测不是很准哈

 

Estimating the Transition and Emission Matrices

Suppose you do not know the transition and emission matrices in the model, and you observe a sequence of emissions, seq. If you have an initial guess as to the values of TRANS and EMIS, you can estimate the transition and emission matrices using the function hmmtrain.

For example, suppose you have the following initial guesses for TRANS and EMIS.

 

 

%%%%%%%%%%%%%%%%%%%%%%%%

TRANS_GUESS = [0.5 0.5;0.5 0.5];

EMIS_GUESS = [0.3 0.4 0.3;0.6 0.3 0.2];

%%%%%%%%%%%%%%%%%%%%%%%%

 

You can estimate TRANS and EMIS with the following command.

 

%%%%%%%%%%%%%%%%%%%%%%%%%%

[TRANS_EST2, EMIS_EST2] = hmmtrain(seq, TRANS_GUESS, EMIS_GUESS)

%%%%%%%%%%%%%%%%%%%%%%%%%%

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
hmm算法matlab实现和实例 hmm_em.m function [LL, prior, transmat, obsmat, nrIterations] = ... dhmm_em(data, prior, transmat, obsmat, varargin) % LEARN_DHMM Find the ML/MAP parameters of an HMM with discrete outputs using EM. % [ll_trace, prior, transmat, obsmat, iterNr] = learn_dhmm(data, prior0, transmat0, obsmat0, ...) % % Notation: Q(t) = hidden state, Y(t) = observation % % INPUTS: % data{ex} or data(ex,:) if all sequences have the same length % prior(i) % transmat(i,j) % obsmat(i,o) % % Optional parameters may be passed as 'param_name', param_value pairs. % Parameter names are shown below; default values in [] - if none, argument is mandatory. % % 'max_iter' - max number of EM iterations [10] % 'thresh' - convergence threshold [1e-4] % 'verbose' - if 1, print out loglik at every iteration [1] % 'obs_prior_weight' - weight to apply to uniform dirichlet prior on observation matrix [0] % % To clamp some of the parameters, so learning does not change them: % 'adj_prior' - if 0, do not change prior [1] % 'adj_trans' - if 0, do not change transmat [1] % 'adj_obs' - if 0, do not change obsmat [1] % % Modified by Herbert Jaeger so xi are not computed individually % but only their sum (over time) as xi_summed; this is the only way how they are used % and it saves a lot of memory. [max_iter, thresh, verbose, obs_prior_weight, adj_prior, adj_trans, adj_obs] = ... process_options(varargin, 'max_iter', 10, 'thresh', 1e-4, 'verbose', 1, ... 'obs_prior_weight', 0, 'adj_prior', 1, 'adj_trans', 1, 'adj_obs', 1); previous_loglik = -inf; loglik = 0; converged = 0; num_iter = 1; LL = []; if ~iscell(data) data = num2cell(data, 2); % each row gets its own cell end while (num_iter <= max_iter) & ~converged % E step [loglik, exp_num_trans, exp_num_visits1, exp_num_emit] = ... compute_ess_dhmm(prior, transmat, obsmat, data, obs_prior_weight); % M step if adj_prior prior = normalise(exp_num_visits1); end if adj_trans & ~isempty(exp_num_trans) transmat = mk_stochastic(exp_num_trans); end if adj_obs obsmat = mk_stochastic(exp_num_emit); end
以下是使用Matlab进行HMM模型训练的基本步骤: 1. 准备数据 首先,需要准备训练数据,包括观测序列和对应的状态序列。这里假设有n个样本,每个样本包含T个观测值和对应的T个状态值。可以将这些数据存储在一个n*T的矩阵中。 2. 初始化HMM模型参数 HMM模型包括初始状态概率向量、转移概率矩阵和发射概率矩阵。这些参数需要初始化为一些随机值或者根据经验确定的值。 3. Baum-Welch算法 使用Baum-Welch算法,也称为EM算法,来估计HMM模型的参数。其基本思想是在每一次迭代中,根据当前参数估计每个样本的隐含状态,然后使用这些隐含状态来更新模型参数。这个过程会迭代多次,直到模型参数收敛。 4. 模型评估 最后,可以使用训练好的HMM模型来预测新的样本的隐含状态,或者计算模型在训练数据上的对数似然值来评估模型的性能。 具体的Matlab代码可以参考以下示例: % 准备数据 obs = [1 2 3 4 5 6 7 8 9 10; 1 2 3 4 5 6 7 8 9 10; 1 2 3 4 5 6 7 8 9 10]; states = [1 2 1 2 1 2 1 2 1 2; 1 2 1 2 1 2 1 2 1 2; 1 2 1 2 1 2 1 2 1 2]; n = size(obs, 1); % 样本数 T = size(obs, 2); % 观测序列长度 % 初始化模型参数 pi = [0.5 0.5]; % 初始状态概率向量 A = [0.7 0.3; 0.3 0.7]; % 转移概率矩阵 B = [0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9; 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1]; % 发射概率矩阵 M = size(B, 2); % 观测值个数 alpha = zeros(n, T, M); % alpha变量 beta = zeros(n, T, M); % beta变量 gamma = zeros(n, T, M); % gamma变量 xi = zeros(n, T, M, M); % xi变量 % Baum-Welch算法 tol = 1e-6; % 收敛容差 maxiter = 100; % 最大迭代次数 loglik_old = -inf; % 初始对数似然值 for iter = 1:maxiter % E步:计算alpha、beta、gamma、xi变量 for i = 1:n [alpha(i, :, :), beta(i, :, :), gamma(i, :, :), xi(i, :, :, :)] = hmmfwdbwd(obs(i, :), pi, A, B); end % M步:更新模型参数 pi = squeeze(sum(gamma(:, 1, :), 1)) / n; % 更新初始状态概率 A = squeeze(sum(sum(xi(:, 1:end-1, :, :), 1), 2)) ./ squeeze(sum(sum(gamma(:, 1:end-1, :), 1), 2)); % 更新转移概率 B = squeeze(sum(gamma, 2)) ./ squeeze(sum(sum(gamma, 2), 3)); % 更新发射概率 % 计算对数似然值 loglik = 0; for i = 1:n loglik = loglik + hmmloglik(obs(i, :), pi, A, B); end % 判断是否收敛 if abs(loglik - loglik_old) < tol break; end loglik_old = loglik; end % 模型评估 % 预测新的样本的隐含状态 obs_new = [1 2 3 4 5 6 7 8 9 10]; states_new = viterbi(obs_new, pi, A, B); % 计算模型在训练数据上的对数似然值 loglik_train = 0; for i = 1:n loglik_train = loglik_train + hmmloglik(obs(i, :), pi, A, B); end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值