【易懂教程】我是如何十分钟理解与推导贝叶斯滤波(Bayes Filter)算法?

“很多时候一些算法看起来极其复杂,极其难懂。不是因为我们愚不可及。而是因为我们看到的已经是别人省略过很多步骤和省略很多脑海中思考过的思路最后呈现出的公式和文字。而好的博客就是应该尽量还原这些思考过程以及省略掉的步骤。”——@Ai酱

像卡尔曼滤波(Kalman filters)、粒子滤波(Particle filters),隐含马尔科夫模型(Hidden Markov models),动态贝叶斯网络(Dynamic Bayesian networks)等等算法。这些算法是贝叶斯滤波算法的具体实现.因此学好了贝叶斯滤波再学其他算法那就容易很多了。注意:贝叶斯滤波只提供了一种思想,卡尔曼滤波就是对这个思想的其中一种实现。

破解概念上的束缚之贝叶斯滤波算法到底有什么用?

学东西最烦的是看了半个月的算法细节,结果发现自己还是不知道这算法有什么用,怎么实现。今天博主就开篇破解贝叶斯中的概念上的障碍。让大家快速学习贝叶斯滤波算法,并且能够用到自己的项目中。贝叶斯滤波算法它做的工作就是根据已有的信息来计算概率。比如我想根据一些信息识别某个人性别是不是女,那贝叶斯滤波算法要做的是就是计算这个人是女的概率P(女)。来了新的信息就计算新的概率。。如果你不理解这句话看接下来这个例子你就懂了。假如现在贝叶斯滤波算法是要根据你已输入的信息分析某个人是男是女。贝叶斯滤波算法最终的输出是计算出根据现有信息判断这个人是男性的概率是多少,女性的概率是多少。然后你的算法就选择概率更大的那种情况输出结果。如果有新的信息进来(比如“那个人有长头发”),贝叶斯算法要重新计算这个人是男性的概率是多少,女性的概率是多少。

那它具体怎么做的呢?
当你什么信息都不提供给贝叶斯滤波算法的时候,然后你问贝叶斯算法那个人的性别是女的概率是多少。贝叶斯滤波算法会告诉你P(女)=0.5。注意:P(女)=0.5这个表示的含义是“根据已有信息,那个人是女性概率是0.5”. 现在P(女)=P(男)=0.5我们是没法判断性别。这个数值“0.5”是我们设置的一个初始值,一般是需要根据你的统计经验设置的(如果你是想用贝叶斯滤波算法进行垃圾邮件识别,那么它是垃圾邮件这个概率肯定不会有0.5这么大。毕竟垃圾邮件还是少数。你需要统计收到的邮件中垃圾邮件的占比,然后作为算法的初始值。好让算法在没有任何提示信息的情况下能输出当前邮件是垃圾邮件的概率)。
然后,回到性别识别那个问题。

当你告诉算法这个人有长头发,你再问算法这个人现在性别是女的概率是多少。贝叶斯滤波算法会根据概率论中的条件概率知识算出“在知道某个人有长头发的条件下,这个人性别是女的概率P(女)=0.87”。至于它到底怎么算的文章后面会讲。现在你只需要对整个算法有个直观理解即可。为什么它能知道根据“有长头发”这个信息来更新概率呢?这是因为算法需要我们告诉它“长头发中女性占比是多少(这个叫做先验知识)”,P(女)=0.87这个也是需要我们经过统计才能得到的数据

当你再告诉算法这个人使用口红,然后你再问算法这个人现在性别是女的概率是多少?贝叶斯滤波算法会根据概率论中条件概率知识,以及需要你告诉它“使用口红的人中女性占比是多少”,来更新当前这个人是女性的概率P(女)=0.91。

以上就是贝叶斯算法做的工作。现在我想聪明的你已经对贝叶斯滤波算法已经有了一个直观的理解。我总结一下贝叶斯滤波算法做的工作:它做的工作就是根据不断接收到的新信息和我提供的一些已经知道的统计值,来不断更新概率。更新概率值的方法是根据概率论中的条件概率计算公式来更新的。贝叶斯滤波算法计算的结果是一个概率值有什么用呢
比如我要它根据我提供的一些信息识别某个人是不是女,那它就得计算这个人是女的概率P(女).如果我想让它根据雷达测距判断机器人离障碍物距离,那它就得计算出机器人离障碍物各种距离取值的概率(为何要计算概率?因为雷达测量会存在误差),比如计算机器人离障碍物10cm远的概率是0.87,离障碍物11cm远的概率是0.21,离障碍物9cm远的概率是0.01。那么我就认为机器人离障碍物距离是10cm。

