这里是github上的关于hmm的:连接git
几率计算问题:前向-后向算法github
学习问题:Baum-Welch算法(状态未知)算法
预测问题:Viterbi算法网络
https://github.com/TimVerion/HMM_codedom
首先了解一下过去化学学习的熵,热力学中表征物质状态的参量之一,用符号S表示,其物理意义是体系混乱程度的度量。克劳修斯于 1865 年的论文中定义了“熵” ,其中有两句名言:“宇宙的能量是恒定的。”,“宇宙的熵趋于最大值。”机器学习
信息量:指的是一个样本/事件所蕴含的信息,若是一个事件的几率越大,那么就能够认为该事件所蕴含的信息越少。极端状况下,好比:“太阳从东方升起”,由于是肯定事件,因此不携带任何信息量。ide
信息熵:1948年,香农引入信息熵;一个系统越是有序,信息熵就越低,一个系统越是混乱,信息熵就越高,因此信息熵被认为是一个系统有序程度的度量。信息熵就是用来描述系统信息量的不肯定度。函数
信息熵(Entropy)公式:性能
High Entropy(高信息熵):表示随机变量X是均匀分布的,各类取值状况是等概率出现的。Low Entropy(低信息熵):表示随机变量X各类取值不是等几率出现。可能出现有的事件几率很大,有的事件几率很小。学习
例子:
机器学习中常常提到的最大熵的思想,就是当你要猜一个几率分布时,若是你对这个分布一无所知,那就猜熵最大的均匀分布,若是你对这个分布知道一些状况,那么,就猜知足这些状况的熵最大的分布,就像咱们使用最大似然去预测同样。
例子:软银的孙正义他强调商战要达到“不战而屈人之兵”,避免“不战胜仗”,就得从事优点职业。
孙正义投资雅虎,阿里,网约车火了便投资中国的滴滴和美国的Uber,也就是不把全部鸡蛋放进一个篮子里,这正是最大熵原理。
与最大熵思想区分开来后,咱们要知道最大熵模型就是让信息熵最大,而所谓的条件最大熵模型,就是在必定约束下条件熵最大的模型。再直白一点就是咱们要保留所有的不肯定性,将风险降到最小。
也就是当从模型整体随机抽取n组样本观测值后,最合理的参数估计量应该使得从模型中抽取该n组样本观测值的几率最大,这样咱们便构造了一个最大熵模型,没错这正是最大似然估计的定义。
最大熵模型,能够说是集简与繁于一体,形式简单,实现复杂。值得一提的是,在Google的不少产品中,好比机器翻译,都直接或间接地用到了最大熵模型。
三门问题:出自美国的电视游戏节目。参赛者会看见三扇关闭了的门,其中一扇的后面有一辆汽车,选中后面有车的那扇门可赢得该汽车,另外两扇门后面则各藏有一只山羊。当参赛者选定了一扇门,但未去开启它的时候,节目主持人开启剩下两扇门的其中一扇,露出其中一只山羊。主持人其后会问参赛者要不要换另外一扇仍然关上的门。问题是:换另外一扇门会否增长参赛者赢得汽车的机率?若是严格按照上述的条件,即主持人清楚地知道,本身打开的那扇门后是羊,那么答案是会。不换门的话,赢得汽车的概率是1/3。换门的话,赢得汽车的概率是2/3。
先验几率P(A):在不考虑任何状况下,A事件发生的几率
条件几率P(B|A):A事件发生的状况下,B事件发生的几率
后验几率P(A|B):在B事件发生以后,对A事件发生的几率的从新评估
全几率:若是A和A'构成样本空间的一个划分,那么事件B的几率为:A和A'的概率分别乘以B对这两个事件的几率之和。
有上面的知识推出贝叶斯公式(后验几率):
把某个研究系统中涉及到的随机变量,根据是否条件独立绘制在一个有向图中,就造成了贝叶斯网络。贝叶斯网络(Bayesian Network),又称有向无环图模型(directed acyclicgraphical model, DAG),是一种几率图模型,根据几率图的拓扑结构,考察一组随机变量{X1,X2,...,Xn}及其N组条件几率分布(Conditional ProbabililtyDistributions, CPD)的性质
当多个特征属性之间存在着某种相关关系的时候,使用朴素贝叶斯算法就无法解决这类问题,那么贝叶斯网络就是解决这类应用场景的一个很是好的算法。通常而言,贝叶斯网络的有向无环图中的节点表示随机变量,能够是可观察到的变量,或隐变量,未知参数等等。链接两个节点之间的箭头表明两个随机变量之间的因果关系(也就是这两个随机变量之间非条件独立),若是两个节点间以一个单箭头链接在一块儿,表示其中一个节点是“因”,另一个是“果”,从而两节点之间就会产生一个条件几率值。注意:每一个节点在给定其直接前驱的时候,条件独立于其后继。
贝叶斯网络的关键方法是图模型,构建一个图模型咱们须要把具备因果联系的各个变量用箭头连在一块儿。贝叶斯网络的有向无环图中的节点表示随机变量。链接两个节点的箭头表明此两个随机变量是具备因果关系的。贝叶斯网络是模拟人的认知思惟推理模式的,用一组条件几率以及有向无环图对不肯定性因果推理关系建模
P(a,b, c) = P(c | a,b)P(b | a)P(a)
上面的知识点讲到了MLE(最大似然估计),这里先说一下MAP(最大后验几率),MAP和MLE同样,都是经过样本估计参数θ的值;在MLE中,是使似然函数P(x|θ)最大的时候参数θ的值,MLE中假设先验几率是一个等值的;而在MAP中,则是求θ使P(x|θ)P(θ)的值最大,这也就是要求θ值不只仅是让似然函数最大,同时要求θ自己出现的先验几率也得比较大。
能够认为MAP是贝叶斯算法的一种应用:
EM算法(Expectation Maximization Algorithm, 最大指望算法)是一种迭代类型
的算法,是一种在几率模型中寻找参数最大似然估计或者最大后验估计的算法,
其中几率模型依赖于没法观测的隐藏变量。
EM算法流程:
初始化分布参数
重复下列两个操做直到收敛:
E步骤:估计隐藏变量的几率分布指望函数;
M步骤:根据指望函数从新估计分布参数
EM实现的过程当中还会有一个Jensen不等式知识点,它使得咱们能够假设隐含数据并造成极大化模型,而后对联合几率求最大值直到收敛。
""" 实现GMM高斯混合聚类 根据EM算法流程实现这个流程 """ import numpy as np from scipy.stats import multivariate_normal def train(x, max_iter=100): """ 进行GMM模型训练,并返回对应的μ和σ的值(假定x数据中的簇类别数目为2) :param x: 输入的特征矩阵x :param max_iter: 最大的迭代次数 :return: 返回一个五元组(pi, μ1, μ2,σ1,σ2) """ # 1. 获取样本的数量m以及特征维度n m, n = np.shape(x) # 2. 初始化相关变量 # 以每一列中的最小值做为mu1,mu1中的元素数目就是列的数目(n)个 mu1 = x.min(axis=0) mu2 = x.max(axis=0) sigma1 = np.identity(n) sigma2 = np.identity(n) pi = 0.5 # 3. 实现EM算法 for i in range(max_iter): # a. 初始化多元高斯分布(初始化两个多元高斯混合几率密度函数) norm1 = multivariate_normal(mu1, sigma1) norm2 = multivariate_normal(mu2, sigma2) # E step # 计算全部样本数据在norm1和norm2中的几率 tau1 = pi * norm1.pdf(x) tau2 = (1 - pi) * norm2.pdf(x) # 几率作一个归一化操做 w = tau1 / (tau1 + tau2) # M step mu1 = np.dot(w, x) / np.sum(w) mu2 = np.dot(1 - w, x) / np.sum(1 - w) sigma1 = np.dot(w * (x - mu1).T, (x - mu1)) / np.sum(w) sigma2 = np.dot((1 - w) * (x - mu2).T, (x - mu2)) / np.sum(1 - w) pi = np.sum(w) / m # 返回最终解 return (pi, mu1, mu2, sigma1, sigma2) if __name__ == '__main__': np.random.seed(28) # 产生一个服从多元高斯分布的数据(标准正态分布的多元高斯数据) mean1 = (0, 0, 0) # x1\x2\x3的数据分布都是服从正态分布的,同时均值均为0 cov1 = np.diag((1, 1, 1)) data1 = np.random.multivariate_normal(mean=mean1, cov=cov1, size=500) # 产生一个数据分布不均衡 mean2 = (2, 2, 3) cov2 = np.array([[1, 1, 3], [1, 2, 1], [0, 0, 1]]) data2 = np.random.multivariate_normal(mean=mean2, cov=cov2, size=200) # 合并两个数据 data = np.vstack((data1, data2)) pi, mu1, mu2, sigma1, sigma2 = train(data, 100) print("第一个类别的相关参数:") print(mu1) print(sigma1) print("第二个类别的相关参数:") print(mu2) print(sigma2) print("预测样本属于那个类别(几率越大就是那个类别):") norm1 = multivariate_normal(mu1, sigma1) norm2 = multivariate_normal(mu2, sigma2) x = np.array([0, 1, 0]) print(pi * norm1.pdf(x)) # 属于类别1的几率为:0.0275 => 0.989 print((1 - pi) * norm2.pdf(x))# 属于类别1的几率为:0.0003 => 0.011
隐马尔可夫模型(Hidden Markov Model,HMM)做为一种统计分析模型,创立于20世纪70年代。80
年代获得了传播和发展,成为信号处理的一个重要方向,现已成功地用于语音识别,行为识别,文字识别以及故障诊断等领域。
HMM是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中肯定该过程的隐含参数。而后利用这些参数来做进一步的分析,例如模式识别。
数学定理:设{X(t), t ∈ T}是一个随机过程,E为其状态空间,若对于任意的t1<t2<...<tn<t,任意的x1,x2,...,xn,x∈E,随机变量X(t)在已知变量X(t1)=x1,...,X(tn)=xn之下的条件分布函数只与X(tn)=xn有关,而与X(t1)=x1,...,X(tn-1)=xn-1无关,即条件分布函数知足下列等式,此性质称为马尔可夫性;若是随机过程知足马尔可夫性,则该过程称为马尔可夫过程。
大体意思就是咱们当前状态只受上一状态的影响,而跟上一状态以前的状态无关,就叫作马尔可夫性。
马尔可夫链是指具备马尔可夫性质的随机过程。在过程当中,在给定当前信息的情况下,过去的信息状态对于预测未来状态是无关的。在马尔可夫链的每一步,系统根据几率分布,能够从一个状态变成另一个状态,也能够保持当前状态不变。状态的改变叫作转移,状态改变的相关几率叫作转移几率。马尔可夫链中的三元素是:状态空间S、转移几率矩阵P、初始几率分布π。
举个例子来说:
设将天气状态分为晴、阴、雨三种状态,假定某天的天气状态只和上一天的天气状态有关,状态使用1(晴)、2(阴)、3(雨)表示,转移几率矩阵P以下:
咱们再看一下它们的各自转移方式:
假设某天的天气几率只与前一天的几率有关,也就是以下公式:
下面咱们开始迭代,首先假设第一天的初始几率Π=[0.5,0.3,0.2],由上式和P矩阵迭代:
这里从新假设第一天的初始几率π=[0.1,0.6,0.3],由上式和P矩阵迭代:
由此得出规律,只要迭代次数够多,咱们初始几率π并不会影响最终几率的出现。
HMM是一种统计模型,在语音识别、行为识别、NLP、故障诊断等领域具备高效的性能。
HMM是关于时序的几率模型,描述一个含有未知参数的马尔可夫链所生成的不可观测的状态随机序列,再由各个状态生成观测随机序列的过程。
HMM是一个双重随机过程---具备必定状态的隐马尔可夫链和随机的观测序列。HMM随机生成的状态随机序列被称为状态序列;每一个状态成一个观测,由此产生的观测随机序列,被称为观测序列。
HMM由隐含状态S、可观测状态O、初始状态几率矩阵π、隐含状态转移几率矩阵A、可观测值转移矩阵B(又称为混淆矩阵,Confusion Matrix);
这里Π和A决定了状态序列S,B决定了可观测序列O,因此它们三个式整个隐马的关键:
这里S和O是相对于整个集合而言的,咱们通常只会度量前T个状态序列I和观测序列Q:
这里每一个q发生的几率只受i的影响,而每个i只受前一个i的影响。
假设有三个盒子,编号为1,2,3;每一个盒子都装有黑白两种颜色的小球,球的比例以下:
编号 | 白球 | 黑球 |
---|---|---|
1 | 4 | 6 |
2 | 8 | 2 |
3 | 5 | 5 |
按照下列规则的方式进行有放回的抽取小球,获得球颜色的观测序列:
按照π的几率选择一个盒子,从盒子中随机抽取出一个小球(B),记录颜色后,放回盒子中;
按照某种条件几率(A)选择新的盒子,重复该操做;
最终获得观测序列:“白黑白白黑“
状态集合:S={盒子1,盒子2,盒子3}观测集合:O={白,黑}设状态序列和观测序列的长度T=5,并假设以下A,B,π
状态转移几率矩阵A:
观测几率矩阵B:
初始几率分布π:
这时候咱们面对本身假设的A,B,π,那它们获得观测序列“白黑白白黑“的几率是多少?
如今假设条件下,惟一未知得就是状态序列,因此这里就要尝试使用不一样的状态序列,并找到在一个在估计模型下的拥有最大几率的状态序列。
有了状态序列咱们就能够预测再次抽取时发生事件的几率,在这个例子里就是咱们每次到底抽的时那个盒子,可是估计模型是假设的因此在去求状态序列的前面,应该先去求得最优得A,B,π使得在这个模型下观测序列发生得几率最大。
这里便出现了两个问题:
1,如何求得一个估计模型,让观测序列在该模型下发生几率最大。
2,如何求得隐藏得状态序列,让它在最优估计模型下发生得几率最大。
这里为何要求几率最大,便涉及到了最大熵模型。
应用到实际便成了三个问题,就是多一个咱们如何该观测序列在估计模型上出现得几率。
给定模型λ=(A,B,π)和观测序列Q={q1,q2,...,qT},计算模型λ下观测到序列Q出现的几率P(Q|λ)
已知观测序列Q={q1,q2,...,qT},估计模型λ=(A,B,π)的参数,使得在该模型下观测序列P(Q|λ)最大。
给定模型λ=(A,B,π)和观测序列Q={q1,q2,...,qT},求给定观测序列条件几率P(I|Q,λ)最大的状态序列I
前向几率-后向几率指的实际上是在一个观测序列中,时刻t对应的状态为si的几率值转换过来的信息。
因此这两种均可以解决几率计算问题,也就是看懂一个就能够继续下一个问题。
首先写出在状态序列为s_i的状况下,观测序列出现的几率。
前向算法定义:给定λ(A,B,π),定义到时刻t部分观测序列为q1,q2,...,qt且状态为si的几率为前向几率。此时咱们加设β为1,因此表达方程记作:
初值
先计算第一个α:
递推
求出第一个后,递推使t = 1,2,...,T-1
结果
这样状态序列为s_i的状况下,观测序列出现的几率就变成了
[前向传播代码] https://github.com/TimVerion/HMM_code/blob/master/hmm/forward_probability.py 前向传播代码
# 伪代码,不可运行 # 更新初值(t=1) for i in n_range: alpha[0][i] = pi[i] * B[i][fetch_index_by_obs_seq_f(Q, 0)] # 迭代更新其它时刻 T = len(Q) tmp = [0 for i in n_range] for t in range(1, T): for i in n_range: # 1. 计算上一个时刻t-1累积过来的几率值 for j in n_range: tmp[j] = alpha[t - 1][j] * A[j][i] # 2. 更新alpha的值 alpha[t][i] = np.sum(tmp) * B[i][fetch_index_by_obs_seq_f(Q, t)]
后向传播定义:给定λ,定义到时刻t状态为si的前提下,从t+1到T部分观测序列为qt+1,qt+2,...,qT的几率为后向几率。记作:
1. 初值
先计算第一个β,在咱们进行前向算法的时候咱们假设β为1:
递推
求出第一个后,递推使t = T-1,T-2...,1
结果
这样状态序列为s_i的状况下,观测序列出现的几率就变成了:
# 更新初值(t=T) for i in n_range: beta[T - 1][i] = 1 # 迭代更新其它时刻 tmp = [0 for i in n_range] for t in range(T - 2, -1, -1): for i in n_range: # 1. 计算到下一个时刻t+1的几率值 for j in n_range: tmp[j] = A[i][j] * beta[t + 1][j] * B[j][fetch_index_by_obs_seq_f(Q, t +1)] # 2. 更新beta的值 beta[t][i] = np.sum(tmp)
根据几率计算问题咱们能够求的两个能够帮助咱们解决学习问题的几率:
将给定模型λ和观测序列Q的状况下,在时刻t处于状态si的几率,记作:
单个状态几率的意义主要是用于判断在每一个时刻最可能存在的状态,从而能够得到一个状态序列做为最终的预测结果。
推导过程:
将给定模型λ和观测序列Q的状况下,在时刻t处于状态si而且在t+1时刻处于状态sj的概率,记作:
也就是:
若训练数据包含观测序列和状态序列,则HMM的学习问题很是简单,是监督学习算法。咱们甚至在知道观测序列和状态序列的时候咱们能够利用大数定理求出最优模型。
可是咱们的训练数据只包含观测序列,则HMM的学习问题须要使用EM算法求解,是非监督学习算法,这里使用的EM算法也叫作鲍姆韦尔奇。
那么咱们想一下,这里假设全部的观测数据为Q={q1,q2,...,qT},全部的隐状态为I={i1,i2,...,iT},则完整的数据为(O,I),完整数据的对数似然函数为ln(p(Q,I;λ)); 而后直接使用EM算法的方式就能够来进行参数估计了。(EM算法不懂见上)
初始化分布参数
重复下列两个操做直到收敛:
E步骤:估计隐藏变量的几率分布指望函数:
当咱们了解L函数,也就是咱们须要极大化的函数,能够直接对π求导,而后让偏导等于零。
这里写到γ是否是很熟悉,没错就是咱们是上面求的单个状态的几率。
和上一个变量求解同样,咱们须要极大化L
在上面的式子里,咱们求aij也就是A的时候,咱们必须使用单个状态的几率和两个状态的联合几率。
同上咱们对B求偏导,而后让偏导等于零:
通过极大化L函数咱们能够求得π、a、b的值,这样咱们便获得了一个最优模型。
# 1. 迭代更新(EM算法思想类型) for time in range(max_iter): # a. 在当前的pi,A,B的状况下对观测序列Q分别计算alpha、beta、gamma和ksi forward.calc_alpha(pi, A, B, Q, alpha, fetch_index_by_obs_seq_f) backward.calc_beta(pi, A, B, Q, beta, fetch_index_by_obs_seq_f) single.calc_gamma(alpha, beta, gamma) continuous.calc_ksi(alpha, beta, A, B, Q, ksi, fetch_index_by_obs_seq # b. 更新pi、A、B的值 # b.1. 更新pi值 for i in n_range: pi[i] = gamma[0] # b.2. 更新状态转移矩阵A的值 tmp1 = np.zeros(T - 1) tmp2 = np.zeros(T - 1) for i in n_range: for j in n_range: # 获取全部时刻从状态i转移到状态j的值 for t in t_1_range: tmp1[t] = ksi[t][i][j] tmp2[t] = gamma[t] # 更新状态i到状态j的转移几率 A[i][j] = np.sum(tmp1) / np.sum(tm # b.3. 更新状态和观测值之间的转移矩阵 for i in n_range: for k in m_range: tmp1 = np.zeros(T) tmp2 = np.zeros(T) # 获取全部时刻从状态i转移到观测值k的几率和 number = 0 for t in t_range: if k == fetch_index_by_obs_seq_f(Q, t): 若是序列Q中时刻t对应的观测值就是k,那么进行统计这个时刻t为状态i的几率值 tmp1[t] = gamma[t][i] number + tmp2[t] = gamma[t] # 更新状态i到观测值k之间的转移几率 if number == 0: # 没有转移,因此为0 B[i][k] = 0 else: # 有具体值,那么进行更新操做 B[i][k] = np.sum(tmp1) / np.sum(tem2)
Viterbi算法实际是用动态规划的思路求解HMM预测问题,求出几率最大的“路径”,每条“路径”对应一个状态序列。
动态规划是运筹学的一个分支,是求解决策过程最优化的数学方法。把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。
好比斐波那契数列和背包问题都利用了这个思想。
# 1. 计算t=1的时候delta的值 for i in n_range: delta[0][i] = pi[i] * B[i][fetch_index_by_obs_seq_f(Q, 0)] # 2. 更新其它时刻的值 for t in range(1, T): for i in n_range: # 当前时刻t的状态为i # a. 获取最大值 max_delta = -1 for j in n_range: # j表示的是上一个时刻的状态值 tmp = delta[t - 1][j] * A[j][i] if tmp > max_delta: max_delta = tmp pre_index[t][i] = j # b. 更新值 delta[t][i] = max_delta * B[i][fetch_index_by_obs_seq_f(Q, t)] # 3. 解码操做,查找到最大的结果值 decode = [-1 for i in range(T)]
隐马尔可夫模型(HMM)是由马尔可夫过程衍生出的几率图模型,常被用于语音模式识别、生物基因序列标记、金融时间序列预测等。
HMM在咱们生活中无处不在,举个简单的例子:
身边的朋友通常出行有骑共享单车出行的,说下雨就比晴天骑车的人数少,当咱们听朋友说今天外面共享单车被骑没了,咱们能够推断出今每天气不错,这里显式状态是出行,而隐状态是天气。
因此咱们很早就已经会HMM算法的思想了,只是差这几个算法和证实。
这里说的HMM不是买零食的韩梅梅
时间点 t的隐藏条件和时间点 t-1的隐藏条件有关。
由于人类语音拥有先后的关系,能够从语义与发音两点来看:
单字的发音拥有先后关系:例如"They are"经常发音成"They're",或是"Did you"会由于"you"的发音受"did"的影响,经常发音成"did ju",并且语音识别中用句子的发音来进行分析,所以须要考虑到每一个音节的先后关系,才可以有较高的准确率。
句子中的单字有先后关系:从英文文法来看,主词后面经常接助动词或是动词,动词后面接的会是受词或介系词。而或是从单一单字的使用方法来看,对应的动词会有固定使用的介系词或对应名词。所以分析语音频息时须要为了提高每一个单字的准确率,也须要分析先后的单字。
马尔可夫模型将输入消息视为一单位一单位,接着进行分析,与人类语音模型的特性类似。语音系统识别的单位为一个单位时间内的声音。利用梅尔倒频谱等语音处理方法,转换成一个发音单位,为离散型的信息。而马尔可夫模型使用的隐藏条件也是一个个被数据包的 x(t),所以使用马尔可夫模型来处理声音频号比较合适。