├── .gitignore
├── imgs
└── header.png
├── index.ipynb
├── jupyterbasics
├── JupyterBasics.ipynb
└── imgs
│ ├── header.png
│ ├── jupyter.jpg
│ └── toolbar.png
├── ml
├── cv_hyperparameter_tuning.ipynb
├── data
│ └── data-demo.pkl
├── feature_visualization.ipynb
├── gesture_recognition.pdf
└── simple_classification.ipynb
├── optimization
├── imgs
│ ├── .DS_Store
│ ├── chi-homepage.png
│ ├── gui-design.png
│ ├── header.png
│ ├── history.png
│ ├── integration-with-ucd.png
│ ├── interactive-optimization.png
│ ├── landscapes.png
│ ├── login-dialogue.png
│ ├── menus.png
│ ├── multi-objective.png
│ ├── multidisciplinary-overview.png
│ ├── optimality.png
│ ├── optimization.png
│ ├── overview.png
│ ├── problem-sizes.png
│ ├── representations.png
│ ├── result-100000.png
│ ├── results-gallery.png
│ ├── sa-pseudocode.png
│ ├── sa.jpg
│ ├── scatterplots.png
│ ├── simulated-annealing.gif
│ ├── summary.png
│ ├── toolbar.png
│ ├── ucd-with-ML.png
│ └── ucd.png
├── layout_optimization.ipynb
└── render.py
├── probabilisticfiltering
├── LICENSE
├── ProbabilisticFiltering.ipynb
├── README.md
├── gestures.py
├── gestures.txt
└── imgs
│ ├── brain_inference.png
│ ├── brain_inference.svg
│ ├── brain_space_bottleneck_reversed.svg
│ ├── brain_space_bottleneck_reversed_simple.svg
│ ├── brainspace.png
│ ├── capture.png
│ ├── control_loop.png
│ ├── control_loop.svg
│ ├── finger_sequence.png
│ ├── finger_track.png
│ ├── finger_track.svg
│ ├── fwd_inv.png
│ ├── fwd_inv.svg
│ ├── gesture.png
│ ├── gesture.svg
│ ├── header.png
│ ├── header.svg
│ ├── header2.svg
│ ├── header3.svg
│ ├── phase.gif
│ ├── stochastic.png
│ ├── stochastic.svg
│ ├── svm.jpg
│ └── undo.jpg
└── statisticaldecoding
└── statisticaldecoding.ipynb
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 |
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 |
33 | # Installer logs
34 | pip-log.txt
35 | pip-delete-this-directory.txt
36 |
37 | # Unit test / coverage reports
38 | htmlcov/
39 | .tox/
40 | .coverage
41 | .coverage.*
42 | .cache
43 | nosetests.xml
44 | coverage.xml
45 | *,cover
46 | .hypothesis/
47 |
48 | # Translations
49 | *.mo
50 | *.pot
51 |
52 | # Django stuff:
53 | *.log
54 | local_settings.py
55 |
56 | # Flask stuff:
57 | instance/
58 | .webassets-cache
59 |
60 | # Scrapy stuff:
61 | .scrapy
62 |
63 | # Sphinx documentation
64 | docs/_build/
65 |
66 | # PyBuilder
67 | target/
68 |
69 | # IPython Notebook
70 | .ipynb_checkpoints
71 |
72 | # pyenv
73 | .python-version
74 |
75 | # celery beat schedule file
76 | celerybeat-schedule
77 |
78 | # dotenv
79 | .env
80 |
81 | # virtualenv
82 | venv/
83 | ENV/
84 |
85 | # Spyder project settings
86 | .spyderproject
87 |
88 | # Rope project settings
89 | .ropeproject
90 |
--------------------------------------------------------------------------------
/imgs/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/imgs/header.png
--------------------------------------------------------------------------------
/index.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "
\n",
8 | "\n",
9 | "---------------\n",
10 | "\n",
11 | "## Course Index\n",
12 | "\n",
13 | "* [Designing layouts with combinatorial optimization](optimization/layout_optimization.ipynb)\n",
14 | "* Machine learning for gesture recognition\n",
15 | " * [Gesture recogntion notes](ml/gesture_recognition.pdf)\n",
16 | " * [Simple Classification](ml/simple_classification.ipynb)\n",
17 | " * [Feature Visualization](ml/feature_visualization.ipynb)\n",
18 | " * [Hyperparamer tuning](ml/cv_hyperparameter_tuning.ipynb)\n",
19 | "* [Robust motion-based interfaces using probabilistic state tracking](probabilisticfiltering/probabilisticfiltering.ipynb)\n",
20 | "* [Probabilistic decoding for intelligent text entry](statisticaldecoding/statisticaldecoding.ipynb)\n",
21 | "\n",
22 | "----\n",
23 | "\n",
24 | "**New to Jupyter? [Quickstart tutorial](jupyterbasics/JupyterBasics.ipynb).**"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {
31 | "collapsed": true
32 | },
33 | "outputs": [],
34 | "source": []
35 | }
36 | ],
37 | "metadata": {
38 | "kernelspec": {
39 | "display_name": "Python 2",
40 | "language": "python",
41 | "name": "python2"
42 | },
43 | "language_info": {
44 | "codemirror_mode": {
45 | "name": "ipython",
46 | "version": 2
47 | },
48 | "file_extension": ".py",
49 | "mimetype": "text/x-python",
50 | "name": "python",
51 | "nbconvert_exporter": "python",
52 | "pygments_lexer": "ipython2",
53 | "version": "2.7.12"
54 | }
55 | },
56 | "nbformat": 4,
57 | "nbformat_minor": 0
58 | }
59 |
--------------------------------------------------------------------------------
/jupyterbasics/JupyterBasics.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "
\n",
8 | "\n",
9 | "---------------\n",
10 | "\n",
11 | " \n"
12 | ]
13 | },
14 | {
15 | "cell_type": "markdown",
16 | "metadata": {},
17 | "source": [
18 | "# Jupyter Quickstart\n",
19 | "This tutorial very briefly introduces the Jupyter Notebook environment. The most important things to know:\n",
20 | "* code cells are grey and you can select them by clicking on them\n",
21 | "* pressing SHIFT-ENTER runs the selected code in that cell."
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "metadata": {},
27 | "source": [
28 | "### Cells\n",
29 | "\n",
30 | "The notebook is made up of **cells**. A cell is a snippet of code or text. You can break up code into cells as you wish. Each cell with code in it can be run on its own.\n",
31 | "\n",
32 | "* Click on a cell to highlight it (you will see a highlight box appear around it)\n",
33 | "* Press SHIFT-ENTER to run the code (hold SHIFT, then press ENTER).\n",
34 | "
\n",
35 | "\n",
36 | " **1) Try this on the cell below:** \n"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": 1,
42 | "metadata": {
43 | "collapsed": false,
44 | "nbgrader": {
45 | "grade": false,
46 | "locked": false,
47 | "solution": false
48 | }
49 | },
50 | "outputs": [
51 | {
52 | "name": "stdout",
53 | "output_type": "stream",
54 | "text": [
55 | "Hello, world\n"
56 | ]
57 | }
58 | ],
59 | "source": [
60 | "print \"Hello, world\""
61 | ]
62 | },
63 | {
64 | "cell_type": "markdown",
65 | "metadata": {},
66 | "source": [
67 | "After selecting the cell above and pressing SHIFT-ENTER. you should see:\n",
68 | "\n",
69 | " In [1]: print \"Hello, world\"\n",
70 | " Hello, world\n",
71 | "\n",
72 | "The line underneath is the **output** of the code you ran. All the code in the cell is run when you press SHIFT-ENTER. \n",
73 | "\n",
74 | "---\n",
75 | "### Editing\n",
76 | "You can edit a code cell just by clicking on it, and editing the text. Press SHIFT-ENTER to run it again. \n",
77 | "\n",
78 | " **2) Edit the code in the cell above to print out a different message, then run it again.** "
79 | ]
80 | },
81 | {
82 | "cell_type": "markdown",
83 | "metadata": {},
84 | "source": [
85 | "### Text cells\n",
86 | "The instructions you are reading are also in cells, but these are **text cells**.\n",
87 | "If you *double*-click on these text cells you can edit them as well. Press SHIFT-ENTER to \"format\" the cell.\n",
88 | "\n",
89 | "The text inside these boxes is [Markdown](http://daringfireball.net/projects/markdown/syntax). \n",
90 | "\n",
91 | "Jupyter will also recognise LaTeX formulae if you surround them with dollar symbols \n",
92 | "`$ x = x + 1 $` $ x = x + 1 $\n",
93 | "And you can make display equations using double dollar signs:\n",
94 | "`$$ \\sum_{i=0}^{N} i^{\\alpha_i} + \\beta_i $$` becomes\n",
95 | "$$ \\sum_{i=0}^{N} i^{\\alpha_i} + \\beta_i $$\n",
96 | "\n",
97 | " **3) Double-click on this cell. It will turn gray and the font will change. Edit this text to say something different. Then press SHIFT-ENTER to format it.** "
98 | ]
99 | },
100 | {
101 | "cell_type": "markdown",
102 | "metadata": {},
103 | "source": [
104 | "### Navigation and editing\n",
105 | "\n",
106 | "* Editing *inside* cells works like a normal text form on a web page. \n",
107 | "\n",
108 | "\n",
109 | "**4) Try typing `print \"Hello Jupyter\"` in the box below, then pressing SHIFT-ENTER to run it.** "
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 2,
115 | "metadata": {
116 | "collapsed": false
117 | },
118 | "outputs": [
119 | {
120 | "data": {
121 | "text/html": [
122 | "
"
123 | ],
124 | "text/plain": [
125 | ""
126 | ]
127 | },
128 | "execution_count": 2,
129 | "metadata": {},
130 | "output_type": "execute_result"
131 | }
132 | ],
133 | "source": []
134 | },
135 | {
136 | "cell_type": "markdown",
137 | "metadata": {},
138 | "source": [
139 | "### Copy and paste"
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "* You can cut, copy and paste entire cells using the toolbar or menu, or use `CTRL-X` (cut), `CTRL-C` (copy) and `CTRL-V` (paste). \n",
147 | "\n",
148 | " **5) Try copying the cell below that says \"copy me!\" and paste it twice below.** "
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "metadata": {},
154 | "source": [
155 | " Copy me!
"
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "### Adding new cells\n",
163 | "* You can insert new cells (e.g. to write code in) by using `Insert/Cell Above` or `Insert/Cell Below` from the menu. Or use the + button on the toolbar. \n",
164 | "\n",
165 | " **6) Insert a cell below, and enter `print \"hello from a new cell\"`** "
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {},
171 | "source": [
172 | "Sometimes you want to add a text cell, to write notes, for example. To do this, add a cell as before, *then* go to the `Cell` menu and select `Cell Type/Markdown`. To change the cell type back to code, go to `Cell/Cell Type/Code`.\n",
173 | "\n",
174 | "** 7) Insert a text cell below. Put the text `# Title` in the cell. Notice that when you press SHIFT-ENTER the text will become a title line. This is caused by the leading # symbol. **"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {},
180 | "source": [
181 | "### Saving\n",
182 | "\n",
183 | "* Remember to **save** regularly! Press `CTRL-S` to save, or use the menu option `File/Save and Checkpoint`\n",
184 | "\n",
185 | "### Making copies of notebooks\n",
186 | "\n",
187 | "* You can make a copy of your work using `File/Make a Copy` (e.g. if you want to change something but have a \"good\" version to go back to). \n",
188 | "\n",
189 | " **9) Make a copy of this notebook. You can change the copies name using the menu option `File/Rename...` Save. ** \n",
190 | "\n",
191 | "### Undo\n",
192 | "\n",
193 | "* You can undo typing inside cells (`Edit/Undo` or `CTRL-Z`) but be aware that undo works independently inside each cell (i.e. each cell maintains its own undo history).\n"
194 | ]
195 | },
196 | {
197 | "cell_type": "markdown",
198 | "metadata": {},
199 | "source": [
200 | "-----\n",
201 | "### Stopping and restarting\n",
202 | "You can make Python run for a very long time, for example if you create an infinite loop. No other cells can run while we are waiting.\n",
203 | "\n",
204 | "If this happens, you will see an asterisk `In [*]` beside the cell that is running. The circle next to `Python 2` at the very top left of the screen will be filled while the process is busy. To stop it, click on the cell and press the stop button on the toolbar. \n",
205 | "\n",
206 | " **10) Run the cell below. It will run forever. Look for the asterisk, and then stop the cell.** "
207 | ]
208 | },
209 | {
210 | "cell_type": "code",
211 | "execution_count": 2,
212 | "metadata": {
213 | "collapsed": false
214 | },
215 | "outputs": [
216 | {
217 | "ename": "KeyboardInterrupt",
218 | "evalue": "",
219 | "output_type": "error",
220 | "traceback": [
221 | "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
222 | "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
223 | "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# infinite loop\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mwhile\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[1;32mpass\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
224 | "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
225 | ]
226 | }
227 | ],
228 | "source": [
229 | "# infinite loop\n",
230 | "while 1:\n",
231 | " pass"
232 | ]
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {},
237 | "source": [
238 | "### Variables\n",
239 | "When you run a cell, it changes the Python state. For example if you assign a value to a variable, the next cell you run will know about that value. \n",
240 | "\n",
241 | " **11) There are two cells below. Run them both. **"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": null,
247 | "metadata": {
248 | "collapsed": false
249 | },
250 | "outputs": [],
251 | "source": [
252 | "# greeting 1\n",
253 | "greeting = \"Hello, world\""
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "metadata": {
260 | "collapsed": false
261 | },
262 | "outputs": [],
263 | "source": [
264 | "# print greeting\n",
265 | "# Python remembers the value of greeting from the last run cell.\n",
266 | "print greeting"
267 | ]
268 | },
269 | {
270 | "cell_type": "markdown",
271 | "metadata": {},
272 | "source": [
273 | " **12) Now run the cell below (`#greeting 2`), then run the `print greeting` cell again. Notice that the output changes. Try running the first greeting cell again. ** \n",
274 | "\n",
275 | "Python runs each cell when you tell it, and remembers the values you set. The order the cells appear in the notebook isn't important -- it is the order in which you **run** the cells."
276 | ]
277 | },
278 | {
279 | "cell_type": "code",
280 | "execution_count": null,
281 | "metadata": {
282 | "collapsed": false
283 | },
284 | "outputs": [],
285 | "source": [
286 | "# greeting 2\n",
287 | "greeting = \"Is this thing on?\""
288 | ]
289 | },
290 | {
291 | "cell_type": "markdown",
292 | "metadata": {},
293 | "source": [
294 | "Occasionally you might want to reset the Python state back to what it was before any code ran -- to forget any variables you have stored. \n",
295 | "\n",
296 | "
**12) Press the restart button on the toolbar, or go to the menu option `Kernel/Restart`. The contents of the notebook will not change. Now try running the `print greeting` cell above. You will get an error, because Python has forgotten the value. Run the `greeting 1` cell and then run the `print greeting cell`**. "
297 | ]
298 | },
299 | {
300 | "cell_type": "markdown",
301 | "metadata": {},
302 | "source": [
303 | "\n",
304 | "## A little more advanced\n",
305 | "Let's compute the length of a path in the [Collatz](http://en.wikipedia.org/wiki/Collatz_conjecture) sequence. That is, we take a number $n$ and halve it if $n \\equiv 0 \\mod 2$, otherwise replace it with $3n+1$. We count the number of steps until we reach 1. \n",
306 | "\n",
307 | "Remember that to execute the cell, and thus to define the function, select the cell and press SHIFT-ENTER."
308 | ]
309 | },
310 | {
311 | "cell_type": "code",
312 | "execution_count": 5,
313 | "metadata": {
314 | "collapsed": false
315 | },
316 | "outputs": [],
317 | "source": [
318 | "def collatz(n, steps=0):\n",
319 | " \"\"\"Compute the number of steps to reach 1 in the Collatz sequence.\n",
320 | " Note the use of triple quotes to specify a docstring.\n",
321 | " \n",
322 | " Also note the use of a default parameter (steps) to count the number \n",
323 | " of recursive calls.\"\"\"\n",
324 | " if n==1:\n",
325 | " return steps\n",
326 | " if n%2==0:\n",
327 | " return collatz(n/2, steps+1)\n",
328 | " else:\n",
329 | " return collatz(3*n+1, steps+1)"
330 | ]
331 | },
332 | {
333 | "cell_type": "markdown",
334 | "metadata": {},
335 | "source": [
336 | "Now try it in the cell below (e.g. entering *collatz(331)* and pressing SHIFT-ENTER should print 24)."
337 | ]
338 | },
339 | {
340 | "cell_type": "code",
341 | "execution_count": 6,
342 | "metadata": {
343 | "collapsed": false
344 | },
345 | "outputs": [
346 | {
347 | "data": {
348 | "text/plain": [
349 | "24"
350 | ]
351 | },
352 | "execution_count": 6,
353 | "metadata": {},
354 | "output_type": "execute_result"
355 | }
356 | ],
357 | "source": [
358 | "collatz(331)"
359 | ]
360 | },
361 | {
362 | "cell_type": "markdown",
363 | "metadata": {},
364 | "source": [
365 | "OK, let's plot the graph of this function for various $n$. We'll use numpy to manipulate vectors of values, and matplotlib to plot the graph. First we must import them. In future workbooks this will already be done at the start, but we do it explicitly here for clarity."
366 | ]
367 | },
368 | {
369 | "cell_type": "code",
370 | "execution_count": 7,
371 | "metadata": {
372 | "collapsed": false
373 | },
374 | "outputs": [],
375 | "source": [
376 | "import numpy as np # np is the conventional short name for numpy\n",
377 | "import matplotlib.pyplot as plt # and plt is the conventional name for matplotlib\n",
378 | "import seaborn # all this does (in this case) is restyle matplotlib to use better layouts"
379 | ]
380 | },
381 | {
382 | "cell_type": "markdown",
383 | "metadata": {},
384 | "source": [
385 | "Now we create an array of integers `1:n` and plot it. Note the use of `arange` to create an array of integers, and the list comprehension `[collatz(n) for n in ns]`, which applies the `collatz` function to each element of `ns`.\n"
386 | ]
387 | },
388 | {
389 | "cell_type": "code",
390 | "execution_count": 8,
391 | "metadata": {
392 | "collapsed": false
393 | },
394 | "outputs": [
395 | {
396 | "data": {
397 | "text/plain": [
398 | "[]"
399 | ]
400 | },
401 | "execution_count": 8,
402 | "metadata": {},
403 | "output_type": "execute_result"
404 | }
405 | ],
406 | "source": [
407 | "ns = np.arange(1,500) # generate n = [1,2,3,4,...]\n",
408 | "collatzed = np.array([collatz(n) for n in ns]) # apply collatz(n) to each value and put it in a numpy array\n",
409 | "plt.plot(ns, collatzed) # plot the result"
410 | ]
411 | },
412 | {
413 | "cell_type": "markdown",
414 | "metadata": {},
415 | "source": [
416 | "If you hit SHIFT-ENTER on the above, you should see a plot. \n",
417 | "\n",
418 | "It looks pretty noisy; perhaps there is some periodic structure. We can use the FFT to look at this. np.fft.fft() computes the [http://en.wikipedia.org/wiki/Fourier_transform](Fourier transform); we can compute the magnitude spectrum $|f(x)|$ by taking the absolute value, and discarding the symmetric half:"
419 | ]
420 | },
421 | {
422 | "cell_type": "code",
423 | "execution_count": null,
424 | "metadata": {
425 | "collapsed": false
426 | },
427 | "outputs": [],
428 | "source": [
429 | "fftd = np.fft.fft(collatzed)\n",
430 | "# take absolute value\n",
431 | "real_magnitude = np.abs(fftd)\n",
432 | "# trim off symmetric part (note the slice syntax)\n",
433 | "real_magnitude = real_magnitude[1:len(fftd)/2] # note that we drop the 0th element (DC)\n",
434 | "fig = plt.figure() # make a new figure\n",
435 | "ax = fig.add_subplot(111) # this just creates a new single blank axis\n",
436 | "ax.plot(real_magnitude) # and plots onto it (we can create multi-panel plots using add_subplot)"
437 | ]
438 | },
439 | {
440 | "cell_type": "markdown",
441 | "metadata": {},
442 | "source": [
443 | "That looks pretty unstructured. Let's try more numbers, and make the fft plot a function we can reuse later."
444 | ]
445 | },
446 | {
447 | "cell_type": "code",
448 | "execution_count": null,
449 | "metadata": {
450 | "collapsed": false
451 | },
452 | "outputs": [],
453 | "source": [
454 | "ns = np.arange(1,10000)\n",
455 | "collatzed = [collatz(n) for n in ns]\n"
456 | ]
457 | },
458 | {
459 | "cell_type": "code",
460 | "execution_count": null,
461 | "metadata": {
462 | "collapsed": false
463 | },
464 | "outputs": [],
465 | "source": [
466 | "def fft_plot(x):\n",
467 | " \"\"\"Plot the magnitude spectrum of x, showing only the real, positive-frequency \n",
468 | " portion, and excluding component 0 (DC). \"\"\"\n",
469 | " fftd = np.fft.fft(x)\n",
470 | " # get absolute (magnitude spectrum)\n",
471 | " real_magnitude = np.abs(fftd)\n",
472 | " # chop off symmetric part\n",
473 | " real_magnitude = real_magnitude[1:len(fftd)/2] \n",
474 | " fig = plt.figure() # make a new figure\n",
475 | " ax = fig.add_subplot(111)\n",
476 | " ax.plot(real_magnitude)"
477 | ]
478 | },
479 | {
480 | "cell_type": "code",
481 | "execution_count": null,
482 | "metadata": {
483 | "collapsed": false
484 | },
485 | "outputs": [],
486 | "source": [
487 | "fft_plot(collatzed)"
488 | ]
489 | },
490 | {
491 | "cell_type": "markdown",
492 | "metadata": {},
493 | "source": [
494 | "Some interesting structure, with big spikes, but the frequency approach isn't revealing much. Let's investigate the distribution of the variable. We can get a histogram with `plt.hist()`."
495 | ]
496 | },
497 | {
498 | "cell_type": "code",
499 | "execution_count": null,
500 | "metadata": {
501 | "collapsed": false
502 | },
503 | "outputs": [],
504 | "source": [
505 | "# normed forces the frequency axis to sum to 1\n",
506 | "plt.hist(collatzed, bins=50, normed=True);"
507 | ]
508 | },
509 | {
510 | "cell_type": "markdown",
511 | "metadata": {},
512 | "source": [
513 | "OK, this is more interesting. Let's show a normal fit to the distribution, using maximum likelihood estimation. `scipy.stats` has the tools we need to do this."
514 | ]
515 | },
516 | {
517 | "cell_type": "code",
518 | "execution_count": 9,
519 | "metadata": {
520 | "collapsed": false
521 | },
522 | "outputs": [
523 | {
524 | "data": {
525 | "text/plain": [
526 | "[]"
527 | ]
528 | },
529 | "execution_count": 9,
530 | "metadata": {},
531 | "output_type": "execute_result"
532 | }
533 | ],
534 | "source": [
535 | "mean, std = np.mean(collatzed), np.std(collatzed)\n",
536 | "import scipy.stats as stats # we must import scipy.stats, as we've not used it yet\n",
537 | "\n",
538 | "# np.linspace() linearly spaces points on a range: here 200 points spanning the distribution\n",
539 | "pdf_range = np.linspace(np.min(collatzed), np.max(collatzed), 200)\n",
540 | "\n",
541 | "# scipy.stats has many distribution functions, including normal (norm)\n",
542 | "pdf = stats.norm.pdf(pdf_range, mean, std)\n",
543 | "plt.hist(collatzed, bins=50, normed=True)\n",
544 | "plt.plot(pdf_range, pdf, 'g', linewidth=3) # plot using thick green line "
545 | ]
546 | },
547 | {
548 | "cell_type": "markdown",
549 | "metadata": {},
550 | "source": [
551 | "Obviously, this distribution is non-Gaussian, but let's test to make sure. `scipy.stats` provides many statistical tools, including normality testing. `scipy.stats.normaltest` gives us a combination of D’Agostino and Pearson’s test.\n",
552 | "\n",
553 | "Note: to see the documentation for `normaltest`, try clicking at the end of `normaltest` and press SHIFT-TAB to see the tooltip. Hit the ^ symbol to bring up the full help in a pane below. This works for any function.\n"
554 | ]
555 | },
556 | {
557 | "cell_type": "code",
558 | "execution_count": null,
559 | "metadata": {
560 | "collapsed": false
561 | },
562 | "outputs": [],
563 | "source": [
564 | "import scipy.stats as stats # we must import scipy.stats as we've not used it yet\n",
565 | "k2, p = stats.normaltest(collatzed)\n",
566 | "print p # p-value, testing if the distribution differs from the normal. p<0.05 suggests it is"
567 | ]
568 | },
569 | {
570 | "cell_type": "markdown",
571 | "metadata": {},
572 | "source": [
573 | "We can safely assume this distribution is non-Gaussian. \n",
574 | "\n",
575 | "As an additional measure, we can plot a [Q-Q plot](http://en.wikipedia.org/wiki/Q%E2%80%93Q_plot), showing the quantiles of the `collatzed` distribution against the quantiles of a normal distribution. If the distribution is normal, the plot would be show as a straight line.\n",
576 | "\n",
577 | "The Q-Q plot is a very useful way of eyeballing distribution fits.\n",
578 | "\n",
579 | "`scipy.stats.probplot()` does the job easily:"
580 | ]
581 | },
582 | {
583 | "cell_type": "code",
584 | "execution_count": null,
585 | "metadata": {
586 | "collapsed": false
587 | },
588 | "outputs": [],
589 | "source": [
590 | "plt.figure() # don't plot on the same axis as the previous plot\n",
591 | "qq = stats.probplot(collatzed, dist=\"norm\", plot=plt) # note the use of \"norm\" to specify the test distribution\n"
592 | ]
593 | },
594 | {
595 | "cell_type": "markdown",
596 | "metadata": {},
597 | "source": [
598 | "The \"wobbliness\" of the line indicates that this is not a good distribution match."
599 | ]
600 | }
601 | ],
602 | "metadata": {
603 | "kernelspec": {
604 | "display_name": "Python 2",
605 | "language": "python",
606 | "name": "python2"
607 | },
608 | "language_info": {
609 | "codemirror_mode": {
610 | "name": "ipython",
611 | "version": 2
612 | },
613 | "file_extension": ".py",
614 | "mimetype": "text/x-python",
615 | "name": "python",
616 | "nbconvert_exporter": "python",
617 | "pygments_lexer": "ipython2",
618 | "version": "2.7.12"
619 | }
620 | },
621 | "nbformat": 4,
622 | "nbformat_minor": 0
623 | }
624 |
--------------------------------------------------------------------------------
/jupyterbasics/imgs/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/jupyterbasics/imgs/header.png
--------------------------------------------------------------------------------
/jupyterbasics/imgs/jupyter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/jupyterbasics/imgs/jupyter.jpg
--------------------------------------------------------------------------------
/jupyterbasics/imgs/toolbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/jupyterbasics/imgs/toolbar.png
--------------------------------------------------------------------------------
/ml/cv_hyperparameter_tuning.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "raw",
5 | "metadata": {},
6 | "source": [
7 | "Download: https://goo.gl/NrCq9t"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 10,
13 | "metadata": {
14 | "collapsed": false
15 | },
16 | "outputs": [],
17 | "source": [
18 | "import numpy as np\n",
19 | "from sklearn import datasets\n",
20 | "from sklearn.model_selection import GridSearchCV, RandomizedSearchCV, LeaveOneOut, train_test_split\n",
21 | "from sklearn.svm import SVC\n",
22 | "from sklearn.ensemble import RandomForestClassifier\n",
23 | "from scipy.stats import randint as sp_randint\n",
24 | "np.random.seed(1)"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": 11,
30 | "metadata": {
31 | "collapsed": false
32 | },
33 | "outputs": [
34 | {
35 | "name": "stdout",
36 | "output_type": "stream",
37 | "text": [
38 | "(120, 4) - (30, 4)\n"
39 | ]
40 | }
41 | ],
42 | "source": [
43 | "iris =datasets.load_iris()\n",
44 | "noise = np.random.normal(iris.data.mean(),1,iris.data.shape)\n",
45 | "#iris.data = iris.data + noise\n",
46 | "\n",
47 | "X_train, X_test, labels_train, labels_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=1)\n",
48 | "print(str(X_train.shape) + \" - \" + str(X_test.shape))"
49 | ]
50 | },
51 | {
52 | "cell_type": "markdown",
53 | "metadata": {},
54 | "source": [
55 | "# SVM and Grid Search"
56 | ]
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": 12,
61 | "metadata": {
62 | "collapsed": false
63 | },
64 | "outputs": [
65 | {
66 | "name": "stdout",
67 | "output_type": "stream",
68 | "text": [
69 | "Best parameters set found on training set:\n",
70 | "{'C': 100, 'gamma': 0.001, 'kernel': 'rbf'}\n",
71 | "\n",
72 | "Grid scores:\n",
73 | "Validation: 0.367 (+/-0.482), Training: 0.367 for {'C': 0.01, 'gamma': 0.001, 'kernel': 'rbf'}\n",
74 | "Validation: 0.367 (+/-0.482), Training: 0.367 for {'C': 0.01, 'gamma': 0.0001, 'kernel': 'rbf'}\n",
75 | "Validation: 0.692 (+/-0.462), Training: 0.692 for {'C': 1, 'gamma': 0.001, 'kernel': 'rbf'}\n",
76 | "Validation: 0.367 (+/-0.482), Training: 0.367 for {'C': 1, 'gamma': 0.0001, 'kernel': 'rbf'}\n",
77 | "Validation: 0.933 (+/-0.249), Training: 0.934 for {'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}\n",
78 | "Validation: 0.692 (+/-0.462), Training: 0.692 for {'C': 10, 'gamma': 0.0001, 'kernel': 'rbf'}\n",
79 | "Validation: 0.975 (+/-0.156), Training: 0.976 for {'C': 100, 'gamma': 0.001, 'kernel': 'rbf'}\n",
80 | "Validation: 0.933 (+/-0.249), Training: 0.934 for {'C': 100, 'gamma': 0.0001, 'kernel': 'rbf'}\n",
81 | "Validation: 0.867 (+/-0.340), Training: 0.889 for {'C': 0.01, 'kernel': 'linear'}\n",
82 | "Validation: 0.975 (+/-0.156), Training: 0.983 for {'C': 1, 'kernel': 'linear'}\n",
83 | "Validation: 0.967 (+/-0.180), Training: 0.975 for {'C': 10, 'kernel': 'linear'}\n",
84 | "Validation: 0.958 (+/-0.200), Training: 0.975 for {'C': 100, 'kernel': 'linear'}\n",
85 | "\n",
86 | "Test Accuracy [0.967]\n"
87 | ]
88 | }
89 | ],
90 | "source": [
91 | "# Optimize the parameters by cross-validation\n",
92 | "parameters = [\n",
93 | " {'kernel': ['rbf'], 'gamma': [1e-3, 1e-4], 'C': [0.01, 1, 10, 100]},\n",
94 | " {'kernel': ['linear'], 'C': [0.01, 1, 10, 100]}\n",
95 | "]\n",
96 | "\n",
97 | "loo = LeaveOneOut()\n",
98 | "\n",
99 | "# Grid search object with SVM classifier.\n",
100 | "clf = GridSearchCV(SVC(), parameters, cv=10)\n",
101 | "clf.fit(X_train, labels_train)\n",
102 | "\n",
103 | "print(\"Best parameters set found on training set:\")\n",
104 | "print(clf.best_params_)\n",
105 | "print()\n",
106 | "\n",
107 | "means_valid = clf.cv_results_['mean_test_score']\n",
108 | "stds_valid = clf.cv_results_['std_test_score']\n",
109 | "means_train = clf.cv_results_['mean_train_score']\n",
110 | "\n",
111 | "print(\"Grid scores:\")\n",
112 | "for mean_valid, std_valid, mean_train, params in zip(means_valid, stds_valid, means_train, clf.cv_results_['params']):\n",
113 | " print(\"Validation: %0.3f (+/-%0.03f), Training: %0.3f for %r\" % (mean_valid, std_valid, mean_train, params))\n",
114 | "print()\n",
115 | "\n",
116 | "labels_test, labels_predicted = labels_test, clf.predict(X_test)\n",
117 | "print(\"Test Accuracy [%0.3f]\" % ((labels_predicted == labels_test).mean()))"
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {},
123 | "source": [
124 | "# Random Forest and Random Search"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": 4,
130 | "metadata": {
131 | "collapsed": true
132 | },
133 | "outputs": [],
134 | "source": [
135 | "from sklearn.model_selection import KFold, PredefinedSplit, ShuffleSplit"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": 13,
141 | "metadata": {
142 | "collapsed": false
143 | },
144 | "outputs": [
145 | {
146 | "name": "stdout",
147 | "output_type": "stream",
148 | "text": [
149 | "Best parameters set found on training set:\n",
150 | "{'max_depth': 3, 'max_features': 1, 'min_samples_leaf': 2, 'min_samples_split': 9, 'n_estimators': 3}\n",
151 | "\n",
152 | "Grid scores:\n",
153 | "Validation: 0.942 (+/-0.068), Training: 0.958 for {'max_depth': 3, 'max_features': 1, 'min_samples_leaf': 2, 'min_samples_split': 9, 'n_estimators': 3}\n",
154 | "Validation: 0.758 (+/-0.069), Training: 0.820 for {'max_depth': 3, 'max_features': 2, 'min_samples_leaf': 9, 'min_samples_split': 2, 'n_estimators': 1}\n",
155 | "Validation: 0.783 (+/-0.144), Training: 0.870 for {'max_depth': 3, 'max_features': 1, 'min_samples_leaf': 9, 'min_samples_split': 7, 'n_estimators': 1}\n",
156 | "Validation: 0.883 (+/-0.085), Training: 0.917 for {'max_depth': 2, 'max_features': 2, 'min_samples_leaf': 4, 'min_samples_split': 6, 'n_estimators': 5}\n",
157 | "Validation: 0.925 (+/-0.082), Training: 0.944 for {'max_depth': 3, 'max_features': 3, 'min_samples_leaf': 6, 'min_samples_split': 5, 'n_estimators': 1}\n",
158 | "Validation: 0.900 (+/-0.062), Training: 0.938 for {'max_depth': 2, 'max_features': 1, 'min_samples_leaf': 7, 'min_samples_split': 8, 'n_estimators': 5}\n",
159 | "Validation: 0.917 (+/-0.078), Training: 0.925 for {'max_depth': 2, 'max_features': 2, 'min_samples_leaf': 3, 'min_samples_split': 9, 'n_estimators': 5}\n",
160 | "Validation: 0.933 (+/-0.075), Training: 0.954 for {'max_depth': 2, 'max_features': 3, 'min_samples_leaf': 7, 'min_samples_split': 3, 'n_estimators': 3}\n",
161 | "Validation: 0.883 (+/-0.085), Training: 0.900 for {'max_depth': 3, 'max_features': 2, 'min_samples_leaf': 8, 'min_samples_split': 3, 'n_estimators': 3}\n",
162 | "Validation: 0.683 (+/-0.089), Training: 0.741 for {'max_depth': 2, 'max_features': 1, 'min_samples_leaf': 3, 'min_samples_split': 2, 'n_estimators': 1}\n",
163 | "\n",
164 | "Test Accuracy [0.967]\n"
165 | ]
166 | }
167 | ],
168 | "source": [
169 | "# cv parameter of RandomizedSearchCV or GridSearchCV can be fed with a customized cross-validation object.\n",
170 | "ss = ShuffleSplit(n_splits=10, test_size=0.2, random_state=1)\n",
171 | " \n",
172 | "# Optimize the parameters by cross-validation.\n",
173 | "parameters = {\n",
174 | " \"max_depth\": sp_randint(2, 4),\n",
175 | " \"max_features\": sp_randint(1, 4),\n",
176 | " \"min_samples_split\": sp_randint(2, 10),\n",
177 | " \"min_samples_leaf\": sp_randint(2, 10),\n",
178 | " 'n_estimators': [1,3,5,10],\n",
179 | " }\n",
180 | "\n",
181 | "# Random search object with SVM classifier.\n",
182 | "clf = RandomizedSearchCV(\n",
183 | " estimator=RandomForestClassifier(random_state=1),\n",
184 | " param_distributions=parameters,\n",
185 | " n_iter=10,\n",
186 | " cv=10,\n",
187 | " random_state=1,\n",
188 | " )\n",
189 | "clf.fit(X_train, labels_train)\n",
190 | "\n",
191 | "print(\"Best parameters set found on training set:\")\n",
192 | "print(clf.best_params_)\n",
193 | "print()\n",
194 | "\n",
195 | "means_valid = clf.cv_results_['mean_test_score']\n",
196 | "stds_valid = clf.cv_results_['std_test_score']\n",
197 | "means_train = clf.cv_results_['mean_train_score']\n",
198 | "\n",
199 | "print(\"Grid scores:\")\n",
200 | "for mean_valid, std_valid, mean_train, params in zip(means_valid, stds_valid, means_train, clf.cv_results_['params']):\n",
201 | " print(\"Validation: %0.3f (+/-%0.03f), Training: %0.3f for %r\" % (mean_valid, std_valid, mean_train, params))\n",
202 | "print()\n",
203 | "\n",
204 | "labels_test, labels_predicted = labels_test, clf.predict(X_test)\n",
205 | "print(\"Test Accuracy [%0.3f]\" % ((labels_predicted == labels_test).mean()))"
206 | ]
207 | },
208 | {
209 | "cell_type": "markdown",
210 | "metadata": {
211 | "collapsed": true
212 | },
213 | "source": [
214 | "## Random Search vs. Grid Search\n",
215 | "\n",
216 | "\n",
217 | "\n",
218 | "\n",
219 | "Image source and further reading: Bergstra, J., & Bengio, Y. (2012). Random search for hyper-parameter optimization. Journal of Machine Learning Research, 13(Feb), 281-305."
220 | ]
221 | },
222 | {
223 | "cell_type": "code",
224 | "execution_count": 11,
225 | "metadata": {
226 | "collapsed": false
227 | },
228 | "outputs": [
229 | {
230 | "name": "stdout",
231 | "output_type": "stream",
232 | "text": [
233 | "RandomizedSearchCV took 29.74 seconds for 216 candidates parameter settings.\n",
234 | "Model with rank: 1\n",
235 | "Mean validation score: 0.934 (std: 0.005)\n",
236 | "Parameters: {'bootstrap': False, 'criterion': 'gini', 'max_depth': None, 'max_features': 5, 'min_samples_leaf': 2, 'min_samples_split': 8}\n",
237 | "\n",
238 | "Model with rank: 1\n",
239 | "Mean validation score: 0.934 (std: 0.011)\n",
240 | "Parameters: {'bootstrap': False, 'criterion': 'gini', 'max_depth': None, 'max_features': 7, 'min_samples_leaf': 2, 'min_samples_split': 3}\n",
241 | "\n",
242 | "Model with rank: 3\n",
243 | "Mean validation score: 0.932 (std: 0.008)\n",
244 | "Parameters: {'bootstrap': False, 'criterion': 'gini', 'max_depth': None, 'max_features': 6, 'min_samples_leaf': 1, 'min_samples_split': 5}\n",
245 | "\n",
246 | "GridSearchCV took 27.85 seconds for 216 candidate parameter settings.\n",
247 | "Model with rank: 1\n",
248 | "Mean validation score: 0.935 (std: 0.003)\n",
249 | "Parameters: {'bootstrap': False, 'criterion': 'entropy', 'max_depth': None, 'max_features': 3, 'min_samples_leaf': 3, 'min_samples_split': 10}\n",
250 | "\n",
251 | "Model with rank: 2\n",
252 | "Mean validation score: 0.933 (std: 0.007)\n",
253 | "Parameters: {'bootstrap': False, 'criterion': 'gini', 'max_depth': None, 'max_features': 10, 'min_samples_leaf': 1, 'min_samples_split': 3}\n",
254 | "\n",
255 | "Model with rank: 3\n",
256 | "Mean validation score: 0.931 (std: 0.002)\n",
257 | "Parameters: {'bootstrap': True, 'criterion': 'entropy', 'max_depth': None, 'max_features': 3, 'min_samples_leaf': 1, 'min_samples_split': 2}\n",
258 | "\n",
259 | "Model with rank: 3\n",
260 | "Mean validation score: 0.931 (std: 0.005)\n",
261 | "Parameters: {'bootstrap': False, 'criterion': 'gini', 'max_depth': None, 'max_features': 3, 'min_samples_leaf': 1, 'min_samples_split': 3}\n",
262 | "\n"
263 | ]
264 | }
265 | ],
266 | "source": [
267 | "#Example Code: http://scikit-learn.org/stable/auto_examples/model_selection/randomized_search.html\n",
268 | "import numpy as np\n",
269 | "\n",
270 | "from time import time\n",
271 | "from scipy.stats import randint as sp_randint\n",
272 | "\n",
273 | "from sklearn.model_selection import GridSearchCV\n",
274 | "from sklearn.model_selection import RandomizedSearchCV\n",
275 | "from sklearn.datasets import load_digits\n",
276 | "from sklearn.ensemble import RandomForestClassifier\n",
277 | "\n",
278 | "# get some data\n",
279 | "digits = load_digits()\n",
280 | "X, y = digits.data, digits.target\n",
281 | "\n",
282 | "# build a classifier\n",
283 | "clf = RandomForestClassifier(n_estimators=20)\n",
284 | "\n",
285 | "\n",
286 | "# Utility function to report best scores\n",
287 | "def report(results, n_top=3):\n",
288 | " for i in range(1, n_top + 1):\n",
289 | " candidates = np.flatnonzero(results['rank_test_score'] == i)\n",
290 | " for candidate in candidates:\n",
291 | " print(\"Model with rank: {0}\".format(i))\n",
292 | " print(\"Mean validation score: {0:.3f} (std: {1:.3f})\".format(\n",
293 | " results['mean_test_score'][candidate],\n",
294 | " results['std_test_score'][candidate]))\n",
295 | " print(\"Parameters: {0}\".format(results['params'][candidate]))\n",
296 | " print(\"\")\n",
297 | "\n",
298 | "\n",
299 | "# specify parameters and distributions to sample from\n",
300 | "param_dist = {\"max_depth\": [3, None],\n",
301 | " \"max_features\": sp_randint(1, 11),\n",
302 | " \"min_samples_split\": sp_randint(2, 11),\n",
303 | " \"min_samples_leaf\": sp_randint(1, 11),\n",
304 | " \"bootstrap\": [True, False],\n",
305 | " \"criterion\": [\"gini\", \"entropy\"]}\n",
306 | "\n",
307 | "# run randomized search\n",
308 | "n_iter_search = 216\n",
309 | "random_search = RandomizedSearchCV(clf, param_distributions=param_dist,\n",
310 | " n_iter=n_iter_search)\n",
311 | "\n",
312 | "start = time()\n",
313 | "random_search.fit(X, y)\n",
314 | "print(\"RandomizedSearchCV took %.2f seconds for %d candidates\"\n",
315 | " \" parameter settings.\" % ((time() - start), n_iter_search))\n",
316 | "report(random_search.cv_results_)\n",
317 | "\n",
318 | "# use a full grid over all parameters\n",
319 | "param_grid = {\"max_depth\": [3, None],\n",
320 | " \"max_features\": [1, 3, 10],\n",
321 | " \"min_samples_split\": [2, 3, 10],\n",
322 | " \"min_samples_leaf\": [1, 3, 10],\n",
323 | " \"bootstrap\": [True, False],\n",
324 | " \"criterion\": [\"gini\", \"entropy\"]}\n",
325 | "\n",
326 | "# run grid search\n",
327 | "grid_search = GridSearchCV(clf, param_grid=param_grid)\n",
328 | "start = time()\n",
329 | "grid_search.fit(X, y)\n",
330 | "\n",
331 | "print(\"GridSearchCV took %.2f seconds for %d candidate parameter settings.\"\n",
332 | " % (time() - start, len(grid_search.cv_results_['params'])))\n",
333 | "report(grid_search.cv_results_)"
334 | ]
335 | },
336 | {
337 | "cell_type": "code",
338 | "execution_count": null,
339 | "metadata": {
340 | "collapsed": true
341 | },
342 | "outputs": [],
343 | "source": []
344 | }
345 | ],
346 | "metadata": {
347 | "kernelspec": {
348 | "display_name": "Python 3",
349 | "language": "python",
350 | "name": "python3"
351 | },
352 | "language_info": {
353 | "codemirror_mode": {
354 | "name": "ipython",
355 | "version": 3
356 | },
357 | "file_extension": ".py",
358 | "mimetype": "text/x-python",
359 | "name": "python",
360 | "nbconvert_exporter": "python",
361 | "pygments_lexer": "ipython3",
362 | "version": "3.6.0"
363 | }
364 | },
365 | "nbformat": 4,
366 | "nbformat_minor": 2
367 | }
368 |
--------------------------------------------------------------------------------
/ml/data/data-demo.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/ml/data/data-demo.pkl
--------------------------------------------------------------------------------
/ml/gesture_recognition.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/ml/gesture_recognition.pdf
--------------------------------------------------------------------------------
/optimization/imgs/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/.DS_Store
--------------------------------------------------------------------------------
/optimization/imgs/chi-homepage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/chi-homepage.png
--------------------------------------------------------------------------------
/optimization/imgs/gui-design.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/gui-design.png
--------------------------------------------------------------------------------
/optimization/imgs/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/header.png
--------------------------------------------------------------------------------
/optimization/imgs/history.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/history.png
--------------------------------------------------------------------------------
/optimization/imgs/integration-with-ucd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/integration-with-ucd.png
--------------------------------------------------------------------------------
/optimization/imgs/interactive-optimization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/interactive-optimization.png
--------------------------------------------------------------------------------
/optimization/imgs/landscapes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/landscapes.png
--------------------------------------------------------------------------------
/optimization/imgs/login-dialogue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/login-dialogue.png
--------------------------------------------------------------------------------
/optimization/imgs/menus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/menus.png
--------------------------------------------------------------------------------
/optimization/imgs/multi-objective.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/multi-objective.png
--------------------------------------------------------------------------------
/optimization/imgs/multidisciplinary-overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/multidisciplinary-overview.png
--------------------------------------------------------------------------------
/optimization/imgs/optimality.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/optimality.png
--------------------------------------------------------------------------------
/optimization/imgs/optimization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/optimization.png
--------------------------------------------------------------------------------
/optimization/imgs/overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/overview.png
--------------------------------------------------------------------------------
/optimization/imgs/problem-sizes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/problem-sizes.png
--------------------------------------------------------------------------------
/optimization/imgs/representations.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/representations.png
--------------------------------------------------------------------------------
/optimization/imgs/result-100000.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/result-100000.png
--------------------------------------------------------------------------------
/optimization/imgs/results-gallery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/results-gallery.png
--------------------------------------------------------------------------------
/optimization/imgs/sa-pseudocode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/sa-pseudocode.png
--------------------------------------------------------------------------------
/optimization/imgs/sa.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/sa.jpg
--------------------------------------------------------------------------------
/optimization/imgs/scatterplots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/scatterplots.png
--------------------------------------------------------------------------------
/optimization/imgs/simulated-annealing.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/simulated-annealing.gif
--------------------------------------------------------------------------------
/optimization/imgs/summary.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/summary.png
--------------------------------------------------------------------------------
/optimization/imgs/toolbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/toolbar.png
--------------------------------------------------------------------------------
/optimization/imgs/ucd-with-ML.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/ucd-with-ML.png
--------------------------------------------------------------------------------
/optimization/imgs/ucd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/optimization/imgs/ucd.png
--------------------------------------------------------------------------------
/optimization/render.py:
--------------------------------------------------------------------------------
1 | '''
2 | Plots a lattice layout in SVG format
3 |
4 | Original from : http://nbviewer.jupyter.org/gist/rpmuller/5666810
5 | Modified by Antti Oulasvirta, April 2017
6 | '''
7 |
8 | import math
9 |
10 | class SVGlayout:
11 | def __init__(self, labels, columns, padding = 5, associations = None):
12 | self.labels = labels
13 | self.columns = columns
14 | self.w = 100 # element width
15 | self.h = 70 # element height
16 | self.p = padding # padding
17 | self.border = 0
18 | if associations == None:
19 | self.colors = ['white'] * len(labels)
20 | else:
21 | self.colorize(associations)
22 | self.polygons = self.topolygons()
23 | self.inSVG = self.tosvg()
24 |
25 | def topolygons(self):
26 |
27 | """
28 | Converts a list of color assignments into polygons describing a lattice layout.
29 | Columns is the number of columns in the layout.
30 | Colors is the assignment of colors to cells in the lattice.
31 | """
32 |
33 | polygons = []
34 |
35 |
36 | for i,color in enumerate(self.colors):
37 | column = int(i / self.columns)
38 | row = i % self.columns
39 | w = self.w
40 | h = self.h
41 | p = self.p
42 | polygons.append([(row*w+p*(row+1),column*h+p*(column+1)),(row*w+w+p*(row+1),column*h+p*(column+1)),(row*w+w+p*(row+1),column*h+h+p*(column+1)),(row*w+p*(row+1),column*h+h+p*(column+1))])
43 |
44 | #[(-20,0),(0,100),(5,100),(5,0)]
45 | return polygons
46 | #colorindex = ['aqua','blue','fuchsia','gray','green','lime','maroon',
47 | # 'navy','olive','purple','red','silver','teal','yellow']
48 |
49 | def tosvg(self):
50 | """
51 | Convert a list of polygons and their colors into an SVG image.
52 | Polygons are lists of x,y tuples.
53 | Colors is a list of color names (e.g., 'aqua')
54 | """
55 | import xml.etree.ElementTree as ET
56 |
57 | xmin,xmax,ymin,ymax = self.bbox()
58 | width = xmax + self.p * 2
59 | height = ymax + self.p * 2
60 |
61 | # insert bounding box as a polygon
62 | svg = ET.Element('svg', xmlns="http://www.w3.org/2000/svg", version="1.1",
63 | height="%s" % height, width="%s" % width)
64 | canvas = [(0,0),(xmax+self.p,0),(xmax+self.p,ymax+self.p),(0,ymax+self.p)]
65 | self.polygons.insert(0,canvas)
66 | self.colors.insert(0,"white")
67 | self.labels.insert(0, "")
68 |
69 | # add each element to ET
70 | for i,polygon in enumerate(self.polygons):
71 | point_list = " ".join(["%d,%d" % (x,y) for (x,y) in polygon])
72 | ET.SubElement(svg,"polygon",fill=self.colors[i],
73 | stroke="black",points=point_list)
74 |
75 | # add labels
76 | e_h = int( (self.polygons[i][2][1] - self.polygons[i][0][1]) / 1.5) # positioning in a rectangle
77 |
78 | for i,label in enumerate(self.labels):
79 | e_w = int( (self.polygons[i][1][0] - self.polygons[i][0][0]) / (2 + len(label) / 1.15))
80 |
81 | el = ET.SubElement(svg,"text",x=str(self.polygons[i][0][0] + e_w),y=str(self.polygons[i][0][1] + e_h))
82 | el.set("font-size",str(25))
83 | el.text = label
84 | return ET.tostring(svg)
85 |
86 | def bbox(self):
87 | """
88 | Compute the bounding box of a list of polygons. Border adds an optional
89 | border amount to all values in the bbox.
90 | """
91 | xmin=ymin = 1e10
92 | xmax=ymax = -1e10
93 | for polygon in self.polygons:
94 | for x,y in polygon:
95 | xmax = max(xmax,x)
96 | xmin = min(xmin,x)
97 | ymax = max(ymax,y)
98 | ymin = min(ymin,y)
99 | return xmin-self.border,xmax+self.border,ymin-self.border,ymax+self.border
100 |
101 | # Posteriori coloring: Returns a color scheme [array] for a layout
102 | def colorize(self,associations):
103 | color_scheme = ['steelblue', 'dimgrey', 'lavender', 'lightblue', 'plum']
104 | colors = ['white'] * len(self.labels)
105 | k = 0
106 | for i in range(0, len(self.labels)):
107 | for j in range(i+1, len(self.labels)):
108 | association = max(0,associations.get(self.labels[i]+self.labels[j]), associations.get(self.labels[j] + self.labels[i]))
109 | if (distance (self.columns, i, j) <= 1.41) and (association > 0.0):
110 | if colors[i] == 'white' and colors[j] == 'white':
111 | colors[i] = color_scheme[k]
112 | colors[j] = color_scheme[k]
113 | k += 1
114 | elif colors[j] == 'white':
115 | colors [j] = colors[i]
116 | elif colors[i] == 'white':
117 | colors [i] = colors[j]
118 | self.colors = colors
119 |
120 | # Returns Euclidean (unit) distance between two positions in a layout
121 | def distance (columns, i, j):
122 | return math.sqrt( abs(j / columns - i / columns)**2 + abs( i % columns - j % columns)**2)
123 |
--------------------------------------------------------------------------------
/probabilisticfiltering/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/probabilisticfiltering/README.md:
--------------------------------------------------------------------------------
1 | # probabilisticfiltering
2 | Notes for the probabilistic filtering section of the CHI 2017 course
3 |
--------------------------------------------------------------------------------
/probabilisticfiltering/gestures.py:
--------------------------------------------------------------------------------
1 | from Tkinter import *
2 | import numpy as np
3 | import json
4 |
5 | class GestureData(object):
6 | def __init__(self, jsonfile):
7 | with open(jsonfile, "r") as f:
8 | gestures_json = json.load(f)
9 | self.screen_size = max(gestures_json["width"], gestures_json["height"])
10 | self.gestures = [np.array(path) for path in gestures_json["gestures"]]
11 | self.n_gestures = len(self.gestures)
12 |
13 | def get_template(self, i, t):
14 | if 0', self.motion)
34 | self.w.bind('', self.click)
35 | self.master.bind('', self.exit)
36 |
37 | self.ox, self.oy = None, None
38 |
39 | def exit(self, event):
40 | if self.gesture is not None:
41 | self.click()
42 |
43 | with open("gestures.txt", "w") as f:
44 | f.write(self.json())
45 | print "%d gestures recorded to gestures.txt" % (len(self.gestures))
46 | self.master.destroy()
47 |
48 |
49 | def redraw(self):
50 | w.move(line_id, 0, 1)
51 | master.after(50, redraw)
52 |
53 | def click(self, event):
54 | if self.gesture is None:
55 | self.gesture = []
56 | else:
57 | self.gestures.append(self.gesture)
58 | self.gesture = None
59 | self.w.delete("all")
60 |
61 | def motion(self,event):
62 | if self.gesture is not None:
63 | x, y = event.x, self.height - event.y
64 | self.gesture.append([x,y])
65 | self.w.create_line(self.ox, self.oy, x,y)
66 | self.ox, self.oy = x,y
67 |
68 | def json(self):
69 | return json.dumps({"width":self.width, "height":self.height, "gestures":self.gestures})
70 |
71 | def record_gestures():
72 | gesture = Gesture(400,400)
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/probabilisticfiltering/gestures.txt:
--------------------------------------------------------------------------------
1 | {"gestures": [[[220, 37], [212, 37], [207, 37], [201, 37], [198, 37], [194, 37], [188, 37], [179, 37], [166, 37], [161, 37], [158, 37], [153, 37], [149, 37], [144, 38], [137, 41], [135, 41], [133, 41], [130, 42], [128, 43], [124, 44], [122, 46], [116, 48], [115, 50], [112, 52], [108, 55], [104, 58], [99, 63], [95, 70], [94, 76], [94, 79], [94, 82], [94, 84], [94, 85], [94, 89], [95, 92], [98, 97], [101, 101], [103, 105], [104, 106], [108, 110], [118, 114], [131, 120], [144, 123], [153, 123], [159, 125], [173, 126], [180, 126], [188, 126], [192, 125], [195, 123], [195, 122], [190, 122], [179, 123], [160, 126], [151, 129], [134, 135], [122, 141], [115, 145], [112, 148], [108, 154], [105, 158], [103, 164], [101, 168], [98, 179], [98, 184], [98, 187], [98, 192], [98, 201], [103, 211], [107, 217], [108, 218], [113, 223], [118, 227], [126, 231], [138, 235], [151, 238], [160, 241], [166, 242], [174, 244], [182, 244], [191, 245], [195, 245], [200, 245], [203, 245], [209, 245], [210, 245], [213, 244], [214, 244], [215, 244], [216, 243], [217, 243]], [[262, 32], [259, 32], [247, 32], [227, 32], [211, 32], [193, 32], [177, 37], [166, 41], [162, 43], [153, 49], [144, 57], [141, 60], [136, 67], [133, 70], [127, 79], [124, 84], [121, 91], [118, 95], [115, 102], [112, 114], [113, 127], [119, 138], [123, 144], [135, 153], [148, 159], [167, 165], [184, 171], [193, 176], [203, 180], [211, 187], [217, 193], [219, 197], [221, 203], [222, 210], [222, 214], [221, 217], [218, 219], [216, 221], [209, 227], [201, 231], [195, 232], [192, 233], [189, 233], [184, 233], [183, 233], [176, 233], [174, 233], [167, 233], [158, 233], [148, 233], [135, 233], [128, 233], [124, 233], [116, 233], [111, 233], [105, 233], [95, 233], [86, 233], [78, 233], [75, 233], [72, 233], [68, 233], [66, 233], [64, 233], [63, 233]], [[66, 255], [66, 250], [65, 244], [64, 231], [64, 216], [64, 206], [64, 183], [64, 164], [64, 134], [71, 110], [74, 99], [82, 84], [91, 74], [96, 70], [99, 68], [106, 65], [115, 65], [122, 66], [129, 75], [133, 86], [138, 103], [141, 121], [142, 131], [142, 150], [144, 164], [144, 177], [147, 186], [149, 194], [152, 201], [157, 207], [163, 211], [169, 214], [177, 217], [182, 216], [187, 216], [194, 215], [202, 213], [207, 210], [210, 205], [212, 201], [214, 190], [216, 181], [219, 169], [220, 161], [220, 156], [221, 146], [224, 129], [224, 111], [224, 98], [224, 92], [224, 87], [224, 80], [224, 76], [224, 71], [224, 67], [223, 64], [222, 63], [222, 61], [221, 60], [221, 59], [219, 58]], [[229, 40], [216, 40], [199, 40], [177, 41], [156, 44], [145, 47], [135, 50], [125, 56], [120, 60], [117, 61], [112, 66], [103, 73], [99, 79], [99, 85], [99, 90], [99, 93], [100, 100], [100, 104], [103, 109], [104, 112], [106, 117], [110, 122], [112, 123], [115, 127], [116, 128], [123, 132], [128, 135], [129, 135], [134, 137], [142, 139], [152, 140], [161, 140], [166, 140], [170, 140], [173, 140], [175, 140], [178, 140], [179, 140], [180, 140], [181, 140], [182, 140], [183, 140], [186, 141], [188, 142], [189, 143], [189, 145], [190, 146], [192, 148], [195, 151], [197, 155], [199, 158], [199, 160], [201, 162], [202, 163], [203, 165], [204, 168], [205, 170], [206, 173], [209, 177], [209, 181], [209, 182], [210, 184], [210, 185], [210, 189], [210, 194], [209, 197], [209, 198], [207, 201], [206, 204], [205, 206], [204, 207], [201, 211], [198, 214], [194, 218], [189, 220], [186, 224], [181, 225], [176, 228], [169, 230], [165, 231], [162, 233], [160, 233], [155, 234], [152, 234], [149, 235], [146, 235], [141, 235], [138, 235], [131, 235], [127, 235], [120, 235], [111, 235], [100, 233], [91, 232], [88, 230], [81, 229], [75, 225], [72, 223], [71, 222], [71, 218], [69, 216], [69, 215], [68, 213], [68, 208], [69, 204], [69, 203], [70, 200], [72, 195], [73, 191], [77, 188], [82, 182], [84, 179], [87, 176], [92, 171], [95, 169], [99, 165], [103, 163], [104, 162], [109, 159], [116, 156], [118, 156], [119, 155], [123, 154], [128, 153], [130, 153], [131, 152], [135, 152], [138, 151], [139, 149], [141, 149], [145, 147], [147, 146], [149, 146], [152, 145], [153, 145], [154, 145], [155, 144], [156, 144], [157, 143], [159, 143], [159, 141], [160, 141], [161, 141]], [[229, 206], [219, 194], [211, 180], [199, 161], [190, 142], [178, 120], [168, 104], [164, 98], [159, 92], [156, 89], [155, 89], [153, 87], [148, 86], [140, 86], [129, 85], [124, 85], [120, 85], [116, 85], [110, 88], [101, 90], [91, 94], [85, 97], [84, 98], [79, 102], [70, 109], [60, 120], [54, 128], [53, 133], [52, 136], [50, 140], [50, 142], [51, 147], [52, 150], [53, 155], [59, 163], [64, 170], [72, 177], [78, 180], [82, 183], [91, 186], [104, 190], [115, 191], [123, 191], [131, 191], [135, 189], [141, 185], [146, 180], [151, 175], [156, 169], [159, 167], [163, 163], [170, 155], [176, 148], [181, 142], [189, 134], [195, 127], [202, 120], [205, 114], [210, 108], [213, 106], [214, 105], [216, 102], [216, 101], [218, 97], [219, 96], [222, 94], [222, 93], [224, 91], [225, 88], [226, 87], [227, 85], [229, 84], [231, 80], [232, 78], [233, 77], [234, 76], [235, 74], [237, 73], [238, 72]], [[72, 256], [72, 252], [70, 241], [69, 226], [67, 217], [67, 199], [67, 185], [67, 180], [68, 163], [70, 138], [71, 126], [74, 120], [76, 111], [82, 99], [85, 92], [88, 88], [92, 82], [97, 72], [102, 66], [110, 60], [116, 56], [120, 55], [127, 55], [134, 55], [139, 57], [146, 60], [161, 69], [172, 75], [182, 85], [191, 99], [193, 107], [194, 119], [194, 124], [189, 134], [183, 140], [176, 145], [168, 149], [162, 150], [159, 151], [154, 151], [143, 153], [136, 154], [132, 154], [123, 154], [114, 152], [108, 152], [102, 151], [99, 150], [97, 150], [96, 150], [95, 150], [93, 150], [91, 150], [88, 149], [87, 149], [85, 149], [84, 149], [83, 149], [80, 149], [79, 149], [78, 149], [77, 149], [76, 150], [75, 150], [72, 151], [71, 152], [71, 155], [71, 156], [71, 159], [73, 164], [74, 169], [76, 172], [80, 177], [85, 182], [88, 186], [91, 188], [95, 192], [98, 195], [103, 199], [106, 200], [110, 204], [119, 211], [131, 220], [145, 228], [156, 234], [160, 235], [169, 241], [174, 243], [184, 246], [187, 247], [196, 250], [197, 251], [200, 251], [202, 253], [203, 253], [204, 253], [205, 253], [207, 254], [208, 254]]], "width": 400, "height": 400}
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/brain_inference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/brain_inference.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/brain_inference.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
415 |
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/brainspace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/brainspace.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/capture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/capture.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/control_loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/control_loop.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/control_loop.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
468 |
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/finger_sequence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/finger_sequence.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/finger_track.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/finger_track.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/finger_track.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
399 |
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/fwd_inv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/fwd_inv.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/fwd_inv.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
777 |
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/gesture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/gesture.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/gesture.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
484 |
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/header.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/phase.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/phase.gif
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/stochastic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/stochastic.png
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/svm.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/svm.jpg
--------------------------------------------------------------------------------
/probabilisticfiltering/imgs/undo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnhw/computationalchi2017/ac4f3c203009e28032a8a42a6534db6b55df5540/probabilisticfiltering/imgs/undo.jpg
--------------------------------------------------------------------------------