贝叶斯滤波算法怎么随着收到的新信息来更新概率的?

还是以前面的根据已有信息识别性别例子举例。我们要想识别一个人是否是女性,现在要贝叶斯滤波算法做的就是需要它计算出根据当前信息判断当前这个人是女的概率P(女)。
我们已经知道的先验知识是(这些数据是我们统计到的,你项目中的这些先验知识有些是需要统计得到,有些是需要建模比如假设它是正态分布等等)
在没有任何信息的情况下初始值:P(女)=0.5
留有长头发的人中女性占比:0.8。
使用口红的人中女性占比:0.9

那么在没有任何额外信息的情况下,贝叶斯滤波认为当前这个人是女性的概率P(女)=0.5
当新知道当前这个人留有长头发这个信息时,怎么更新概率值呢?
此时当前这个人是女性的概率可以这么表示P(女|长头发), 这个表达式的意思是在知道现在这个人的长头发的条件下女性的概率。
事实上这个值就是我们在先验知识中已知的“留有长头发的人中女性占比”,即0.8。你会说万一我不知道留有长头发中的人之中女性占比呢?这意味着我们需要用概率论中的条件概率知识求解P(女|长头发)。(如果你对条件概率怎么求还不清楚可以参考这篇文章十分钟复习概率论知识)。根据概率论知识我们知道P()=P()P()=P()P()P()P(女|长头发)=\frac {P(女 并且有 长头发)}{P(长头发)}=\frac {P(长头发|女)P(女)}{P(长头发)}。所以我们有两种方式可以求P(女|长头发)。

  1. 如果我们知道长头发的人占总人口比例即P(长头发),并且还知道有长头发的女性占总人口的比例即P(女 并且有 长头发),那么就用P()=P()P()P(女|长头发)=\frac {P(女 并且有 长头发)}{P(长头发)}这种方式求留有长头发的人中女性占比P(女|长头发)。

  2. 如果我们知道长头发的人占总人口比例即P(长头发),而且还知道女性中留有长头发的人占比P(长头发|女),并且还知道女性占总人口比例P(女)。那么就用P()=P()P()P()P(女|长头发)=\frac {P(长头发|女)P(女)}{P(长头发)}这个方式求解。

你已知什么先验知识那就用什么方式求解,贝叶斯滤波通常是用P()=P()P()P()P(女|长头发)=\frac {P(长头发|女)P(女)}{P(长头发)}这种方式求解。这是因为这种方式在在实际应用场景中这个公式中需要的先验知识更容易获得。你在实际实现贝叶斯滤波算法时候只需要考虑你能够知道公式中的哪些先验知识概率值,然后再确定用哪种方式求P()P(女|长头发)

现在你已经学会了贝叶斯滤波算法你一定会问那为何很多书上感觉贝叶斯滤波算法比这个复杂得多啊。这是实际应用中往往是会同时接收到多个信息。即P(女|长头发, 有口红)这种形式,这个表示在知道一个人长头发,并且有口红的条件下它是女性的概率是多少。然后书上或者博客省略了很多化简步骤直接告诉你P(,)=P()P()P()P(女|长头发, 有口红)=\frac{P(长头发|女,有口红)P(女|有口红)}{P(长头发|有口红)}省略了这么多当然这个你自然看不懂,而且事实上有时候这种求P(女|长头发, 有口红)的方式里面的先验知识你压根就不知道,比如P(长头发|有口红)这个先验知识值你不知道怎么可能求出这个公式P(,)=P()P()P()P(女|长头发, 有口红)=\frac{P(长头发|女,有口红)P(女|有口红)}{P(长头发|有口红)}

我将还原这个公式的推导过程P(,)=P()P()P()P(女|长头发, 有口红)=\frac{P(长头发|女,有口红)P(女|有口红)}{P(长头发|有口红)}。相信你看完下面这个推导会有所收获。
以下:
根据定义我们可以知道P(女|长头发, 有口红)就是同时具备“长头发, 有口红”这个特征的人中,具备“女,长头发, 有口红”这三个标签的人所占的比例。所以得到:
P(,)=P(,,)P(,)P(女|长头发, 有口红)=\frac{P(女,长头发, 有口红)}{P(长头发,有口红)}
然后分子P(女,长头发, 有口红)这个联合概率可以变成一个条件概率公式。分母P(长头发,有口红)这也是联合概率
P(,)=P(,,)P(,)=P(,)P(,)P()P()=P(,)P()P()P()P()=P(,)P()P()P(女|长头发, 有口红)=\frac{P(女,长头发, 有口红)}{P(长头发,有口红)}=\frac{P(长头发|女, 有口红)P(女, 有口红)}{P(长头发|有口红)P(有口红)}=\frac{P(长头发|女, 有口红)P(女| 有口红)P(有口红)}{P(长头发|有口红)P(有口红)}=\frac{P(长头发|女, 有口红)P(女| 有口红)}{P(长头发|有口红)}
以上。

