Moved description of histogram problems to this chapter.

The kalman filter chapter lead off with a long discussion of the problems
with histograms. That seemed to belong more at the end of the histogram
chapter, so I moved it there.
This commit is contained in:
Roger Labbe 2014-05-09 12:28:56 -07:00
parent 412344fe72
commit 3504351fe6

View File

@ -1,7 +1,7 @@
{
"metadata": {
"name": "",
"signature": "sha256:35f19121bea1b617984e84b0fa7dca20a612d6302af68a65f9d7d24120786c2d"
"signature": "sha256:ed8104ceb49f694c36a56ac93873fcef520772e80c863e6346aeb03f40798c42"
},
"nbformat": 3,
"nbformat_minor": 0,
@ -75,18 +75,13 @@
"collapsed": false,
"input": [
"%matplotlib inline\n",
"from __future__ import print_function, division\n",
"import matplotlib.pyplot as plt\n",
"import bar_plot\n",
"import numpy as np\n",
"\n",
"pos = np.array([0.333, 0.333, 0., 0., 0., 0., 0., 0., 0.333, 0.])\n",
"\n",
"def bar_plot(pos):\n",
" ax = plt.figure().gca()\n",
" x = np.arange(len(pos))\n",
" ax.bar(x, pos)\n",
" plt.xticks(x+0.5, x)\n",
" plt.show()\n",
"\n",
"bar_plot (pos)"
"bar_plot.plot (pos)"
],
"language": "python",
"metadata": {},
@ -106,7 +101,7 @@
"collapsed": false,
"input": [
"pos = hallway * 0.3\n",
"print 'pos =', pos"
"print('pos =', pos)"
],
"language": "python",
"metadata": {},
@ -132,7 +127,7 @@
"collapsed": false,
"input": [
"pos = np.array([0,1,0,0,0,0,0,0,0,0])\n",
"print pos"
"print(pos)"
],
"language": "python",
"metadata": {},
@ -178,8 +173,8 @@
"reading = 1 # 1 is 'door'\n",
"pos = measure (pos, 1, .6, .2)\n",
"\n",
"print pos\n",
"print 'sum =', sum(pos)"
"print(pos)\n",
"print('sum =', sum(pos))"
],
"language": "python",
"metadata": {},
@ -216,9 +211,9 @@
"reading = 1 # 1 is 'door'\n",
"pos = sense (pos, 1, .6, .2)\n",
"\n",
"print 'sum =', sum(pos)\n",
"print 'probability of door =', pos[0]\n",
"print 'probability of wall =', pos[2]"
"print('sum =', sum(pos))\n",
"print('probability of door =', pos[0])\n",
"print('probability of wall =', pos[2])"
],
"language": "python",
"metadata": {},
@ -262,9 +257,9 @@
" return result\n",
" \n",
"pos = np.array([.4, .1, .2, .3])\n",
"print 'pos before update =', pos\n",
"print('pos before update =', pos)\n",
"pos = perfect_update(pos, 1)\n",
"print 'pos after update =', pos\n"
"print('pos after update =', pos)\n"
],
"language": "python",
"metadata": {},
@ -278,7 +273,7 @@
"\n",
"#### Adding Noise to the Update\n",
"\n",
"We want to solve real world problems, and we have already stated that all sensors have noise. Therefore the code above must be wrong. What if the sensor detected our dog moving 1 space, but he actually moved 2 spaces, or 0? Once again this may initially sound like an insummountable problem, but let's just model it in math. Since this is just an example, we will create a pretty simple noise model for the sensor - later in the book we will handle far more sophisticated errors.\n",
"We want to solve real world problems, and we have already stated that all sensors have noise. Therefore the code above must be wrong. What if the sensor reported that our dog moved one space, but he actually moved two spaces, or zero? Once again this may initially sound like an insummountable problem, but let's just model it in math. Since this is just an example, we will create a pretty simple noise model for the sensor - later in the book we will handle far more sophisticated errors.\n",
"\n",
"We will say that when the sensor sends a movement update, it is 80% likely to be right, and it is 10% likely to overshoot one position to the right, and 10% likely to undershoot to the left. That is, if we say the movement was 4 (meaning 4 spaces to the right), the dog is 80% likely to have moved 4 spaces to the right, 10% to have moved 3 spaces, and 10% to have moved 5 spaces.\n",
"\n",
@ -301,7 +296,7 @@
"\n",
"p = np.array([0,0,0,1,0,0,0,0])\n",
"res = update (p, 2, .8, .1, .1)\n",
"print res"
"print(res)"
],
"language": "python",
"metadata": {},
@ -320,7 +315,7 @@
"input": [
"p = np.array([0, 0, .4, .6, 0, 0, 0, 0])\n",
"res = update (p, 2, .8, .1, .1)\n",
"print res"
"print(res)"
],
"language": "python",
"metadata": {},
@ -339,7 +334,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
"bar_plot (res)"
"bar_plot.plot (res)"
],
"language": "python",
"metadata": {},
@ -359,8 +354,8 @@
"pos = [1.0,0,0,0,0,0,0,0,0,0]\n",
"for i in range (500):\n",
" pos = update(pos, 1, .8, .1, .1)\n",
"print pos\n",
"bar_plot(pos)"
"print(pos)\n",
"bar_plot.plot(pos)"
],
"language": "python",
"metadata": {},
@ -380,8 +375,8 @@
"pos = [1.0,0,0,0,0,0,0,0,0,0]\n",
"for i in range (100):\n",
" pos = update(pos, 1, .8, .1, .1)\n",
"print pos\n",
"bar_plot(pos)"
"print(pos)\n",
"bar_plot.plot(pos)"
],
"language": "python",
"metadata": {},
@ -411,7 +406,7 @@
"print(p)\n",
"p = update(p, 1, .8, .1, .1)\n",
"print(p)\n",
"bar_plot(p)"
"bar_plot.plot(p)"
],
"language": "python",
"metadata": {},
@ -430,7 +425,7 @@
"input": [
"p = sense(p, 1, .6, .2)\n",
"print(p)\n",
"bar_plot(p)"
"bar_plot.plot(p)"
],
"language": "python",
"metadata": {},
@ -449,7 +444,7 @@
"input": [
"p = update(p, 1, .8, .1, .1)\n",
"p = sense(p, 0, .6, .2)\n",
"bar_plot(p)"
"bar_plot.plot(p)"
],
"language": "python",
"metadata": {},
@ -468,7 +463,7 @@
"input": [
"p = update(p, 1, .8, .1, .1)\n",
"p = sense(p, 0, .6, .2)\n",
"bar_plot(p)"
"bar_plot.plot(p)"
],
"language": "python",
"metadata": {},
@ -503,8 +498,8 @@
"for m in measurements:\n",
" pos = sense(pos, m, .6, .2)\n",
" pos = update(pos, 1, .8, .1, .1)\n",
"bar_plot(pos)\n",
"print pos"
"bar_plot.plot(pos)\n",
"print(pos)"
],
"language": "python",
"metadata": {},
@ -523,7 +518,7 @@
"input": [
"pos = sense(pos, m, .6, .2)\n",
"pos = update(pos, 1, .8, .1, .1)\n",
"bar_plot(pos)"
"bar_plot.plot(pos)"
],
"language": "python",
"metadata": {},
@ -545,7 +540,7 @@
"for m in measurements:\n",
" pos = sense(pos, m, .6, .2)\n",
" pos = update(pos, 1, .8, .1, .1)\n",
"bar_plot(pos)"
"bar_plot.plot(pos)"
],
"language": "python",
"metadata": {},
@ -558,6 +553,46 @@
"As you can see we quickly filtered out the bad sensor reading and converged on the most likely positions for our dog."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Drawbacks and Limitations to the Discrete Bayesian Filter\n",
"\n",
"Do not be mislead by the simplicity of the examples I chose. This is a robust and complete implementation of a histogram filter, and you may use the code in real world solutions. If you need a multimodal, discrete filter, this filter works.\n",
"\n",
"With that said, while this filter is used in industry, it is not used often because it has several limitations. Getting around those limitations is the motivation behind the chapters in the rest of this book.\n",
"\n",
"The first problem is scaling. Our dog tracking problem used only one variable, $pos$, to denote the dog's position. Most interesting problems will want to track several things in a large space. Realistically, at a minimum we would want to track our dogs $(x,y)$ coordinate, and probably his velocity $(\\dot{x},\\dot{y})$ as well. We have not covered the multidimensional case, but instead of a histogram we use a multidimensional grid to store the probabilities at each discrete location. Each *sense()* and *update()* step requires updating all values in the grid, so a simple four variable problem would require $O(n^4)$ running time *per time step*. Realistic filters have 10 or more variables to track, leading to exhorbinant computation requirements.\n",
"\n",
"The second problem is that the histogram is discrete, but we live in a continuous world. The histogram requires that you model the output of your filter as a set of discrete points. In our dog in the hallway example, we used 10 positions, which is obviously far too few positions for anything but a toy problem. For example, for a 100 meter hallway you would need 10,000 positions to model the hallway to 1cm accuracy. So each sense and update operation would entail performing calculations for 10,000 different probabilities. It gets exponentially worse as we add dimensions. If our dog was roaming in a $100x100 m^2$ courtyard, we would need 100,000,000 bins ($10,000^2$) to get 1cm accuracy.\n",
"\n",
"A third problem is that the histogram is multimodal. This is not always a problem - an entire class of filters, the particle filters, are multimodal and are often used because of this property. But imagine if the GPS in your car reported to you that it is 40% sure that you are on D street, but 30% sure you are on Willow Avenue. I doubt that you would find that useful. Also, GPSs report their error - they might report that you are at $(109.878W, 38.326N)$ with an error of $9m$. There is no clear mathematical way to extract error information from a histogram. Heuristics suggest themselves to be sure, but there is no exact determination. You may or may not care about that while driving, but you surely do care if you are trying to send a rocket to Mars or track and hit an oncoming missle.\n",
"\n",
"This difficulty is related to the fact that the filter often does not represent what is physically occuring in the world. Consider this distribution for our dog:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"p = [0.2245871, 0.06288015, 0.06109133, 0.0581008, 0.09334062, 0.2245871,\n",
" 0.06288015, 0.06109133, 0.0581008, 0.09334062]\n",
"bar_plot.plot(p) "
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" The largest probabilities are in position 0 and position 5. This does not fit our physical intuition at all. A dog cannot be in two places at once (my dog Simon certainly tries - his food bowl and my lap often have equal allure to him). We would have to use heuristics to decide how to interpret this distribution, and there is usually no satisfactory answer. This is not always a weakness - a considerable amount of literature has been written on *Multi-Hypothesis Tracking (MHT)*. We cannot always distill our knowledge to one conclusion, and MHT uses various techniques to maintain multiple story lines at once, using backtracking schemes to go *back in time* to correct hypothesis once more information is known. This will be the subject of later chapters. In other cases we truly have a multimodal situation - we may be optically tracking pedistrians on the street and need to represent all of their positions. \n",
" \n",
"In practice it is the exponential increase in computation time that leads to this filter being the least frequently used of all filters in this book. Many problems are best formulated as discrete or multimodal, but we have other filter choices with better performance. With that said, if I had a small problem that this technique could handle I would choose to use it; it is trivial to implement, debug, and understand, all virtues in my book."
]
},
{
"cell_type": "markdown",
"metadata": {},
@ -582,7 +617,6 @@
"\n",
"Finally, the bar charts may strike you as being a bit less certain than we would want. A 25% certaintly may not give you a lot of confidence in the anwser. Of course, what is important here is the ratio of this probability to the other probabilities in your vector. If the next largest bar is 23% then we are not very knowledgable about our position, whereas if the next largest is 3% we are in fact quite certain. But this is not clear or intuitive. However, there is an extremely important insight that Kalman filters implement that will signficantly improve our accuracy from the same data.\n",
"\n",
"Do not be mislead by the simplicity of the example I chose. This is a robust and complete implementation of a histogram filter, and you may use the code in complicated, real world solutions. If you need a multimodal, discrete filter, this filter works.\n",
"\n",
"**If you can understand this chapter you will be able to understand and implement Kalman filters** I cannot stress this enough. If anything is murky, go back and reread this chapter and play with the code. the rest of this book will build on the algorithms that we use here. If you don't intuitively understand why this histogram filter works, and can at least work through the math, you will have little success with the rest of the material. However, if you grasp the fundamental insight - multiplying probabilities when we measure, and shifting probabilities when we update leads to a converging solution - then you understand everything important you need to grasp the Kalman filter. "
]