From 0ba138a9dcc0eec53459ed2c85e8022d7fb5c436 Mon Sep 17 00:00:00 2001 From: Michiel Cottaar <MichielCottaar@gmail.com> Date: Sat, 17 Feb 2018 15:12:48 +0000 Subject: [PATCH] probabilistic programming --- talks/packages/packages.md | 268 ++++++++++++++++++++++++------------- 1 file changed, 178 insertions(+), 90 deletions(-) diff --git a/talks/packages/packages.md b/talks/packages/packages.md index b9ee03f..7d11138 100644 --- a/talks/packages/packages.md +++ b/talks/packages/packages.md @@ -70,10 +70,6 @@ Alternatives: ## [Ipython](http://ipython.org/)/[Jupyter](https://jupyter.org/) notebook: interactive python environments Supports: -- setting up matplotlib -``` -%matplotlib nbagg -``` - run code in multiple languages ``` %%bash @@ -99,6 +95,11 @@ optimize.minimize(costfunc, x0=[0], method='l-bfgs-b') plt.plot([0, 3]) ``` +- getting help +``` +plt.plot? +``` + - [and much more...](https://ipython.readthedocs.io/en/stable/interactive/magics.html) The next generation is already out: [jupyterlab](https://jupyterlab.readthedocs.io/en/latest/) @@ -225,7 +226,7 @@ if __name__ == '__main__': ``` ``` -%run test_argparse.py 3 8.5 -q +%run test_argparse.py 3 8.5 ``` Alternatives: @@ -283,7 +284,7 @@ if __name__ == '__main__': ``` ``` -%run test_gooey.py +!python.app test_gooey.py ``` ``` @@ -327,6 +328,10 @@ This can for example be used to produce static HTML output in a highly flexible ``` ``` +import numpy as np +import matplotlib.pyplot as plt +plt.ioff() + def plot_sine(amplitude, frequency): x = np.linspace(0, 2 * np.pi, 100) y = amplitude * np.sin(frequency * x) @@ -342,6 +347,7 @@ def plot_sine(amplitude, frequency): !mkdir plots amplitudes = [plot_sine(A, 1.) for A in [0.1, 0.3, 0.7, 1.0]] frequencies = [plot_sine(1., F) for F in [1, 2, 3, 4, 5, 6]] +plt.ion() ``` ``` @@ -484,6 +490,71 @@ if __name__ == '__main__': - theano/tensorflow/pytorch - keras +## [pymc3](http://docs.pymc.io/): Pobabilstic programming +``` +import numpy as np +import matplotlib.pyplot as plt + +# Initialize random number generator +np.random.seed(123) + +# True parameter values +alpha, sigma = 1, 1 +beta = [1, 2.5] + +# Size of dataset +size = 100 + +# Predictor variable +X1 = np.random.randn(size) +X2 = np.random.randn(size) * 0.2 + +# Simulate outcome variable +Y = alpha + beta[0]*X1 + beta[1]*X2 + np.random.randn(size)*sigma +``` + +``` +import pymc3 as pm +basic_model = pm.Model() + +with basic_model: + + # Priors for unknown model parameters + alpha = pm.Normal('alpha', mu=0, sd=10) + beta = pm.Normal('beta', mu=0, sd=10, shape=2) + sigma = pm.HalfNormal('sigma', sd=1) + + # Expected value of outcome + mu = alpha + beta[0]*X1 + beta[1]*X2 + + # Likelihood (sampling distribution) of observations + Y_obs = pm.Normal('Y_obs', mu=mu, sd=sigma, observed=Y) +``` + +``` +with basic_model: + + # obtain starting values via MAP + start = pm.find_MAP(fmin=optimize.fmin_powell) + + # instantiate sampler + step = pm.Slice() + + # draw 5000 posterior samples + trace = pm.sample(5000, step=step, start=start) +``` + +``` +_ = pm.traceplot(trace) +``` + +``` +pm.summary(trace) +``` + +Alternative: [pystan](https://pystan.readthedocs.io/en/latest/): wrapper around the [Stan](http://mc-stan.org/users/) probabilistic programming language. + + ## [Pycuda](https://documen.tician.de/pycuda/): Programming the GPU Wrapper around [Cuda](https://developer.nvidia.com/cuda-zone). The alternative [Pyopencl](https://documen.tician.de/pyopencl/) provides a very similar wrapper around [OpenCL](https://www.khronos.org/opencl/). @@ -516,87 +587,87 @@ print(dest-a*b) Also see [pyopenGL](http://pyopengl.sourceforge.net/): graphics programming in python (used in FSLeyes) ## Testing - [unittest](https://docs.python.org/3.6/library/unittest.html): python built-in testing -> ``` -> import unittest -> -> class TestStringMethods(unittest.TestCase): -> -> def test_upper(self): -> self.assertEqual('foo'.upper(), 'FOO') -> -> def test_isupper(self): -> self.assertTrue('FOO'.isupper()) -> self.assertFalse('Foo'.isupper()) -> -> def test_split(self): -> s = 'hello world' -> self.assertEqual(s.split(), ['hello', 'world']) -> # check that s.split fails when the separator is not a string -> with self.assertRaises(TypeError): -> s.split(2) -> -> if __name__ == '__main__': -> unittest.main() -> ``` +``` +import unittest + +class TestStringMethods(unittest.TestCase): + + def test_upper(self): + self.assertEqual('foo'.upper(), 'FOO') + + def test_isupper(self): + self.assertTrue('FOO'.isupper()) + self.assertFalse('Foo'.isupper()) + + def test_split(self): + s = 'hello world' + self.assertEqual(s.split(), ['hello', 'world']) + # check that s.split fails when the separator is not a string + with self.assertRaises(TypeError): + s.split(2) + +if __name__ == '__main__': + unittest.main() +``` - [doctest](https://docs.python.org/3.6/library/doctest.html): checks the example usage in the documentation -> ``` -> def factorial(n): -> """Return the factorial of n, an exact integer >= 0. -> -> >>> [factorial(n) for n in range(6)] -> [1, 1, 2, 6, 24, 120] -> >>> factorial(30) -> 265252859812191058636308480000000 -> >>> factorial(-1) -> Traceback (most recent call last): -> ... -> ValueError: n must be >= 0 -> -> Factorials of floats are OK, but the float must be an exact integer: -> >>> factorial(30.1) -> Traceback (most recent call last): -> ... -> ValueError: n must be exact integer -> >>> factorial(30.0) -> 265252859812191058636308480000000 -> -> It must also not be ridiculously large: -> >>> factorial(1e100) -> Traceback (most recent call last): -> ... -> OverflowError: n too large -> """ -> -> import math -> if not n >= 0: -> raise ValueError("n must be >= 0") -> if math.floor(n) != n: -> raise ValueError("n must be exact integer") -> if n+1 == n: # catch a value like 1e300 -> raise OverflowError("n too large") -> result = 1 -> factor = 2 -> while factor <= n: -> result *= factor -> factor += 1 -> return result -> -> -> if __name__ == "__main__": -> import doctest -> doctest.testmod() -> ``` +``` +def factorial(n): + """Return the factorial of n, an exact integer >= 0. + + >>> [factorial(n) for n in range(6)] + [1, 1, 2, 6, 24, 120] + >>> factorial(30) + 265252859812191058636308480000000 + >>> factorial(-1) + Traceback (most recent call last): + ... + ValueError: n must be >= 0 + + Factorials of floats are OK, but the float must be an exact integer: + >>> factorial(30.1) + Traceback (most recent call last): + ... + ValueError: n must be exact integer + >>> factorial(30.0) + 265252859812191058636308480000000 + + It must also not be ridiculously large: + >>> factorial(1e100) + Traceback (most recent call last): + ... + OverflowError: n too large + """ + + import math + if not n >= 0: + raise ValueError("n must be >= 0") + if math.floor(n) != n: + raise ValueError("n must be exact integer") + if n+1 == n: # catch a value like 1e300 + raise OverflowError("n too large") + result = 1 + factor = 2 + while factor <= n: + result *= factor + factor += 1 + return result + + +if __name__ == "__main__": + import doctest + doctest.testmod() +``` Two external packages provide more convenient unit tests: - [py.test](https://docs.pytest.org/en/latest/) - [nose2](http://nose2.readthedocs.io/en/latest/usage.html) -> ``` -> # content of test_sample.py -> def inc(x): -> return x + 1 -> -> def test_answer(): -> assert inc(3) == 5 -> ``` +``` +# content of test_sample.py +def inc(x): + return x + 1 + +def test_answer(): + assert inc(3) == 5 +``` - [coverage](https://coverage.readthedocs.io/en/coverage-4.5.1/): measures which part of the code is covered by the tests @@ -605,8 +676,7 @@ Linters check the code for any syntax errors, [style errors](https://www.python. - [pylint](https://pypi.python.org/pypi/pylint): most extensive linter - [pyflake](https://pypi.python.org/pypi/pyflakes): if you think pylint is too strict - [pep8](https://pypi.python.org/pypi/pep8): just checks for style errors -### Static typing -Optional static typing: +### Optional static typing - Document how your method/function should be called - Static checking of whether your type hints are still up to date - Static checking of whether you call your own function correctly @@ -619,12 +689,12 @@ def greet_all(names: List[str]) -> None: for name in names: print('Hello, {}'.format(name)) -greet_all(['python', 'ruby']) # type checker will be fine with this +greet_all(['python', 'java', 'C++']) # type checker will be fine with this -greet_all('some name') # this will actually run fine, but type checker will raise an error +greet_all('matlab') # this will actually run fine, but type checker will raise an error ``` -Packages to use this: +Packages: - [typing](https://docs.python.org/3/library/typing.html): built-in library containing generics, unions, etc. - [mypy](http://mypy-lang.org/): linter doing static type checking - [pyAnnotate](https://github.com/dropbox/pyannotate): automatically assign types to most of your functions/methods based on runtime @@ -636,7 +706,7 @@ Packages to use this: There are also many, many libraries to interact with databases, but you will have to google those yourself. -# Several honourable mentions +# Quick mentions - [trimesh](https://github.com/mikedh/trimesh): Triangular mesh algorithms - [Pillow](https://pillow.readthedocs.io/en/latest/): Read/write/manipulate a wide variety of images (png, jpg, tiff, etc.) - [psychopy](http://www.psychopy.org/): equivalent of psychtoolbox (workshop coming up in April in Nottingham) @@ -653,6 +723,24 @@ There are also many, many libraries to interact with databases, but you will hav - [pickle](https://docs.python.org/3/library/pickle.html): Store/load any python object - [shutil](https://docs.python.org/3/library/shutil.html): copy/move files - [subprocess](https://docs.python.org/3/library/subprocess.html): call shell commands - - [time](https://docs.python.org/3/library/time.html)/[timeit](https://docs.python.org/3/library/timeit.html): keeping track of it + - [time](https://docs.python.org/3/library/time.html)/[timeit](https://docs.python.org/3/library/timeit.html): Timing your code - [turtle](https://docs.python.org/3/library/turtle.html#module-turtle): teach python to your kids! - [warnings](https://docs.python.org/3/library/warnings.html#module-warnings): tell people they are not using your code properly + +``` +from turtle import * +color('red', 'yellow') +begin_fill() +speed(10) +while True: + forward(200) + left(170) + if abs(pos()) < 1: + break +end_fill() +done() +``` + +``` +import this +``` \ No newline at end of file -- GitLab