只要我们知道P(长头发|女, 有口红)、P(女| 有口红)、P(长头发|有口红)这三个值,那我们就可以求得P(女|长头发, 有口红),即可以算出在知道一个人有长头发、有口红的情况下这个人是女性的概率。如果这个概率值大于0.5那就可以认为根据已有的知识我们可以认为现在这个人是女性,如果小于0.5那就认为现在这个人是男性。如果不知道P(长头发|女, 有口红)、P(女| 有口红)、P(长头发|有口红)这三个值怎么求呢?
我们用定义也是可以求P(女|长头发, 有口红)的,比如下面这个公式:
P(,)=P(,,)P(,)P(女|长头发, 有口红)=\frac{P(女,长头发, 有口红)}{P(长头发,有口红)}

后面的内容是贝叶斯滤波公式推导,如果你想先多了解下贝叶斯滤波的具体实践可以看看这篇文章<[易懂实例讲解]离散型贝叶斯滤波python编程代码实践>

机器人状态估计中的贝叶斯滤波

如果你是为了机器人状态估计而学习贝叶斯滤波的那欢迎继续看下去。如果你只是想了解贝叶斯滤波怎么做的那你已经学会了,你可以完成点赞这个仪式后离开当前页面。为什么我还继续讲讲机器人状态估计下的贝叶斯滤波?因为机器人状态估计中的贝叶斯滤波里面省略了非常多的假设和细节。我想尝试着将这些细节和省略掉的假设还原

机器人状态估计到底是什么?

一句话说清楚机器人状态估计就是:根据机器人之前的状态,传感器观测数据和控制器控制命令来估计当前机器人的状态。那么什么是机器人状态?机器人离障碍物距离,机器人的速度,机器人的姿态,机器人在世界坐标系下的地址这些都是机器人的状态。我就以机器人离某个障碍物的距离作为机器人状态来举例,假设机器人在时刻t,它观测到自己离障碍物距离是ztz_t,它控制自己移动的命令是让它移动utu_t这么远的距离,算法根据传感器数据和控制器数据估计出离某个障碍物的距离是xtx_t,算法上个时刻估算出的距离是xt1x_{t-1}

由于传感器,控制器,上个状态这些数据总会有误差。我怎么知道当前估计出机器人离障碍物距离xtx_t是不是正确的呢?答:计算概率P(xtzt,ut,xt1)P(x_t|z_t,u_t,x_{t-1})。只要这个概率有80%那不就是大概率是对的。P(xtzt,ut,xt1)P(x_t|z_t,u_t,x_{t-1})这个概率公式指的是在知道传感器数据是ztz_t,控制器数据是utu_t,上个状态是xt1x_{t-1}的情况下当前状态是xtx_t的概率。

现在我们已知:

  • P(ztxt)P(z_t|x_t),这个表示的含义是:当机器人处于xtx_t这个状态时,它观测值是ztz_t的概率。这个是观测模型,需要我们自己建模,不同的传感器肯定是不一样的,比如我们设计一种函数f(xt,zt)f(x_t,z_t)它的值就是P(ztxt)P(z_t|x_t)。这个就是卡尔曼滤波要做的事,卡尔曼滤波设计的函数就是认为这个概率函数是一个正态分布(高斯分布)。
  • P(xtxt1,ut)P(x_t|x_{t-1},u_t),这个表示的含义是:当机器人上个状态是xt1x_{t-1},然后它采取的动作(控制命令)是utu_t时,机器人的状态是xtx_t的概率。这个是控制模型,也是需要我们自己建模不同的模型不一样。(卡尔曼滤波是认为这个控制模型是一个线性模型)
  • P(utxt1)P(u_t|x_{t-1}),这个表示的含义是:当机器人处于xt1x_{t-1}这个状态时做出utu_t的动作概率。
    机器人状态估计中的假设:
  • 假设当前观测值ztz_t只与当前状态xtx_t有关,跟机器人的控制命令utu_t和上个状态xt1x_{t-1}无关。
  • 假设当前状态xtx_t只与上个时刻状态xt1x_{t-1}以及与控制命令utu_t有关。

