[易懂实例讲解]离散型贝叶斯滤波python编程代码实践

本文是从例子的角度来讲解贝叶斯滤波。如果你想看贝叶斯滤波的理论推导的话可以看这篇文章《我是如何十分钟理解与推导贝叶斯滤波(Bayes Filter)算法?》。不懂贝叶斯滤波理论也凭直觉可以看懂本文的例子和Python代码实践。

例子的背景介绍

假设有一个机器人它在困在一个管子里面了,只能前进或后退。管子的长度是20cm。机器人收到"前进"命令后有三种可能“有25%概率不执行,有50%概率前进1cm,有25%概率前进2cm”。当然也有特殊情况当机器人离端点只有1cm的时候那么它“25%概率不执行命令,75%概率只走1cm”。当机器人就在端点的时候它就卡住了。现在机器人在11cm那个地方,我向它发送了9个“前进”控制命令。问机器人执行完这9个命令后在各个位置的概率各是多少(即求机器人位于各个位置的概率分布)。

分析

初始位置它是在11cm那个地方,这意味着机器人位于其他19个地方概率是0, 而11cm那个地方的概率是1. 注意:机器人位于这20个地方的概率之和加起来要等于1 (因为他们是一个概率分布里面的)。
概率数组表示就是下面酱紫:
[0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]

接下来我们分析下它收到第一个前进命令会怎么操作

从前面的背景信息可以看到现在机器人在第11位所以有三种情况(只有在靠近端点才可能少于3种)

  1. 25%概率不执行命令
  2. 50%概率前进1位
  3. 25%概率前进2位

所以概率数组更新为
[0 0 0 0 0 0 0 0 0 0 1*0.25 1*0.5 1*0.25 0 0 0 0 0 0 0]=[0 0 0 0 0 0 0 0 0 0 0.25 0.5 0.25 0 0 0 0 0 0 0]

接下来看它收到第二个前进命令如何变化

它现在仍然没有靠近端点的这种特殊情况。但是有点复杂了。因为有三个位置(11位,12位,13位)需要考虑。
仅考虑当机器人在第11位的情况(用0代替12位和13位的概率值影响)
[0 0 0 0 0 0 0 0 0 0 0.25*0.25 0.25*0.5 0.25*0.25 0 0 0 0 0 0 0]
现在仅考虑当机器人在第12位的情况(用0代替11位和13位的概率值影响)
[0 0 0 0 0 0 0 0 0 0 0 0.5*0.25 0.5*0.5 0.5*0.25 0 0 0 0 0 0]
现在仅考虑当机器人在第13位的情况(用0代替11位和12位的概率值影响)
[0 0 0 0 0 0 0 0 0 0 0 0 0.25*0.25 0.25*0.5 0.25*0.25 0 0 0 0 0]
因此收到第二个前进命令后的最终概率数组变化为前面这个三种情况的概率数组之和:
[0 0 0 0 0 0 0 0 0 0 0.25*0.25 0.25*0.5 0.25*0.25 0 0 0 0 0 0 0]+[0 0 0 0 0 0 0 0 0 0 0 0.5*0.25 0.5*0.5 0.5*0.25 0 0 0 0 0 0]+[0 0 0 0 0 0 0 0 0 0 0 0 0.25*0.25 0.25*0.5 0.25*0.25 0 0 0 0 0]

后面的变化就更复杂了我们用一段Python代码实现它(检验代码写错了没的标准是20个数加起来是否等于1)。

# -*- coding: utf-8 -*-
"""

@author: 知乎@Ai酱
"""

import numpy as np
prob = np.hstack((np.zeros(10),1,np.zeros(9)))
prob_update = np.zeros(20)
for _ in range(9):# 前进9次
    for i in range(prob.shape[0]):
        if i == (prob.shape[0]-1): # 如果就是在端点那就会100%不执行任何操作
            prob_update[i] += prob[i]
            pass
        elif i == (prob.shape[0]-2): 
            # 如果是离端点只有一位那25%不执行任何操作,75%跳到下一位
            prob_update[i] += prob[i]*0.25
            prob_update[i+1] += prob[i]*0.75
            pass
        else:
            # 只要i不是靠近端点那就有三种情况
            prob_update[i] += prob[i]*0.25
            prob_update[i+1] += prob[i]*0.5
            prob_update[i+2] += prob[i]*0.25
            pass
        pass
    prob = prob_update
    print(np.sum(prob))
    prob_update = np.zeros(20)
    pass

import matplotlib.pyplot as plt
plt.xticks(np.arange(0, 20, 1))
plt.imshow(np.expand_dims(prob,axis=0),cmap=plt.get_cmap('Greys'))
   # -*- coding: utf-8 -*-
"""

@author: 知乎@Ai酱
"""

import numpy as np
prob = np.hstack((np.zeros(10),1,np.zeros(9)))
prob_update = np.zeros(20)
for _ in range(9):# 前进9次
    for i in range(prob.shape[0]):
        if i == (prob.shape[0]-1): # 如果就是在端点那就会100%不执行任何操作
            prob_update[i] += prob[i]
            pass
        elif i == (prob.shape[0]-2): 
            # 如果是离端点只有一位那25%不执行任何操作,75%跳到下一位
            prob_update[i] += prob[i]*0.25
            prob_update[i+1] += prob[i]*0.75
            pass
        else:
            # 只要i不是靠近端点那就有三种情况
            prob_update[i] += prob[i]*0.25
            prob_update[i+1] += prob[i]*0.5
            prob_update[i+2] += prob[i]*0.25
            pass
        pass
    prob = prob_update
    print(np.sum(prob))
    prob_update = np.zeros(20)
    pass

import matplotlib.pyplot as plt
plt.xticks(np.arange(0, 20, 1))
plt.imshow(np.expand_dims(prob,axis=0),cmap=plt.get_cmap('Greys'))

可以看到经过9次执行命令机器人很大概率是在第20位(下面这个图下标是从0开始)。
在这里插入图片描述
你的赞和关注是我更新的动力!
相关文章:

原文地址:https://www.cnblogs.com/ailitao/p/11787532.html