好推理开始:

  1. 根据定义有:
    P(xtzt,ut,xt1)=P(xt,zt,ut,xt1)P(zt,ut,xt1)P(x_t|z_t,u_t,x_{t-1})=\frac {P(x_t,z_t,u_t,x_{t-1})}{P(z_t,u_t,x_{t-1})}
  2. 由于含有ztz_t的只有一个已知,并且是一个条件概率ztz_t还在竖线的坐边,因此我们把所有的含有ztz_t的联合概率用ztz_t都在坐边的那种形式的条件概率表示.
    P(xtzt,ut,xt1)=P(ztxt,ut,xt1)P(xt,ut,xt1)P(ztut,xt1)P(ut,xt1)P(x_t|z_t,u_t,x_{t-1})=\frac {P(z_t|x_t,u_t,x_{t-1})P(x_t,u_t,x_{t-1})}{P(z_t|u_t,x_{t-1})P(u_t,x_{t-1})}
  3. 由于我们已知P(utxt1)P(u_t|x_{t-1}),因此我们把上式的分母P(ut,xt1)P(u_t,x_{t-1})也变成条件概率形式。
    P(xtzt,ut,xt1)=P(ztxt,ut,xt1)P(xt,ut,xt1)P(ztut,xt1)P(utxt1)P(xt1))P(x_t|z_t,u_t,x_{t-1})=\frac {P(z_t|x_t,u_t,x_{t-1})P(x_t,u_t,x_{t-1})}{P(z_t|u_t,x_{t-1})P(u_t|x_{t-1})P(x_{t-1}))}
  4. 由于我们还已知P(xtxt1,ut)P(x_t|x_{t-1},u_t),所以我们把上式分子中的P(xt,ut,xt1)P(x_t,u_t,x_{t-1})变成一个条件概率。
    P(xtzt,ut,xt1)=P(ztxt,ut,xt1)P(xtut,xt1)P(ut,xt1)P(ztut,xt1)P(utxt1)P(xt1))P(x_t|z_t,u_t,x_{t-1})=\frac {P(z_t|x_t,u_t,x_{t-1})P(x_t|u_t,x_{t-1})P(u_t,x_{t-1})}{P(z_t|u_t,x_{t-1})P(u_t|x_{t-1})P(x_{t-1}))}
  5. 现在分子出现了和第3步一样的P(ut,xt1)P(u_t,x_{t-1})。我们一样把它变成这种条件概率P(utxt1)P(u_t|x_{t-1})形式。
    P(xtzt,ut,xt1)=P(ztxt,ut,xt1)P(xtut,xt1)P(utxt1)P(xt1)P(ztut,xt1)P(utxt1)P(xt1))P(x_t|z_t,u_t,x_{t-1})=\frac {P(z_t|x_t,u_t,x_{t-1})P(x_t|u_t,x_{t-1})P(u_t|x_{t-1})P(x_{t-1})}{P(z_t|u_t,x_{t-1})P(u_t|x_{t-1})P(x_{t-1}))}
  6. 分子分母同时消去P(xt1),P(utxt1)P(x_{t-1}),P(u_t|x_{t-1})
    P(xtzt,ut,xt1)=P(ztxt,ut,xt1)P(xtut,xt1)P(ztut,xt1)P(x_t|z_t,u_t,x_{t-1})=\frac {P(z_t|x_t,u_t,x_{t-1})P(x_t|u_t,x_{t-1})}{P(z_t|u_t,x_{t-1})}
    在前面中我们知道机器人状态估计中有几个假设:
  • 首先是假设当前观测值ztz_t只与当前状态xtx_t有关,跟机器人的控制命令utu_t和上个状态xt1x_{t-1}无关。这意味着分子中的P(ztxt,ut,xt1)=P(ztxt)P(z_t|x_t,u_t,x_{t-1})=P(z_t|x_t),并且分母中的P(ztut,xt1)=P(zt)P(z_t|u_t,x_{t-1})=P(z_t)
    所以:
    P(xtzt,ut,xt1)=P(ztxt)P(xtut,xt1)P(zt)P(x_t|z_t,u_t,x_{t-1})=\frac {P(z_t|x_t)P(x_t|u_t,x_{t-1})}{P(z_t)}
    现在分子已经都是已知量,分母那个1P(zt)\frac{1}{P(z_t)}是一个与xtx_t无关的常量,一般用η\eta表示。
    P(xtzt,ut,xt1)=ηP(ztxt)P(xtut,xt1)P(x_t|z_t,u_t,x_{t-1})=\eta P(z_t|x_t)P(x_t|u_t,x_{t-1})
    这就是我们在机器人状态估计中最常见的公式,无论是贝叶斯估计还是卡尔曼滤波都是这个公式。现在我已经将它推导的细节进行了还原。

以上。

posted @ 2019-07-30 20:01  varyshare|李韬  阅读(820)  评论(0编辑  收藏  举报