├── Uebung 3
├── ff
├── map.png
├── office.png
├── shoes
│ ├── p.pddl
│ └── d.pddl
├── abc
│ ├── abc-p.pddl
│ └── abc-d.pddl
└── 03-CSPs_Planning.ipynb
├── requirements.txt
├── Uebung 5
├── daten.csv
├── iris.csv
└── 05-ML.ipynb
├── README.md
├── .gitignore
├── Uebung 4
└── 04-reasoning.ipynb
├── Uebung 1
└── 01-agents.ipynb
├── Uebung 0
└── 00-pythonintro.ipynb
└── Uebung 2
└── 02-search.ipynb
/Uebung 3/ff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ofenske/SS-KI1/HEAD/Uebung 3/ff
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | matplotlib
2 | numpy
3 | scipy
4 | pandas
5 | scikit-learn
--------------------------------------------------------------------------------
/Uebung 3/map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ofenske/SS-KI1/HEAD/Uebung 3/map.png
--------------------------------------------------------------------------------
/Uebung 3/office.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ofenske/SS-KI1/HEAD/Uebung 3/office.png
--------------------------------------------------------------------------------
/Uebung 3/shoes/p.pddl:
--------------------------------------------------------------------------------
1 | (define (problem shoes)
2 | (:domain shoes)
3 | (:objects left right - foot)
4 | (:init todo)
5 | (:goal todo)
6 | )
--------------------------------------------------------------------------------
/Uebung 5/daten.csv:
--------------------------------------------------------------------------------
1 | Name,Alter,Stadt,Beruf
2 | Alice,25,Berlin,Ingenieur
3 | Bob,30,München,Lehrer
4 | Charlie,35,Hamburg,Arzt
5 | Dave,40,Frankfurt,Anwalt
6 | Eve,45,Köln,Designer
7 | Klaus,12,Rostock,INformatiker
8 |
--------------------------------------------------------------------------------
/Uebung 3/shoes/d.pddl:
--------------------------------------------------------------------------------
1 | (define (domain shoes)
2 | (:types
3 | foot - object
4 | )
5 |
6 | (:predicates
7 | (hasSock ?f - foot)
8 | (hasShoe ?f - foot)
9 | )
10 |
11 | (:action putOnSock
12 | :parameters (?f - foot)
13 | :precondition (not (hasSock ?f))
14 | :effect (hasSock ?f)
15 | )
16 |
17 | (:action putOnShoe
18 | :parameters (todo)
19 | :precondition (todo)
20 | :effect (todo)
21 | )
22 |
23 | )
24 |
--------------------------------------------------------------------------------
/Uebung 3/abc/abc-p.pddl:
--------------------------------------------------------------------------------
1 | (define (problem abc1)
2 | (:domain abc)
3 | (:objects a b c - job
4 | alice bob - agent)
5 | (:init
6 | (at outside alice)
7 | (at outside bob)
8 | (provides water water-tap)
9 | (provides paper paper-stack)
10 | (provides ground-coffee coffee-jar)
11 | (resource-of paper printer)
12 | (resource-of water coffee-machine)
13 | (resource-of ground-coffee coffee-machine)
14 | (hands-free alice)
15 | (hands-free bob))
16 | (:goal ;TODO)
17 |
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SS-KI1
2 | This is the repository for the exercise lecture of the module "Smart Computing"/"Grundlagen der Künstlichen Intelligenz" at the University of Rostock.
3 | There are two ways to execute the material:
4 | 1. Download and execute everything locally on your own laptop.
5 | 2. Execute the material with Binder.
6 |
7 | For the first variant there are the following requirements:
8 | 1. Python and the required packages installed
9 | 2. Jupyter notebook/lab installed
10 |
11 | We would recommend to install all of the above mentioned software via Anaconda (https://www.anaconda.com/).
12 |
13 | Additionally, you can execute the whole repository via Binder (without installing anything): [](https://mybinder.org/v2/gh/turing-tester95/SS2023-KI1/HEAD)
14 |
--------------------------------------------------------------------------------
/Uebung 3/abc/abc-d.pddl:
--------------------------------------------------------------------------------
1 | (define (domain abc)
2 | (:types item location job agent)
3 | (:constants door printer paper-stack coffee-machine water-tap coffee-jar outside - location
4 | water paper ground-coffee coffee - item)
5 | (:predicates
6 | (at ?l ?a)
7 | (has ?i ?l)
8 | (hands-free ?a)
9 | (holds ?i ?a)
10 | (resource-of ?i ?l)
11 | (provides ?i ?l)
12 | (printed ?j)
13 | )
14 |
15 | (:action print
16 | :parameters (;TODO)
17 | :precondition (;TODO)
18 | :effect (;TODO)
19 | )
20 |
21 |
22 | (:action get-coffee
23 | :parameters (;TODO)
24 | :precondition (;TODO)
25 | :effect (;TODO)
26 | )
27 |
28 | (:action fetch
29 | :parameters (;TODO)
30 | :precondition (;TODO)
31 | :effect (;TODO)
32 | )
33 |
34 | (:action replenish
35 | :parameters (;TODO)
36 | :precondition (;TODO)
37 | :effect (;TODO)
38 | )
39 |
40 | (:action goto
41 | :parameters (?a - agent ?x ?y - location)
42 | :precondition (and (not (= ?x ?y))
43 | (at ?x ?a))
44 | :effect (and (not (at ?x ?a))
45 | (at ?y ?a)))
46 | )
47 |
48 |
--------------------------------------------------------------------------------
/.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 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | # MacOS
132 | .DS_Store
133 | .idea
134 | *lsg.ipynb
135 |
136 | # project specific
137 | backup
138 |
139 |
--------------------------------------------------------------------------------
/Uebung 3/03-CSPs_Planning.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# 3. Constraint Satisfaction Probleme und Planung\n",
8 | "\n",
9 | "## 3.1. Kartenfärbungsprobleme als CSP\n",
10 | "Gegeben sei die folgende Karte von Mecklenburg-Vorpommern. \n",
11 | "\n",
12 | "\n",
13 | "* Spezifizieren Sie, analog zur Vorlesung, das zugehörige Kartenfärbungsproblem für 3 Farben als Constraint Satisfaction Problem. Geben Sie für alle Variablen die Domänen und alle notwendigen Bedingungen an.\n",
14 | "\n",
15 | "* Bestimmen Sie eine Lösung für dieses Problem über Suche mit Backtracking! Benutzen Sie dabei die Heuristik Minimum remaining values und geben Sie für jeden Zwischenschritt und jedes Land die möglichen Farben an!"
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {},
21 | "source": [
22 | "## 3.2. Ein einfaches Planungs-Problem\n",
23 | "Das Anziehen von Socken und Schuhen ist ein Planungsproblem. Schuhe können nur angezogen werden, wenn die jeweilige Socke schon angezogen ist. In dieser Aufgabe soll das Anziehen von Socken und Schuhen modelliert werden.\n",
24 | "* Zeichnen Sie den partiell geordneten Plan, und alle total geordneten Pläne auf.\n",
25 | "* Modellieren und lösen Sie das Problem mithilfe der Problem-Domain-Definition-Language (PDDL). \n",
26 | " * Folgen Sie dafür dem folgenden Link: http://editor.planning.domains/#\n",
27 | " * Definieren Sie jeweils eine Datei problem.pddl für das Problem und domain.pddl für die Domäne.\n",
28 | " * Führen den Solver aus und lassen Sie sich eine Lösung ausgeben.\n",
29 | "* Alternativ starten Sie ein neues Terminal hier im Jupyter Dashboard und navigieren in den Ordner \"U4\".\n",
30 | "* Den Planer können Sie wie folgt aufrufen: ./ff -o shoes/d.pddl -f shoes/p.pddl. Interpretieren Sie die Ausgabe."
31 | ]
32 | },
33 | {
34 | "cell_type": "markdown",
35 | "metadata": {},
36 | "source": [
37 | "## 3.3. Das Office-Planungsproblem\n",
38 | "In dieser Aufgabe soll der typische Arbeitstag der Mitarbeiter am Lehrstuhl MMIS (Kaffee holen, umherlaufen, Dinge ausdrucken) als Planungsproblem modelliert werden. Mitarbeiter können nur Kaffee machen, wenn die Kaffeemaschine mit Kaffee und Wasser befüllt ist. Kaffee kann am Kaffee-Glas geholt werden, Wasser am Wasserhahn. Mitarbeiter können immer nur ein Ding gleichzeitig in der Hand halten. Am Drucker kann nur gedruckt werden, wenn der Drucker mit Papier befüllt ist. Papier gibt es am Papier-Schrank. Das Ziel der Mitarbeiter ist es, alle Printjobs gedruckt zu haben, alle einen Kaffee in der Hand zu halten, und am Ausgang zu stehen.\n",
39 | "\n",
40 | "\n",
41 | "\n",
42 | "Die verfügbare Aktionen der Mitarbeiter sind:\n",
43 | "\n",
44 | "* goto: Ein Mitarbeiter bewegt sich zwischen zwei Positionen. Die beiden Positionen dürfen nicht gleich sein.\n",
45 | "* fetch: Ein Mitarbeiter nimmt Papier, Kaffee oder Wasser, wenn er sich an der jeweigen Location befindet.\n",
46 | "* replenish: Ein Mitarbeiter füllt den Drucker oder die Kaffeemaschine auf. Das geht dann, wenn der die entsprechende Ressource in der Hand hält.\n",
47 | "* get-coffee: Ein Mitarbeiter nimmt sich einen Kaffee, wenn er an der Maschine steht, und diese befüllt ist.\n",
48 | "* print: Ein Mitarbeiter druckt einen Printjob, wenn er am Drucker steht, und der Drucker Papier enthält.\n",
49 | "\n",
50 | "Definieren Sie die entsprechenden Aktionen in der Domänen-Datei abc-d.pddl. Rufen Sie den Planer wie folgt auf: ./ff -o abc/abc-d.pddl -f abc/abc-p1.pddl. Interpretieren Sie die Ausgabe."
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {},
56 | "source": []
57 | }
58 | ],
59 | "metadata": {
60 | "kernelspec": {
61 | "display_name": "Python 3 (ipykernel)",
62 | "language": "python",
63 | "name": "python3"
64 | },
65 | "language_info": {
66 | "codemirror_mode": {
67 | "name": "ipython",
68 | "version": 3
69 | },
70 | "file_extension": ".py",
71 | "mimetype": "text/x-python",
72 | "name": "python",
73 | "nbconvert_exporter": "python",
74 | "pygments_lexer": "ipython3",
75 | "version": "3.10.2"
76 | }
77 | },
78 | "nbformat": 4,
79 | "nbformat_minor": 4
80 | }
81 |
--------------------------------------------------------------------------------
/Uebung 5/iris.csv:
--------------------------------------------------------------------------------
1 | ,SepalLength,SepalWidth,PetalLength,PetalWidth,Name
2 | 0,5.1,3.5,1.4,0.2,Iris-setosa
3 | 1,4.9,3.0,1.4,0.2,Iris-setosa
4 | 2,4.7,3.2,1.3,0.2,Iris-setosa
5 | 3,4.6,3.1,1.5,0.2,Iris-setosa
6 | 4,5.0,3.6,1.4,0.2,Iris-setosa
7 | 5,5.4,3.9,1.7,0.4,Iris-setosa
8 | 6,4.6,3.4,1.4,0.3,Iris-setosa
9 | 7,5.0,3.4,1.5,0.2,Iris-setosa
10 | 8,4.4,2.9,1.4,0.2,Iris-setosa
11 | 9,4.9,3.1,1.5,0.1,Iris-setosa
12 | 10,5.4,3.7,1.5,0.2,Iris-setosa
13 | 11,4.8,3.4,1.6,0.2,Iris-setosa
14 | 12,4.8,3.0,1.4,0.1,Iris-setosa
15 | 13,4.3,3.0,1.1,0.1,Iris-setosa
16 | 14,5.8,4.0,1.2,0.2,Iris-setosa
17 | 15,5.7,4.4,1.5,0.4,Iris-setosa
18 | 16,5.4,3.9,1.3,0.4,Iris-setosa
19 | 17,5.1,3.5,1.4,0.3,Iris-setosa
20 | 18,5.7,3.8,1.7,0.3,Iris-setosa
21 | 19,5.1,3.8,1.5,0.3,Iris-setosa
22 | 20,5.4,3.4,1.7,0.2,Iris-setosa
23 | 21,5.1,3.7,1.5,0.4,Iris-setosa
24 | 22,4.6,3.6,1.0,0.2,Iris-setosa
25 | 23,5.1,3.3,1.7,0.5,Iris-setosa
26 | 24,4.8,3.4,1.9,0.2,Iris-setosa
27 | 25,5.0,3.0,1.6,0.2,Iris-setosa
28 | 26,5.0,3.4,1.6,0.4,Iris-setosa
29 | 27,5.2,3.5,1.5,0.2,Iris-setosa
30 | 28,5.2,3.4,1.4,0.2,Iris-setosa
31 | 29,4.7,3.2,1.6,0.2,Iris-setosa
32 | 30,4.8,3.1,1.6,0.2,Iris-setosa
33 | 31,5.4,3.4,1.5,0.4,Iris-setosa
34 | 32,5.2,4.1,1.5,0.1,Iris-setosa
35 | 33,5.5,4.2,1.4,0.2,Iris-setosa
36 | 34,4.9,3.1,1.5,0.1,Iris-setosa
37 | 35,5.0,3.2,1.2,0.2,Iris-setosa
38 | 36,5.5,3.5,1.3,0.2,Iris-setosa
39 | 37,4.9,3.1,1.5,0.1,Iris-setosa
40 | 38,4.4,3.0,1.3,0.2,Iris-setosa
41 | 39,5.1,3.4,1.5,0.2,Iris-setosa
42 | 40,5.0,3.5,1.3,0.3,Iris-setosa
43 | 41,4.5,2.3,1.3,0.3,Iris-setosa
44 | 42,4.4,3.2,1.3,0.2,Iris-setosa
45 | 43,5.0,3.5,1.6,0.6,Iris-setosa
46 | 44,5.1,3.8,1.9,0.4,Iris-setosa
47 | 45,4.8,3.0,1.4,0.3,Iris-setosa
48 | 46,5.1,3.8,1.6,0.2,Iris-setosa
49 | 47,4.6,3.2,1.4,0.2,Iris-setosa
50 | 48,5.3,3.7,1.5,0.2,Iris-setosa
51 | 49,5.0,3.3,1.4,0.2,Iris-setosa
52 | 50,7.0,3.2,4.7,1.4,Iris-versicolor
53 | 51,6.4,3.2,4.5,1.5,Iris-versicolor
54 | 52,6.9,3.1,4.9,1.5,Iris-versicolor
55 | 53,5.5,2.3,4.0,1.3,Iris-versicolor
56 | 54,6.5,2.8,4.6,1.5,Iris-versicolor
57 | 55,5.7,2.8,4.5,1.3,Iris-versicolor
58 | 56,6.3,3.3,4.7,1.6,Iris-versicolor
59 | 57,4.9,2.4,3.3,1.0,Iris-versicolor
60 | 58,6.6,2.9,4.6,1.3,Iris-versicolor
61 | 59,5.2,2.7,3.9,1.4,Iris-versicolor
62 | 60,5.0,2.0,3.5,1.0,Iris-versicolor
63 | 61,5.9,3.0,4.2,1.5,Iris-versicolor
64 | 62,6.0,2.2,4.0,1.0,Iris-versicolor
65 | 63,6.1,2.9,4.7,1.4,Iris-versicolor
66 | 64,5.6,2.9,3.6,1.3,Iris-versicolor
67 | 65,6.7,3.1,4.4,1.4,Iris-versicolor
68 | 66,5.6,3.0,4.5,1.5,Iris-versicolor
69 | 67,5.8,2.7,4.1,1.0,Iris-versicolor
70 | 68,6.2,2.2,4.5,1.5,Iris-versicolor
71 | 69,5.6,2.5,3.9,1.1,Iris-versicolor
72 | 70,5.9,3.2,4.8,1.8,Iris-versicolor
73 | 71,6.1,2.8,4.0,1.3,Iris-versicolor
74 | 72,6.3,2.5,4.9,1.5,Iris-versicolor
75 | 73,6.1,2.8,4.7,1.2,Iris-versicolor
76 | 74,6.4,2.9,4.3,1.3,Iris-versicolor
77 | 75,6.6,3.0,4.4,1.4,Iris-versicolor
78 | 76,6.8,2.8,4.8,1.4,Iris-versicolor
79 | 77,6.7,3.0,5.0,1.7,Iris-versicolor
80 | 78,6.0,2.9,4.5,1.5,Iris-versicolor
81 | 79,5.7,2.6,3.5,1.0,Iris-versicolor
82 | 80,5.5,2.4,3.8,1.1,Iris-versicolor
83 | 81,5.5,2.4,3.7,1.0,Iris-versicolor
84 | 82,5.8,2.7,3.9,1.2,Iris-versicolor
85 | 83,6.0,2.7,5.1,1.6,Iris-versicolor
86 | 84,5.4,3.0,4.5,1.5,Iris-versicolor
87 | 85,6.0,3.4,4.5,1.6,Iris-versicolor
88 | 86,6.7,3.1,4.7,1.5,Iris-versicolor
89 | 87,6.3,2.3,4.4,1.3,Iris-versicolor
90 | 88,5.6,3.0,4.1,1.3,Iris-versicolor
91 | 89,5.5,2.5,4.0,1.3,Iris-versicolor
92 | 90,5.5,2.6,4.4,1.2,Iris-versicolor
93 | 91,6.1,3.0,4.6,1.4,Iris-versicolor
94 | 92,5.8,2.6,4.0,1.2,Iris-versicolor
95 | 93,5.0,2.3,3.3,1.0,Iris-versicolor
96 | 94,5.6,2.7,4.2,1.3,Iris-versicolor
97 | 95,5.7,3.0,4.2,1.2,Iris-versicolor
98 | 96,5.7,2.9,4.2,1.3,Iris-versicolor
99 | 97,6.2,2.9,4.3,1.3,Iris-versicolor
100 | 98,5.1,2.5,3.0,1.1,Iris-versicolor
101 | 99,5.7,2.8,4.1,1.3,Iris-versicolor
102 | 100,6.3,3.3,6.0,2.5,Iris-virginica
103 | 101,5.8,2.7,5.1,1.9,Iris-virginica
104 | 102,7.1,3.0,5.9,2.1,Iris-virginica
105 | 103,6.3,2.9,5.6,1.8,Iris-virginica
106 | 104,6.5,3.0,5.8,2.2,Iris-virginica
107 | 105,7.6,3.0,6.6,2.1,Iris-virginica
108 | 106,4.9,2.5,4.5,1.7,Iris-virginica
109 | 107,7.3,2.9,6.3,1.8,Iris-virginica
110 | 108,6.7,2.5,5.8,1.8,Iris-virginica
111 | 109,7.2,3.6,6.1,2.5,Iris-virginica
112 | 110,6.5,3.2,5.1,2.0,Iris-virginica
113 | 111,6.4,2.7,5.3,1.9,Iris-virginica
114 | 112,6.8,3.0,5.5,2.1,Iris-virginica
115 | 113,5.7,2.5,5.0,2.0,Iris-virginica
116 | 114,5.8,2.8,5.1,2.4,Iris-virginica
117 | 115,6.4,3.2,5.3,2.3,Iris-virginica
118 | 116,6.5,3.0,5.5,1.8,Iris-virginica
119 | 117,7.7,3.8,6.7,2.2,Iris-virginica
120 | 118,7.7,2.6,6.9,2.3,Iris-virginica
121 | 119,6.0,2.2,5.0,1.5,Iris-virginica
122 | 120,6.9,3.2,5.7,2.3,Iris-virginica
123 | 121,5.6,2.8,4.9,2.0,Iris-virginica
124 | 122,7.7,2.8,6.7,2.0,Iris-virginica
125 | 123,6.3,2.7,4.9,1.8,Iris-virginica
126 | 124,6.7,3.3,5.7,2.1,Iris-virginica
127 | 125,7.2,3.2,6.0,1.8,Iris-virginica
128 | 126,6.2,2.8,4.8,1.8,Iris-virginica
129 | 127,6.1,3.0,4.9,1.8,Iris-virginica
130 | 128,6.4,2.8,5.6,2.1,Iris-virginica
131 | 129,7.2,3.0,5.8,1.6,Iris-virginica
132 | 130,7.4,2.8,6.1,1.9,Iris-virginica
133 | 131,7.9,3.8,6.4,2.0,Iris-virginica
134 | 132,6.4,2.8,5.6,2.2,Iris-virginica
135 | 133,6.3,2.8,5.1,1.5,Iris-virginica
136 | 134,6.1,2.6,5.6,1.4,Iris-virginica
137 | 135,7.7,3.0,6.1,2.3,Iris-virginica
138 | 136,6.3,3.4,5.6,2.4,Iris-virginica
139 | 137,6.4,3.1,5.5,1.8,Iris-virginica
140 | 138,6.0,3.0,4.8,1.8,Iris-virginica
141 | 139,6.9,3.1,5.4,2.1,Iris-virginica
142 | 140,6.7,3.1,5.6,2.4,Iris-virginica
143 | 141,6.9,3.1,5.1,2.3,Iris-virginica
144 | 142,5.8,2.7,5.1,1.9,Iris-virginica
145 | 143,6.8,3.2,5.9,2.3,Iris-virginica
146 | 144,6.7,3.3,5.7,2.5,Iris-virginica
147 | 145,6.7,3.0,5.2,2.3,Iris-virginica
148 | 146,6.3,2.5,5.0,1.9,Iris-virginica
149 | 147,6.5,3.0,5.2,2.0,Iris-virginica
150 | 148,6.2,3.4,5.4,2.3,Iris-virginica
151 | 149,5.9,3.0,5.1,1.8,Iris-virginica
152 |
--------------------------------------------------------------------------------
/Uebung 4/04-reasoning.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# 4. Schließen unter Unsicherheit\n",
8 | "## 4.1. Satz von Bayes\n",
9 | "\n",
10 | "Bob möchte gerne wissen, ob es regnet. Dazu schaut er aus dem Fenster, ob die Straße nass ist. Wenn es tatsächlich regnet, ist die Straße mit einer Wahrscheinlichkeit von 95 % nass (in 5 % der Fälle regnet es noch nicht lange genug, damit die Straße für Bob nass aussieht). Wenn es nicht regnet, ist die Straße mit einer Wahrscheinlichkeit von 25 % nass (weil der Nachbar von Bob den Rasensprenger laufen lässt, der auch die Straße trifft). Darüber hinaus weiß Bob, dass es an 40 % aller Tage regnet. Benutzen Sie für die folgenden Aufgaben die folgende Notation:\n",
11 | "\n",
12 | "* $r$: Es regnet.\n",
13 | "* $\\bar{r}$: Es regnet nicht.\n",
14 | "* $n$: Die Straße ist nass.\n",
15 | "\n",
16 | "Berechnen Sie die folgenden Wahrscheinlichkeiten:\n",
17 | "* $p(r) = $\n",
18 | "* $p(\\bar{r}) = $\n",
19 | "* $p(n|r) = $\n",
20 | "* $p(n|\\bar{r}) = $\n",
21 | "* $p(r|n) = $"
22 | ]
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "metadata": {
27 | "tags": []
28 | },
29 | "source": [
30 | "## 4.2. Hidden-Markov-Modelle\n",
31 | "Für eine Smartwatch soll ein System entwickelt werden, das automatisch erkennt, ob der\n",
32 | "Träger gerade schläft. Die Smartwatch enthält einen Beschleunigungssensor, der entwe-\n",
33 | "der den Wert wenig Bewegung“ oder den Wert viel Bewegung“ zurückliefert. Wenn der\n",
34 | "Träger schläft, ist die Wahrscheinlichkeit für viel Bewegung“ 5 % und die Wahrscheinlichkeit für wenig Bewegung“ 95 %. Wenn der Träger wach ist, ist die Wahrscheinlichkeit\n",
35 | "für viel Bewegung“ 60 % und die Wahrscheinlichkeit für wenig Bewegung“ 40 %. Wenn\n",
36 | "der Träger schläft, ist die Wahrscheinlichkeit, dass er im nächsten Zeitschritt wach ist,\n",
37 | "30 %. Wenn der Träger wach ist, ist die Wahrscheinlichkeit, dass er im nächsten Schritt\n",
38 | "schläft, 20 %. Zu Anfang schläft der Träger mit einer Wahrscheinlichkeit von 50 %.\n",
39 | "\n",
40 | "1. Spezifizieren Sie diesen Prozess als HMM, wobei der Zustand beschreibt, ob die Person schläft oder wach ist. Notieren Sie die Initialzustand und das Beobachtungsmodell. \n",
41 | "\n",
42 | "2. Berechnen Sie, ausgehend von der initialen Wahrscheinlichkeitsverteilung über den Zuständen, ... \n",
43 | " a) die Vorhersage, d.h., Wahrscheinlichkeitsverteilung allein auf Basis des Transitionsmodelles! \n",
44 | "\n",
45 | " b) die Korrektur nach der Beobachtung wenig Bewegung“! \n"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {},
51 | "source": [
52 | "## 4.3. Implementierung\n",
53 | "\n",
54 | "### Aufgabe 1 \n",
55 | "Implementieren Sie zunächst für das oben beschriebene HMM das die Modelle für Transition und Observation, wie den Initalzustand des Systems! "
56 | ]
57 | },
58 | {
59 | "cell_type": "code",
60 | "execution_count": 1,
61 | "metadata": {
62 | "ExecuteTime": {
63 | "end_time": "2023-06-30T12:08:16.955975Z",
64 | "start_time": "2023-06-30T12:08:16.886967Z"
65 | },
66 | "tags": []
67 | },
68 | "outputs": [],
69 | "source": [
70 | "import numpy as np"
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": 2,
76 | "metadata": {
77 | "ExecuteTime": {
78 | "end_time": "2023-06-30T12:11:04.708235Z",
79 | "start_time": "2023-06-30T12:11:04.686898Z"
80 | }
81 | },
82 | "outputs": [],
83 | "source": [
84 | "#transition model\n",
85 | "T = \"Implement me!\"\n",
86 | "#prior\n",
87 | "s0 = \"Implement me!\"\n",
88 | "\n",
89 | "#obs model\n",
90 | "O = \"Implement me!\""
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "metadata": {},
96 | "source": [
97 | "### Aufgabe 2\n",
98 | "Implementieren Sie eine Funktion `predict(s,T)` die als Parameter eine Prior-Verteilung $p(x_t | y_{1:t})$ als Vektor $s$ und das Transitionsmodell als Matrix `A` bekommt und als Ausgabe die Verteilung $p(x_{t+1} | y_{1:t})$ liefert."
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": 3,
104 | "metadata": {
105 | "ExecuteTime": {
106 | "end_time": "2023-06-30T12:35:47.771412Z",
107 | "start_time": "2023-06-30T12:35:47.754756Z"
108 | }
109 | },
110 | "outputs": [],
111 | "source": [
112 | "def predict(s, T):\n",
113 | " return \"Implement me!\""
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "### Aufgabe 3\n",
121 | "Implementieren Sie eine Funktion `update(s,O,y)` die als Parameter eine Verteilung $p(x_{t+1} | y_{1:t})$ als Vektor $s$, ein Observationsmodell als Matrix `O` und eine Beobachtung $y_{t+1}$ als Integer `y` bekommt und als Ausgabe $p(x_{t+1} | y_{1:t+1})$ liefert."
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": 4,
127 | "metadata": {
128 | "ExecuteTime": {
129 | "end_time": "2023-06-30T12:35:49.078538Z",
130 | "start_time": "2023-06-30T12:35:49.063814Z"
131 | }
132 | },
133 | "outputs": [],
134 | "source": [
135 | "def update(s, O, y):\n",
136 | " return \"Implement me!\""
137 | ]
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {},
142 | "source": [
143 | "### Aufgabe 4\n",
144 | "Implementieren Sie eine Funktion `filter(s0,Y,T,O)` die als Parameter eine Prior-Verteilung $p(x_0)$ als Vektor `s0`, ein Transitions- und Beobachtungsmodell als Matrizen `T` und `O` und eine Sequenz von Beobachtungen $y_{1:T}$ als Vektor `yy` bekommt und für jedes $t = 1,...,T$ die Verteilung $p(x_t | y_{1:t})$ als Vektor berechnet und als Aufgabe somit eine $T \\times 2$-Matrix liefert."
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": 5,
150 | "metadata": {
151 | "ExecuteTime": {
152 | "end_time": "2023-06-30T12:35:50.991153Z",
153 | "start_time": "2023-06-30T12:35:50.974017Z"
154 | },
155 | "collapsed": false,
156 | "jupyter": {
157 | "outputs_hidden": false
158 | }
159 | },
160 | "outputs": [],
161 | "source": [
162 | "def filter(s0, O, T, yy):\n",
163 | " return \"Implement me!\""
164 | ]
165 | },
166 | {
167 | "cell_type": "markdown",
168 | "metadata": {},
169 | "source": [
170 | "Testen Sie nun ihre Implementierung mit dem untenstehenden Code."
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": 6,
176 | "metadata": {
177 | "ExecuteTime": {
178 | "end_time": "2023-06-30T12:37:11.902249Z",
179 | "start_time": "2023-06-30T12:37:11.880352Z"
180 | },
181 | "collapsed": false,
182 | "jupyter": {
183 | "outputs_hidden": false
184 | }
185 | },
186 | "outputs": [
187 | {
188 | "data": {
189 | "text/plain": [
190 | "[array([[0.5],\n",
191 | " [0.5]]),\n",
192 | " array([[0.33976834],\n",
193 | " [0.66023166]]),\n",
194 | " array([[0.2717807],\n",
195 | " [0.7282193]]),\n",
196 | " array([[0.90265233],\n",
197 | " [0.09734767]])]"
198 | ]
199 | },
200 | "execution_count": 6,
201 | "metadata": {},
202 | "output_type": "execute_result"
203 | }
204 | ],
205 | "source": [
206 | "yy = [\"W\",\"W\",\"V\"]\n",
207 | "ss = filter(s0,O,T,yy)\n",
208 | "ss"
209 | ]
210 | },
211 | {
212 | "cell_type": "code",
213 | "execution_count": null,
214 | "metadata": {
215 | "collapsed": false,
216 | "jupyter": {
217 | "outputs_hidden": false
218 | }
219 | },
220 | "outputs": [],
221 | "source": []
222 | }
223 | ],
224 | "metadata": {
225 | "kernelspec": {
226 | "display_name": "Python 3 (ipykernel)",
227 | "language": "python",
228 | "name": "python3"
229 | },
230 | "language_info": {
231 | "codemirror_mode": {
232 | "name": "ipython",
233 | "version": 3
234 | },
235 | "file_extension": ".py",
236 | "mimetype": "text/x-python",
237 | "name": "python",
238 | "nbconvert_exporter": "python",
239 | "pygments_lexer": "ipython3",
240 | "version": "3.11.4"
241 | }
242 | },
243 | "nbformat": 4,
244 | "nbformat_minor": 4
245 | }
246 |
--------------------------------------------------------------------------------
/Uebung 5/05-ML.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "38ea447f-f229-4a64-908d-1e632e4c28dc",
6 | "metadata": {
7 | "tags": []
8 | },
9 | "source": [
10 | "# 5. Maschinelles Lernen\n",
11 | "Heute werden wir uns mit dem Thema \"Maschinelles Lernen\" beschäftigen. Dazu schauen wir uns zunächst kurz an, welche Datenstruktur wir in Python verwenden können, um unsere Daten zunächst zu explorieren und vorzubereiten. \n",
12 | "\n",
13 | "Anschließend schauen wir uns ein einfaches Klassifikationsproblem an und probieren verschiedene Klassifikationsalgorithmen aus."
14 | ]
15 | },
16 | {
17 | "cell_type": "markdown",
18 | "id": "e14f30d8-825f-44fe-be84-770d43ec0b92",
19 | "metadata": {},
20 | "source": [
21 | "## 5.1. Pandas\n",
22 | "\n",
23 | "Ein weit verbreitetes Python-Paket für Datenmanagement und -analyse ist `pandas`. Die grundlegende Datenstruktur die dieses Paket bereitstellt ist das Data Frame. Ein Data Frame ist eine Tabelle, die im Prinzip so verwendet werden kann wie eine Tabelle in einer relationalen Datenbank. So können z.B. Zeilen oder Spalten (oder beides) selektiert werden."
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": null,
29 | "id": "0ac6488c-ec63-4957-81b1-b0a4ba205259",
30 | "metadata": {
31 | "tags": []
32 | },
33 | "outputs": [],
34 | "source": [
35 | "import pandas as pd\n",
36 | "\n",
37 | "data = {'Name': ['Alice', 'Bob', 'Charlie', 'Dave', 'Eve'],\n",
38 | " 'Alter': [25, 30, 35, 40, 45],\n",
39 | " 'Stadt': ['Berlin', 'München', 'Hamburg', 'Frankfurt', 'Köln']}\n",
40 | "df = pd.DataFrame(data)\n",
41 | "\n",
42 | "# show complete dataframe\n",
43 | "df"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "id": "f95cff74-b3a3-479a-af29-78c8abdd6be3",
49 | "metadata": {},
50 | "source": [
51 | "Wir können uns auch nur die ersten oder letzten Zeilen des DataFrames anschauen."
52 | ]
53 | },
54 | {
55 | "cell_type": "code",
56 | "execution_count": null,
57 | "id": "ce68cd3f-4915-4cab-8fd7-99decdb5567b",
58 | "metadata": {
59 | "tags": []
60 | },
61 | "outputs": [],
62 | "source": [
63 | "print(f\"Die ersten zwei Zeilen: \\n {df.head(2)}\\n\")\n",
64 | "print(f\"Die letzten zwei Zeilen: \\n {df.tail(2)}\\n\")"
65 | ]
66 | },
67 | {
68 | "cell_type": "markdown",
69 | "id": "9ac44525-a900-4fb6-a8d5-dea38f6ab0a5",
70 | "metadata": {},
71 | "source": [
72 | "Weitere Informationen über unser DataFrame können wir uns mit folgenden Methoden holen:"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": null,
78 | "id": "e6b8bae2-ded6-4ea6-89c4-6c6b86c444f0",
79 | "metadata": {
80 | "tags": []
81 | },
82 | "outputs": [],
83 | "source": [
84 | "# Anzeigen der Spaltennamen\n",
85 | "print(\"\\nSpaltennamen:\")\n",
86 | "print(df.columns)\n",
87 | "\n",
88 | "# Anzeigen der Informationen zum DataFrame\n",
89 | "print(\"\\nInfo zum DataFrame:\")\n",
90 | "print(df.info())"
91 | ]
92 | },
93 | {
94 | "cell_type": "markdown",
95 | "id": "a2995d9f-cbb4-40a4-9c56-d4f6be84c735",
96 | "metadata": {},
97 | "source": [
98 | "### Zeilen und Spalten auswählen\n",
99 | "\n",
100 | "Mit pandas können einfach bestimmte Zeilen und Spalten aus dem Data Frame ausgewählt werden. Eine Option besteht darin, Spalten über ihren Namen auszuwählen."
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": null,
106 | "id": "7282e8ae-e038-47ee-ab02-6e9f8ad6ba7d",
107 | "metadata": {
108 | "tags": []
109 | },
110 | "outputs": [],
111 | "source": [
112 | "names = df.loc[:,\"Name\"]\n",
113 | "print(names)"
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "id": "44975173-d8b2-49e7-84ed-01062ae42807",
119 | "metadata": {},
120 | "source": [
121 | "Der `:` steht für \"Wähle alle Zeilen\". Wenn nur eine einzige Spalte gewählt wird, ist das Ergebnis vom Typ `Series`, ansonsten ist das Ergebnis wieder ein Data Frame. Spalten können auch über ihren Index ausgewählt werden:"
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": null,
127 | "id": "7bfccccb-c57e-4fe3-a9f6-04e6ebae13fb",
128 | "metadata": {
129 | "tags": []
130 | },
131 | "outputs": [],
132 | "source": [
133 | "mult_columns = df.iloc[:,1:3]\n",
134 | "mult_columns"
135 | ]
136 | },
137 | {
138 | "cell_type": "markdown",
139 | "id": "5f326750-cc8b-48f6-8e58-32957e23c854",
140 | "metadata": {},
141 | "source": [
142 | "Auf Zeilen kann auf die gleiche Art zugegrifen werden. Der folgende Ausdruck liefert beispielsweise die ersten 5 Zeilen:"
143 | ]
144 | },
145 | {
146 | "cell_type": "code",
147 | "execution_count": null,
148 | "id": "78a58750-f32e-4927-b786-ccb3bb58c0b6",
149 | "metadata": {
150 | "tags": []
151 | },
152 | "outputs": [],
153 | "source": [
154 | "df.iloc[0:4,:]"
155 | ]
156 | },
157 | {
158 | "cell_type": "code",
159 | "execution_count": null,
160 | "id": "9e0b6ddb-2573-46d9-bbd6-da23b86f1fef",
161 | "metadata": {
162 | "tags": []
163 | },
164 | "outputs": [],
165 | "source": [
166 | "df.loc[0:4,[\"Alter\", \"Stadt\"]]"
167 | ]
168 | },
169 | {
170 | "cell_type": "markdown",
171 | "id": "359f1e4d-aad1-4841-adfd-b49771b93a0d",
172 | "metadata": {},
173 | "source": [
174 | "Eine andere praktische Möglichkeit besteht darin, Zeilen oder Spalten über Bool'sche Ausdrücke auszuwählen. Der folgende Ausdruck liefert z.B. alle Zeilen, bei denen der Wert von `Alter` kleiner als 36 ist."
175 | ]
176 | },
177 | {
178 | "cell_type": "code",
179 | "execution_count": null,
180 | "id": "dd583ebe-ac41-4b30-b8fd-a23a667a5e34",
181 | "metadata": {
182 | "tags": []
183 | },
184 | "outputs": [],
185 | "source": [
186 | "df[df['Alter'] < 36]"
187 | ]
188 | },
189 | {
190 | "cell_type": "markdown",
191 | "id": "4bd15c86-3831-4dd9-b79a-9d827e191a6d",
192 | "metadata": {},
193 | "source": [
194 | "### Werte Einfügen\n",
195 | "\n",
196 | "Das Einfügen von Werten in ein Data Frame funktioniert genau so. Der folgende Ausdruck setzt alle Werde der Spalte `Sensor_T8_Acceleration_Y`, die kleiner als 0 sind, auf den Wert 0."
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "id": "25088c51-bce3-41d8-bed6-f4fd9e199bff",
203 | "metadata": {},
204 | "outputs": [],
205 | "source": [
206 | "# Hinzufügen einer neuen Spalte\n",
207 | "df['Beruf'] = ['Ingenieur', 'Lehrer', 'Arzt', 'Anwalt', 'Designer']\n",
208 | "print(\"DataFrame nach Hinzufügen der Spalte 'Beruf':\")\n",
209 | "print(df)\n",
210 | "df.loc[len(df)] = ['Klaus', 12, 'Rostock', 'Informatiker']\n",
211 | "df"
212 | ]
213 | },
214 | {
215 | "cell_type": "markdown",
216 | "id": "522c5d8a-01ef-49ad-8922-b68a3514504a",
217 | "metadata": {},
218 | "source": [
219 | "### Speichern und Laden von DataFrames\n",
220 | "Wir können DataFrames auch in CSV-Dateien speichern oder Daten aus CSV-Dateien in ein DataFrame importieren: "
221 | ]
222 | },
223 | {
224 | "cell_type": "code",
225 | "execution_count": null,
226 | "id": "7a6fddf0-ab82-4e62-9046-ddb76b9b501d",
227 | "metadata": {
228 | "tags": []
229 | },
230 | "outputs": [],
231 | "source": [
232 | "# Speichern des DataFrames in einer CSV-Datei\n",
233 | "df.to_csv('daten.csv', index=False)\n",
234 | "print(\"\\nDataFrame wurde in 'daten.csv' gespeichert.\")\n",
235 | "\n",
236 | "# Speichern des DataFrames in einer CSV-Datei\n",
237 | "df = pd.read_csv('iris.csv', index_col=0)\n",
238 | "print(f\"\\nEin neues DataFrame wurde aus der Datei 'iris.csv' geladen: \\n {df}\")"
239 | ]
240 | },
241 | {
242 | "cell_type": "markdown",
243 | "id": "f4333994-d1ac-4d69-a796-c0a5f5b9446b",
244 | "metadata": {},
245 | "source": [
246 | "## Maschinelles Lernen\n",
247 | "Für das Maschinelle Lernen in Python stehen Ihnen unterschiedliche Packages zur Verfügung. Eines dieser Packages ist scikit-learn, welches fertige Implementierung von verschiedenen ML-Verfahren anbietet. Im weiteren Verlauf der Übung werden wir zunächst sehen aus welchen Schritten eine klassische ML-Pipeline besteht und wie diese mithilfe von Pandas und scikit-learn umgesetzt werden kann. \n",
248 | "\n",
249 | "Zunächst beginnen wir damit die benötigten Bibliotheken zu importieren und unseren Datensatz aus einer CSV-Date zu laden: \n",
250 | "\n",
251 | "Aufgabe: Importieren Sie die Daten aus der Datei `iris.csv` in eine DataFrame. Schauen sie sich anschließend die ersten paar Zeilen des DataFrame an und lassen Sie sich eine statistische Zusammenfassung aller Spalten generieren. \n",
252 | "\n",
253 | "Zusatz: Überprüfen Sie das DataFrame auf fehlende Werte. Wie können Sie gegebenenfalls Null-Werte ersetzen? "
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": null,
259 | "id": "fb2e3ba2-b864-4cdf-8d1a-adc395680ddc",
260 | "metadata": {
261 | "tags": []
262 | },
263 | "outputs": [],
264 | "source": [
265 | "# Importieren der erforderlichen Bibliotheken\n",
266 | "from sklearn.model_selection import train_test_split\n",
267 | "from sklearn.tree import DecisionTreeClassifier\n",
268 | "from sklearn.ensemble import RandomForestClassifier\n",
269 | "from sklearn.metrics import classification_report, confusion_matrix\n",
270 | "\n",
271 | "# 1. Importieren von Daten aus einer CSV-Datei\n",
272 | "data = \"Implement me!\"\n",
273 | "\n",
274 | "# 2. Datenexploration\n",
275 | "print(\"Erste paar Zeilen des DataFrames:\")\n",
276 | "print(\"Implement me!\")\n",
277 | "\n",
278 | "print(\"\\nStatistische Zusammenfassung:\")\n",
279 | "print(\"Implement me!\")\n",
280 | "\n",
281 | "print(\"\\nAnzahl der fehlenden Werte pro Spalte:\")\n",
282 | "print(\"Implement me!\")"
283 | ]
284 | },
285 | {
286 | "cell_type": "markdown",
287 | "id": "ab272d45-0527-4084-ae35-cfae7e6f0538",
288 | "metadata": {},
289 | "source": [
290 | "Nachdem wir die ersten beiden Schritte (Importieren der Daten, Exploration der Daten) erledigt haben, müssen wir die Daten für das Training des Klassifikators vorbereiten. \n",
291 | "\n",
292 | "Aufgabe: Was müssen wir nun mit den Daten machen, um sie anschließend für das Training eines Klassifikators verwenden zu können?"
293 | ]
294 | },
295 | {
296 | "cell_type": "code",
297 | "execution_count": null,
298 | "id": "0a40f024-f046-43a8-922b-afc63e236cec",
299 | "metadata": {
300 | "tags": []
301 | },
302 | "outputs": [],
303 | "source": [
304 | "# 3. Datenvorbereitung\n",
305 | "# Aufteilen der Daten in Features und Zielvariable\n",
306 | "X = \"Implement me!\"\n",
307 | "y = \"Implement me!\""
308 | ]
309 | },
310 | {
311 | "cell_type": "markdown",
312 | "id": "6b33e0f3-492b-4e5b-a501-395632240f19",
313 | "metadata": {},
314 | "source": [
315 | "Nachdem wir nun auch den dritten Schritt, die Datenvorbereitung, erleidgt haben, können schlussendlich unseren Klassifikator trainieren. Wir verwenden hier zunächst den `DecisionTreeClassifier`. Nachdem diesen trainiert haben, lassen wir uns eine Zusammenfassung über die Qualität unseres Klassifikators ausgeben."
316 | ]
317 | },
318 | {
319 | "cell_type": "code",
320 | "execution_count": null,
321 | "id": "2b9bf049-e64f-43be-a7b1-11c59707018c",
322 | "metadata": {},
323 | "outputs": [],
324 | "source": [
325 | "# 4. Training und Evaluation eines Klassifikators\n",
326 | "# Aufteilen der Daten in Trainings- und Testdaten\n",
327 | "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
328 | "# Initialisieren des Klassifikators\n",
329 | "classifier = RandomForestClassifier()\n",
330 | "\n",
331 | "# Trainieren des Klassifikators\n",
332 | "classifier.fit(X_train, y_train)\n",
333 | "\n",
334 | "# Vorhersagen für die Testdaten\n",
335 | "y_pred = classifier.predict(X_test)\n",
336 | "\n",
337 | "# Auswertung der Vorhersagen\n",
338 | "cm = confusion_matrix(y_test, y_pred)\n",
339 | "report = classification_report(y_test, y_pred)\n",
340 | "print(f'Confusion matrix: \\n {cm}')\n",
341 | "print(f'Classification report: \\n {report}')"
342 | ]
343 | },
344 | {
345 | "cell_type": "markdown",
346 | "id": "c67d8b00-6b3d-45fe-be61-745b2afb5c05",
347 | "metadata": {},
348 | "source": [
349 | "## Titanic-Challenge\n",
350 | "Programmieren Sie nun einen Klassifikator für die Titanic-Challenge. Dabei soll ihr Klassifikator vorhersagen können, ob ein Passagier überlebt oder nicht. Verwenden Sie dazu den gegebenen Titanic-Datensatz und führen Sie alle Schritte durch, die Sie in dieser Übung kennengelernt haben. Auf welche Accuracy kommen Sie am Ende? "
351 | ]
352 | },
353 | {
354 | "cell_type": "code",
355 | "execution_count": null,
356 | "id": "a32173c2-a921-43d4-be4c-6deb31fe55e8",
357 | "metadata": {
358 | "tags": []
359 | },
360 | "outputs": [],
361 | "source": [
362 | "# Importieren der erforderlichen Bibliotheken\n",
363 | "import pandas as pd\n",
364 | "import numpy as np\n",
365 | "from sklearn.model_selection import train_test_split\n",
366 | "from sklearn.ensemble import RandomForestClassifier\n",
367 | "from sklearn.linear_model import LogisticRegression\n",
368 | "from sklearn.metrics import classification_report, confusion_matrix\n",
369 | "from sklearn.preprocessing import StandardScaler, MinMaxScaler\n",
370 | "import ssl\n",
371 | "\n",
372 | "# SSL-Verifizierung deaktivieren\n",
373 | "ssl._create_default_https_context = ssl._create_unverified_context\n",
374 | "\n",
375 | "# 1. Importieren der Daten\n",
376 | "url = 'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv'\n",
377 | "data = pd.read_csv(url)\n",
378 | "\n",
379 | "# 2. Datenexploration\n",
380 | "\n",
381 | "print(\"\\nStatistische Zusammenfassung:\")\n",
382 | "print(\"Implement me!\")\n",
383 | "\n",
384 | "print(\"\\nAnzahl der fehlenden Werte pro Spalte:\")\n",
385 | "print(\"Implement me!\")\n",
386 | "\n",
387 | "# 3. Datenvorbereitung\n",
388 | "data = \"Implement me!\"\n",
389 | "\n",
390 | "# 4. Training und Evaluation eines Klassifikators\n",
391 | "# Initialisieren des Klassifikators\n",
392 | "classifier = \"Implement me!\"\n",
393 | "\n",
394 | "# Trainieren des Klassifikators\n",
395 | "\"Implement me!\"\n",
396 | "\n",
397 | "# Vorhersagen für die Testdaten\n",
398 | "y_pred = \"Implement me!\"\n",
399 | "\n",
400 | "# Auswertung der Vorhersagen\n",
401 | "cm = confusion_matrix(y_test, y_pred)\n",
402 | "report = classification_report(y_test, y_pred)\n",
403 | "print(f'Confusion matrix: \\n {cm}')\n",
404 | "print(f'Classification report: \\n {report}')"
405 | ]
406 | }
407 | ],
408 | "metadata": {
409 | "kernelspec": {
410 | "display_name": "Lehre-oZkq39sg",
411 | "language": "python",
412 | "name": "python3"
413 | },
414 | "language_info": {
415 | "codemirror_mode": {
416 | "name": "ipython",
417 | "version": 3
418 | },
419 | "file_extension": ".py",
420 | "mimetype": "text/x-python",
421 | "name": "python",
422 | "nbconvert_exporter": "python",
423 | "pygments_lexer": "ipython3",
424 | "version": "3.11.4"
425 | }
426 | },
427 | "nbformat": 4,
428 | "nbformat_minor": 5
429 | }
430 |
--------------------------------------------------------------------------------
/Uebung 1/01-agents.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# 1. Intelligente Agenten\n",
8 | "Beantworten Sie die folgenden Fragen!\n",
9 | "## Der Turing-Test\n",
10 | "1. Wie funktioniert der Turing-Test?\n",
11 | "2. Was braucht eine Maschine um den Test zu bestehen?\n",
12 | "3. Was ist der totale Turing-Test?\n",
13 | "4. Was braucht eine Maschine um den totalen Turing-Test zu bestehen?\n",
14 | "5. Welche Probleme existieren beim Turing-Test?"
15 | ]
16 | },
17 | {
18 | "cell_type": "markdown",
19 | "metadata": {},
20 | "source": [
21 | "## Agenten\n",
22 | "1. Was ist ein Agent? Aus welchen Bestandteilen besteht ein Agent?\n",
23 | "2. Welche Arten von Agenten kennen Sie? Wie zeichnen Sich die einzelnen Agententypen aus?\n",
24 | "3. Durch welche Eigenschaften zeichnet sich eine Umgebung aus in der sich ein Agent bewegt?:
"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {},
30 | "source": [
31 | "## Der Staubsauger als Agent\n",
32 | "Wir werden heute einen Staubsauger-Agenten und die dazugehörige Umgebung bzw. \"Welt\" programmieren."
33 | ]
34 | },
35 | {
36 | "cell_type": "code",
37 | "execution_count": null,
38 | "metadata": {
39 | "tags": []
40 | },
41 | "outputs": [],
42 | "source": [
43 | "import random"
44 | ]
45 | },
46 | {
47 | "cell_type": "markdown",
48 | "metadata": {},
49 | "source": [
50 | "Zunächst definieren wir uns eine Klasse \"Environment\". Diese Klasse repräsentiert unsere Welt in der sich der Agent bewegen soll."
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "metadata": {
57 | "tags": []
58 | },
59 | "outputs": [],
60 | "source": [
61 | "class InvalidActionError(Exception):\n",
62 | " \"\"\"Is triggered, if the agent wants to execute an ivalid action.\"\"\"\n",
63 | " pass\n",
64 | "\n",
65 | "class Environment:\n",
66 | " \"\"\"Class representing an Environment. Other environment classes can\n",
67 | " inherit from this. They typically need to implement:\n",
68 | " percept: Define the percept that an agent sees.\n",
69 | " execute_action: Define the effects of executing an action.\n",
70 | " Also update the agent.performance slot.\n",
71 | " The environment keeps a dict of .loc_status which includes locations and their respective status. \n",
72 | " There is also a list of .agents.\n",
73 | " \"\"\"\n",
74 | "\n",
75 | " def __init__(self):\n",
76 | " \n",
77 | " self.loc_status = {(0, 0): random.choice(['Clean', 'Dirty']),\n",
78 | " (0, 1): random.choice(['Clean', 'Dirty']),\n",
79 | " (1, 0): random.choice(['Clean', 'Dirty']),\n",
80 | " (1, 1): random.choice(['Clean', 'Dirty'])}\n",
81 | " self.agents = []\n",
82 | " self.time = 0\n",
83 | "\n",
84 | "\n",
85 | " def percept(self, agent):\n",
86 | " \"\"\"Returns the agent's location, and the location status (Dirty/Clean).\"\"\"\n",
87 | " return (agent.location, self.loc_status[agent.location])\n",
88 | "\n",
89 | " def execute_action(self, agent, action):\n",
90 | " \"\"\"Change agent's location and/or location's status\"\"\"\n",
91 | " former_location = agent.location\n",
92 | " if action == 'move_left' and agent.location[1] > 0:\n",
93 | " agent.location = (agent.location[0], agent.location[1]-1)\n",
94 | " print(f\"Moving left: {former_location} -> {agent.location}\")\n",
95 | " print(\"World state: \", self.loc_status)\n",
96 | " elif action == 'move_right' and agent.location[1] < 1:\n",
97 | " agent.location = (agent.location[0], agent.location[1]+1)\n",
98 | " print(f\"Moving right: {former_location} -> {agent.location}\")\n",
99 | " print(\"World state: \", self.loc_status)\n",
100 | " elif action == 'move_down' and agent.location[0] < 1:\n",
101 | " agent.location = (agent.location[0]+1, agent.location[1])\n",
102 | " print(f\"Moving down: {former_location} -> {agent.location}\")\n",
103 | " print(\"World state: \", self.loc_status)\n",
104 | " elif action == 'move_up' and agent.location[0] > 0:\n",
105 | " agent.location = (agent.location[0]-1, agent.location[1])\n",
106 | " print(f\"Moving up: {former_location} -> {agent.location}\")\n",
107 | " print(\"World state: \", self.loc_status)\n",
108 | " elif action == 'clean':\n",
109 | " self.loc_status[agent.location] = 'Clean'\n",
110 | " print(\"Cleaning: \", agent.location)\n",
111 | " print(\"World state: \", self.loc_status)\n",
112 | " elif action == 'do_nothing':\n",
113 | " print(\"Doing nothing at location:\", agent.location)\n",
114 | " print(\"World state: \", self.loc_status)\n",
115 | " else:\n",
116 | " error_message = f\"Invalid action '{action}' at position {former_location}!\"\n",
117 | " raise InvalidActionError(error_message)\n",
118 | " \n",
119 | " \n",
120 | "\n",
121 | " def default_location(self, thing):\n",
122 | " \"\"\"Agents start in either location at random.\"\"\"\n",
123 | " return random.choice([(0,0), (0,1), (1,0), (1,1)])\n",
124 | "\n",
125 | " def exogenous_change(self):\n",
126 | " \"\"\"If there is spontaneous change in the world, override this.\"\"\"\n",
127 | " pass\n",
128 | "\n",
129 | " def step(self):\n",
130 | " \"\"\"Run the environment for one time step. If the\n",
131 | " actions and exogenous changes are independent, this method will\n",
132 | " do. If there are interactions between them, you'll need to\n",
133 | " override this method.\"\"\"\n",
134 | " actions = []\n",
135 | " \n",
136 | " for agent in self.agents:\n",
137 | " actions.append(agent.program(self.percept(agent)))\n",
138 | " for (agent, action) in zip(self.agents, actions):\n",
139 | " self.execute_action(agent, action)\n",
140 | " self.exogenous_change()\n",
141 | "\n",
142 | " def run(self, steps=10):\n",
143 | " \"\"\"Run the Environment for given number of time steps.\"\"\"\n",
144 | " print(\"Initial world state: \", self.loc_status)\n",
145 | " for step in range(steps):\n",
146 | " self.time += 1\n",
147 | " self.step()\n",
148 | " if all(value == \"Clean\" for value in self.loc_status.values()):\n",
149 | " break\n",
150 | "\n",
151 | " def add_agent(self, agent, location=None):\n",
152 | " \"\"\"Add a thing to the environment, setting its location. For\n",
153 | " convenience, if thing is an agent program we make a new agent\n",
154 | " for it. (Shouldn't need to override this.)\"\"\"\n",
155 | " if agent in self.agents:\n",
156 | " print(\"Can't add the same agent twice\")\n",
157 | " else:\n",
158 | " agent.location = location if location is not None else self.default_location(agent)\n",
159 | " self.agents.append(agent)\n",
160 | "\n",
161 | " def delete_agent(self, agent):\n",
162 | " \"\"\"Remove agent from the environment.\"\"\"\n",
163 | " try:\n",
164 | " self.agents.remove(agent)\n",
165 | " except ValueError as e:\n",
166 | " print(e)\n",
167 | " print(\" in Environment delete_agent\")\n",
168 | " print(\" Agent to be removed: {} at {}\".format(agent, agent.location))\n",
169 | " print(\" from list: {}\".format([(agent, agent.location) for agent in self.agents]))"
170 | ]
171 | },
172 | {
173 | "cell_type": "markdown",
174 | "metadata": {},
175 | "source": [
176 | "Dann benötigen wir noch eine Klasse für unsere Agenten. Da wir im Laufe der Übung unterschiedliche Agenten implementieren möchten verwenden wir zunächst eine sogenannte \"abstrakte\" Klasse `TraceAgent`, von der unsere späteren konkreten Agent-Klassen erben können."
177 | ]
178 | },
179 | {
180 | "cell_type": "code",
181 | "execution_count": null,
182 | "metadata": {
183 | "tags": []
184 | },
185 | "outputs": [],
186 | "source": [
187 | "class TraceAgent:\n",
188 | " \"\"\"An abstract class of an agent. Concrete agent classes wil inherit from this class and have to provide (at least) a program function.\n",
189 | " Optionally you can also provide an __init__ function if the agent should have internal states.\"\"\"\n",
190 | " def __init__(self):\n",
191 | " self.loc_status = None\n",
192 | " self.location = None\n",
193 | " \n",
194 | " def programm(self):\n",
195 | " pass"
196 | ]
197 | },
198 | {
199 | "cell_type": "markdown",
200 | "metadata": {},
201 | "source": [
202 | "Hier sehen wir nun eine mögliche Implementierung einer `SimpleAgent`-Klasse. Dabei erbt diese Klasse alle Methoden und Attribute von der abstrakten Klasse `TraceAgent` und überschreibt diese gegebenenfalls mit ihrer eigenen Logik. "
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": null,
208 | "metadata": {
209 | "tags": []
210 | },
211 | "outputs": [],
212 | "source": [
213 | "class SimpleAgent(TraceAgent):\n",
214 | " def program(self, perception):\n",
215 | " self.location, loc_status = perception\n",
216 | " if loc_status == \"Clean\":\n",
217 | " action = \"do_nothing\"\n",
218 | " else:\n",
219 | " action = \"clean\"\n",
220 | " return action"
221 | ]
222 | },
223 | {
224 | "cell_type": "markdown",
225 | "metadata": {},
226 | "source": [
227 | "Nun könnne wir uns mit folgender Zelle eine neue Welt erstellen und unseren `SimpleAgent`zu dieser Welt hinzufügen. Anschließend Simulieren wir 10 Zeitschritte in dieser Welt."
228 | ]
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": null,
233 | "metadata": {
234 | "tags": []
235 | },
236 | "outputs": [],
237 | "source": [
238 | "e = Environment()\n",
239 | "e.add_agent(SimpleAgent())\n",
240 | "e.run(10)"
241 | ]
242 | },
243 | {
244 | "cell_type": "markdown",
245 | "metadata": {},
246 | "source": [
247 | "## Aufgabe 1\n",
248 | "Implementieren Sie die Klasse ReflexAgent als einfachen Reflex-Agenten. Das Verhalten können sie dabei selbst festlegen. Der Agent soll dabei in unserer Welt \"Environment\" funktionieren. Beachten Sie diesen Umstand bei der Festlegung möglicher Aktionen, die der Agent in der genannten Welt ausführen soll. Die Liste der Aktionen ist folgende: \"move_left\", \"move_right\", \"move_up\", \"move_down\", \"do_nothing\" und \"clean\"."
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": null,
254 | "metadata": {
255 | "tags": []
256 | },
257 | "outputs": [],
258 | "source": [
259 | "class ReflexAgent(TraceAgent):\n",
260 | " def program(self, perception):\n",
261 | " self.location, loc_status = perception\n",
262 | " return \"Implement me!\"\n",
263 | "\n",
264 | "e1 = Environment()\n",
265 | "a1 = ReflexAgent()\n",
266 | "e1.add_agent(a1)\n",
267 | "e1.run()"
268 | ]
269 | },
270 | {
271 | "cell_type": "markdown",
272 | "metadata": {},
273 | "source": [
274 | "## Aufgabe 2\n",
275 | "Implementieren Sie die Klasse \"ModelBasedAgent\" als modellbasierten Agenten. Auch dieser Agent soll in der \"Environment\" funktionieren. "
276 | ]
277 | },
278 | {
279 | "cell_type": "code",
280 | "execution_count": null,
281 | "metadata": {
282 | "tags": []
283 | },
284 | "outputs": [],
285 | "source": [
286 | "class ModelBasedAgent(TraceAgent):\n",
287 | " def __init__(self):\n",
288 | " self.loc_status = {(0, 0): None,\n",
289 | " (0, 1): None,\n",
290 | " (1, 0): None,\n",
291 | " (1, 1): None}\n",
292 | " self.location = None\n",
293 | " def program(self, perception):\n",
294 | " location, loc_status = perception\n",
295 | " self.location = location\n",
296 | " self.loc_status[self.location] = loc_status\n",
297 | " \n",
298 | " return \"Implement my logic!\"\n",
299 | "\n",
300 | "e2 = Environment()\n",
301 | "a2 = ModelBasedAgent()\n",
302 | "e2.add_agent(a2)\n",
303 | "e2.run()"
304 | ]
305 | },
306 | {
307 | "cell_type": "markdown",
308 | "metadata": {},
309 | "source": [
310 | "## Aufgabe 3\n",
311 | "Erweitern Sie die Implementierung der Environment, sodass es beliebig viele, auf einem 2D-Gitter angeordnete Positionen gibt. Erweitern Sie auch die Implementierung der beiden Agenten entsprechend, sodass diese sinnvoll in der neuen Umgebung agieren können"
312 | ]
313 | },
314 | {
315 | "cell_type": "code",
316 | "execution_count": null,
317 | "metadata": {
318 | "tags": []
319 | },
320 | "outputs": [],
321 | "source": [
322 | "class ExtendedEnvironment(Environment):\n",
323 | "\n",
324 | " \"\"\"This environment has nxn locations. Each can be Dirty\n",
325 | " or Clean. The agent perceives its location and the location's\n",
326 | " status. This serves as an example of how to implement a simple\n",
327 | " Environment.\"\"\"\n",
328 | "\n",
329 | " def __init__(self, grid_size: int):\n",
330 | " super().__init__()\n",
331 | " \"Implement me!\"\n",
332 | "\n",
333 | " def execute_action(self, agent, action):\n",
334 | " \"\"\"Change agent's location and/or location's status\"\"\"\n",
335 | " \n",
336 | " \"Implement me!\""
337 | ]
338 | },
339 | {
340 | "cell_type": "code",
341 | "execution_count": null,
342 | "metadata": {
343 | "tags": []
344 | },
345 | "outputs": [],
346 | "source": [
347 | "class ExtendedModelBasedAgent(TraceAgent):\n",
348 | " def __init__(self, loc_status):\n",
349 | " self.loc_status = \"Implement me!\"\n",
350 | " self.location = None\n",
351 | " def program(self, perception):\n",
352 | " location, loc_status = perception\n",
353 | " self.location = location\n",
354 | " self.loc_status[self.location] = loc_status\n",
355 | " \n",
356 | " return \"Implement my logic!\"\n",
357 | "\n",
358 | "e4 = Environment()\n",
359 | "a4 = ExtendedModelBasedAgent(e4.loc_status)\n",
360 | "e4.add_agent(a4)\n",
361 | "e4.run()"
362 | ]
363 | },
364 | {
365 | "cell_type": "code",
366 | "execution_count": null,
367 | "metadata": {},
368 | "outputs": [],
369 | "source": []
370 | }
371 | ],
372 | "metadata": {
373 | "kernelspec": {
374 | "display_name": "Lehre-oZkq39sg",
375 | "language": "python",
376 | "name": "python3"
377 | },
378 | "language_info": {
379 | "codemirror_mode": {
380 | "name": "ipython",
381 | "version": 3
382 | },
383 | "file_extension": ".py",
384 | "mimetype": "text/x-python",
385 | "name": "python",
386 | "nbconvert_exporter": "python",
387 | "pygments_lexer": "ipython3",
388 | "version": "3.11.4"
389 | }
390 | },
391 | "nbformat": 4,
392 | "nbformat_minor": 4
393 | }
394 |
--------------------------------------------------------------------------------
/Uebung 0/00-pythonintro.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Einführung in Python \n",
8 | "\n",
9 | "Dieses Tutorial stützt sich stark auf [dieses Tutorial über Audiosignalverarbeitung](https://github.com/spatialaudio/selected-topics-in-audio-signal-processing-exercises).\n",
10 | "\n",
11 | "Für die Übungen werden wir die sehr beliebte Programmiersprache [Python](https://www.python.org) zusammen mit einigen externen Bibliotheken aus dem [Scientific Python Stack](http://scipy.org) verwenden.\n",
12 | "Für den Anfang können Sie auch einen Blick auf diese werfen:\n",
13 | "\n",
14 | "* [Python Einführung](http://nbviewer.ipython.org/github/mgeier/python-audio/blob/master/intro-python.ipynb) (reines Python, kein NumPy)\n",
15 | "\n",
16 | "* [Simple Signal Processing Example](http://nbviewer.ipython.org/github/mgeier/python-audio/blob/master/simple-signals.ipynb) (ziemlich ähnlich zu den Dingen auf dieser Seite)\n",
17 | "\n",
18 | "Beachten Sie, dass Python nicht die einzige Option für die Art von Aufgaben ist, die wir hier angehen werden.\n",
19 | "Wenn Sie sich für einige Alternativen interessieren, schauen Sie sich [Julia](http://julialang.org/), [R](http://www.r-project.org/), [Octave](http://octave.org/) oder [Scilab](http://www.scilab.org/) an.\n",
20 | "Alle genannten Anwendungen sind Open-Source-Software und es gibt natürlich noch mehr Alternativen (sowohl kostenlose als auch proprietäre).\n",
21 | "\n",
22 | "Die meisten Übungen in diesem Kurs (einschließlich derjenigen, die Sie gerade lesen) werden als [Jupyter (früher bekannt als IPython) notebooks](http://jupyter.org/) präsentiert.\n",
23 | "Sie können [online](http://nbviewer.jupyter.org/github/spatialaudio/communication-acoustics-exercises/blob/master/index.ipynb) angesehen werden, aber es ist viel sinnvoller, sie herunterzuladen und sie lokal mit [Jupyter](http://jupyter.org/) zu öffnen und zu erkunden.\n",
24 | "\n",
25 | "Anweisungen zur Installation finden Sie im Abschnitt [Getting Started](index.ipynb#Getting-Started) auf der Hauptseite.\n",
26 | "\n",
27 | "Um eine Vorstellung davon zu bekommen, worum es bei Jupyter geht, werfen Sie einen Blick auf diese [Jupyter-Einführung](http://nbviewer.jupyter.org/github/mgeier/python-audio/blob/master/intro-jupyter.ipynb)."
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {
33 | "tags": []
34 | },
35 | "source": [
36 | "## Was werden wir heute lernen?\n",
37 | "\n",
38 | "* Grundlagen von Python, Jupyter/IPython, NumPy, SciPy, matplotlib und einigen anderen externen Bibliotheken"
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {
44 | "tags": []
45 | },
46 | "source": [
47 | "## Notebook Cells\n",
48 | "\n",
49 | "Das Notebook besteht aus sogenannten \"Zellen\", die für normalen Text (siehe oben) oder für Python-Code (siehe unten) verwendet werden können.\n",
50 | "*Code-Zellen* können per Mausklick (oder mit den Pfeiltasten nach oben/unten und *Enter*) ausgewählt werden, der Code kann bearbeitet und dann durch Drücken von *Shift+Enter* oder durch Anklicken der Schaltfläche im oberen Teil der Seite ausgeführt werden.\n",
51 | "\n",
52 | "Seien Sie nicht schüchtern, probieren Sie es aus:"
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": null,
58 | "metadata": {},
59 | "outputs": [],
60 | "source": [
61 | "50 - 5 * 4 + 12\n",
62 | "a = 10"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {},
68 | "source": [
69 | "Codezellen können aus mehreren Zeilen bestehen (verwenden Sie *Enter* für Zeilenumbrüche).\n",
70 | "Wenn die Codezelle ausgeführt wird, werden alle Zeilen ausgeführt, aber nur der Wert der letzten Zeile wird angezeigt (es sei denn, es gibt keinen Wert anzuzeigen).\n",
71 | "\n",
72 | "Hier ist eine weitere Codezelle, mit der Sie spielen können:"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": null,
78 | "metadata": {},
79 | "outputs": [],
80 | "source": []
81 | },
82 | {
83 | "cell_type": "markdown",
84 | "metadata": {},
85 | "source": [
86 | "Neue Zellen können durch Drücken der Tasten *a* oder *b* (zum Einfügen *oberhalb* oder *unterhalb* der aktuellen Zelle) oder über das Menü eingefügt werden. Sie sollten auch einen Blick auf \"Hilfe\" -> \"Tastaturkürzel\" werfen.\n",
87 | "\n",
88 | "Durch wiederholtes Drücken der Tastenkombination *Umschalttaste+Eingabetaste* können Sie alle Zellen des Notebooks durchlaufen.\n",
89 | "Alternativ können Sie auch im Menü \"Run\" auf \"Run All Cells\" klicken."
90 | ]
91 | },
92 | {
93 | "cell_type": "markdown",
94 | "metadata": {},
95 | "source": [
96 | "# Basics\n",
97 | "Im Folgenden finden Sie ein Python-Programm, das viele der typischerweise benötigten Operationen enthält: Zuweisungen, Arithmetik, logische Operatoren, Ausgabe, Kommentare. Wie Sie sehen, ist Python recht einfach zu lesen. Ich bin sicher, Sie können die Bedeutung jeder Zeile selbst herausfinden."
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {},
104 | "outputs": [],
105 | "source": [
106 | "x = 34 - 23 # A comment.\n",
107 | "y = \"Hello\" # Another one.\n",
108 | "z = 3.45\n",
109 | "if z == 3.45 or y == \"Hello\":\n",
110 | " x = x + 1\n",
111 | " y = y + \" World\"\n",
112 | "print(x)\n",
113 | "print(y)"
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "## Einrückung\n",
121 | "Python behandelt Blöcke anders als andere Programmiersprachen, die Sie vielleicht kennen, wie Java oder C: Die erste Zeile mit weniger Einrückung steht außerhalb des Blocks, die erste Zeile mit mehr Einrückung beginnt einen verschachtelten Block. Ein Doppelpunkt leitet oft einen neuen Block ein. Im nachstehenden Code wird zum Beispiel die vierte Zeile immer ausgeführt, da sie nicht Teil des Blocks ist:"
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": null,
127 | "metadata": {},
128 | "outputs": [],
129 | "source": [
130 | "if 17<16:\n",
131 | " print(\"executed conditionally\")\n",
132 | " print(\"also conditionally\")\n",
133 | "print(\"always executed, because not part of the block above\")"
134 | ]
135 | },
136 | {
137 | "cell_type": "markdown",
138 | "metadata": {},
139 | "source": [
140 | "## Referenz-Semantik\n",
141 | "Zuweisungen verhalten sich so, wie Sie es vielleicht aus Java kennen: Für atomare Datentypen funktionieren Zuweisungen \"by value\", für alle anderen Datentypen (z.B. Listen) funktionieren Zuweisungen \"by reference\": Wenn wir ein Objekt manipulieren, wirkt sich das auf alle Referenzen aus."
142 | ]
143 | },
144 | {
145 | "cell_type": "code",
146 | "execution_count": null,
147 | "metadata": {},
148 | "outputs": [],
149 | "source": [
150 | "a=17\n",
151 | "b=a #assign the *value* of a to b\n",
152 | "a=12\n",
153 | "print(b) #still 12, because assinment by value\n",
154 | "\n",
155 | "x=[1,2,3] #this is what lists look like\n",
156 | "y=x #assign reference to the list to y\n",
157 | "x.append(4) #manipulate the list by adding a value\n",
158 | "print(y) #y also changed, because of assingment by reference"
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {},
164 | "source": [
165 | "# Listen\n",
166 | "Listen werden in eckigen Klammern geschrieben, wie Sie oben gesehen haben. Listen können Werte gemischten Typs enthalten. Listenindizes beginnen mit 0, wie Sie hier sehen können:"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {},
173 | "outputs": [],
174 | "source": [
175 | "li = [17,\"Hello\",4.1,\"Bar\",5,6]\n",
176 | "li[3]"
177 | ]
178 | },
179 | {
180 | "cell_type": "markdown",
181 | "metadata": {},
182 | "source": [
183 | "Sie können auch negative Indizes verwenden, d. h. wir beginnen die Zählung von rechts:"
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": null,
189 | "metadata": {},
190 | "outputs": [],
191 | "source": [
192 | "li[-3]"
193 | ]
194 | },
195 | {
196 | "cell_type": "markdown",
197 | "metadata": {},
198 | "source": [
199 | "Sie können auch Teilmengen von Listen auswählen (\"slicing\"), etwa so:"
200 | ]
201 | },
202 | {
203 | "cell_type": "code",
204 | "execution_count": null,
205 | "metadata": {},
206 | "outputs": [],
207 | "source": [
208 | "li[2:5]"
209 | ]
210 | },
211 | {
212 | "cell_type": "markdown",
213 | "metadata": {},
214 | "source": [
215 | "Beachten Sie, dass das Slicing eine Kopie der Teilliste zurückgibt."
216 | ]
217 | },
218 | {
219 | "cell_type": "markdown",
220 | "metadata": {},
221 | "source": [
222 | "## Einige weitere Listenoperatoren\n",
223 | "Hier sind einige weitere Operatoren, die Sie vielleicht nützlich finden."
224 | ]
225 | },
226 | {
227 | "cell_type": "code",
228 | "execution_count": null,
229 | "metadata": {
230 | "tags": []
231 | },
232 | "outputs": [],
233 | "source": [
234 | "# Boolean test whether a value is in a list: the in operator\n",
235 | "t = [1,2,3,4]\n",
236 | "2 in t \n",
237 | "\n",
238 | "# Concatenate lists: the + operator\n",
239 | "a = [1,2,3,4]\n",
240 | "b = [5,6,7]\n",
241 | "c = a + b\n",
242 | "c\n",
243 | "\n",
244 | "# Repeat a list n times: the * operator\n",
245 | "a=[1,2,3]\n",
246 | "3*a\n",
247 | "\n",
248 | "# Append lists\n",
249 | "a=[1,2,3]\n",
250 | "a.append(4)\n",
251 | "\n",
252 | "# Index of first occurence\n",
253 | "a.index(2)\n",
254 | "\n",
255 | "# Number of occurences\n",
256 | "a = [1,2,3,2,1,2]\n",
257 | "a.count(2)\n",
258 | "\n",
259 | "# Remove first occurence\n",
260 | "a.remove(2)\n",
261 | "\n",
262 | "# Revese the list\n",
263 | "a.reverse()\n",
264 | "\n",
265 | "# Sort the list\n",
266 | "a.sort()"
267 | ]
268 | },
269 | {
270 | "cell_type": "markdown",
271 | "metadata": {},
272 | "source": [
273 | "*Aufgabe*: Probieren Sie aus was passiert, wenn Sie eine Liste von Strings mit den unten verwendeten Methoden sortieren! Was könnte der Grund für das gezeigte Verhalten sein?"
274 | ]
275 | },
276 | {
277 | "cell_type": "code",
278 | "execution_count": null,
279 | "metadata": {
280 | "tags": []
281 | },
282 | "outputs": [],
283 | "source": [
284 | "string_list = ['c', 'd', 'a', 'y', 'x']\n",
285 | "# Sorting with sorted()-method\n",
286 | "print('Value which is returned by sorted()-method: ', sorted(string_list))\n",
287 | "print('Original string_list: ', string_list)\n",
288 | "# Sorting with sort()-method\n",
289 | "print('Value which is returned by sort()-method: ', string_list.sort())\n",
290 | "print('Original string_list: ', str(string_list))"
291 | ]
292 | },
293 | {
294 | "cell_type": "markdown",
295 | "metadata": {},
296 | "source": [
297 | "## Dictionaries: Ein Mapping-Typ\n",
298 | "Dictionaries sind in anderen Sprachen als Maps bekannt: Sie speichern eine Zuordnung zwischen einer Menge von Schlüsseln und einer Menge von Werten. Im Folgenden finden Sie ein Beispiel für die Verwendung von Dictionaries:"
299 | ]
300 | },
301 | {
302 | "cell_type": "code",
303 | "execution_count": null,
304 | "metadata": {
305 | "tags": []
306 | },
307 | "outputs": [],
308 | "source": [
309 | "# Create a new dictionary\n",
310 | "d = {'user':'bozo', \n",
311 | " 'pswd':1234}\n",
312 | "\n",
313 | "# Access the values via a key\n",
314 | "print('Value for key \\'user\\': ', d['user'])\n",
315 | "\n",
316 | "# Add key-value pairs\n",
317 | "d['id'] = 17\n",
318 | "\n",
319 | "# List of keys\n",
320 | "print('List of keys: ', d.keys())\n",
321 | "\n",
322 | "# List of values\n",
323 | "print('List of values: ', d.values())"
324 | ]
325 | },
326 | {
327 | "cell_type": "markdown",
328 | "metadata": {},
329 | "source": [
330 | "# Funktionen\n",
331 | "Funktionen in Python funktionieren so, wie Sie es erwarten würden: Argumente an Funktionen werden durch Zuweisung übergeben, das heißt, übergebene Argumente werden lokalen Namen zugewiesen. Zuweisungen an Argumente können sich nicht auf den Aufrufer auswirken, aber veränderbare Argumente können sich ändern. Hier ist ein Beispiel für die Definition und den Aufruf einer Funktion:\n"
332 | ]
333 | },
334 | {
335 | "cell_type": "code",
336 | "execution_count": null,
337 | "metadata": {
338 | "tags": []
339 | },
340 | "outputs": [],
341 | "source": [
342 | "def myfun(x: int, y: float):\n",
343 | " print(\"The function is executed.\")\n",
344 | " y[0]=8 # This changes the list that y points to\n",
345 | " return(y[1]+x)\n",
346 | "\n",
347 | "mylist = [1,2,3]\n",
348 | "result=myfun(17,mylist)\n",
349 | "print(\"Function returned: \",result)\n",
350 | "print(\"List is now: \",mylist)"
351 | ]
352 | },
353 | {
354 | "cell_type": "markdown",
355 | "metadata": {},
356 | "source": [
357 | "Beachten Sie, das `x: int` eine sogenannter *Type-Hint* ist. Das bedeutet, dass das `int` nach dem `:` vom Python-Interpreter nicht beachtet wird. Diese Art von Anotation soll also dem Entwickler nur ein Hinweis darauf geben, welchen Datentypen für welchen Parameter er erwarten kann, erzwingt aber keine Typsicherheit in Python!"
358 | ]
359 | },
360 | {
361 | "cell_type": "markdown",
362 | "metadata": {},
363 | "source": [
364 | "## Optionale Argumente\n",
365 | "Wir können Standardwerte für Argumente definieren, die nicht übergeben werden müssen:"
366 | ]
367 | },
368 | {
369 | "cell_type": "code",
370 | "execution_count": null,
371 | "metadata": {},
372 | "outputs": [],
373 | "source": [
374 | "def func(a, b, c=10, d=100):\n",
375 | " print(a, b, c, d)\n",
376 | "type(func(b=1,a=2))\n",
377 | "myfun(1,2)"
378 | ]
379 | },
380 | {
381 | "cell_type": "markdown",
382 | "metadata": {},
383 | "source": [
384 | "Einige weitere Fakten über Funktionen:\n",
385 | "* Alle Funktionen in Python haben einen Rückgabewert, Funktionen ohne Rückgabewert haben den speziellen Rückgabewert `None` (wie z. B. die sort()-Funktion)\n",
386 | "* Es gibt keine Funktionsüberladung in Python.\n",
387 | "* Funktionen können wie jeder andere Datentyp verwendet werden: Sie können Argumente für Funktionen sein, Rückgabewerte von Funktionen, Variablen zugewiesen, usw. Das bedeutet, dass Python eine funktionale Programmiersprache ist, und wir können viele Dinge tun, die Sie aus Haskell kennen und lieben, wie Funktionen höherer Ordnung oder auch Lambda-Ausdrücke!"
388 | ]
389 | },
390 | {
391 | "cell_type": "markdown",
392 | "metadata": {},
393 | "source": [
394 | "# Kontrollstrukturen\n",
395 | "Wir haben oben bereits If-Anweisungen gesehen. For- und While-Schleifen funktionieren auch genau so, wie Sie es erwarten würden, hier sind nur einige Beispiele:"
396 | ]
397 | },
398 | {
399 | "cell_type": "code",
400 | "execution_count": null,
401 | "metadata": {},
402 | "outputs": [],
403 | "source": [
404 | "x = 3\n",
405 | "while x < 10:\n",
406 | " if x > 7:\n",
407 | " x += 2\n",
408 | " continue\n",
409 | " x = x + 1\n",
410 | " print(\"Still in the loop.\")\n",
411 | " if x == 8:\n",
412 | " break\n",
413 | "print(\"Outside of the loop.\")"
414 | ]
415 | },
416 | {
417 | "cell_type": "code",
418 | "execution_count": null,
419 | "metadata": {},
420 | "outputs": [],
421 | "source": [
422 | "for x in range(10):\n",
423 | " if x > 7:\n",
424 | " x += 2\n",
425 | " continue\n",
426 | " x = x + 1\n",
427 | " print(\"Still in the loop.\")\n",
428 | " if x == 8:\n",
429 | " break\n",
430 | "print(\"Outside of the loop.\")"
431 | ]
432 | },
433 | {
434 | "cell_type": "markdown",
435 | "metadata": {},
436 | "source": [
437 | "*Aufgabe*: Implementieren Sie eine Funktion, die prüft, ob eine gegebene Zahl eine Primzahl ist."
438 | ]
439 | },
440 | {
441 | "cell_type": "code",
442 | "execution_count": null,
443 | "metadata": {},
444 | "outputs": [],
445 | "source": [
446 | "def isPrime(n: int) -> int:\n",
447 | " print('Implement me!')\n",
448 | "isPrime(18)"
449 | ]
450 | },
451 | {
452 | "cell_type": "markdown",
453 | "metadata": {},
454 | "source": [
455 | "# List Comprehensions\n",
456 | "Es gibt eine spezielle Syntax für List Comprehensions (die Sie vielleicht aus Haskell kennen)."
457 | ]
458 | },
459 | {
460 | "cell_type": "code",
461 | "execution_count": null,
462 | "metadata": {},
463 | "outputs": [],
464 | "source": [
465 | "evens1 = []\n",
466 | "for x in range(3,100):\n",
467 | " if x%3 == 0:\n",
468 | " evens1.append(x)\n",
469 | "print(evens1)\n",
470 | "\n",
471 | "# List of all multiples of 3 that are <100:\n",
472 | "evens2 = [x for x in range(3,100) if x%3==0]\n",
473 | "print(evens2)"
474 | ]
475 | },
476 | {
477 | "cell_type": "markdown",
478 | "metadata": {},
479 | "source": [
480 | "Aufgabe: Erstellen Sie mit Hilfe eines List Comprehension eine Liste aller Primzahlen < 1000."
481 | ]
482 | },
483 | {
484 | "cell_type": "code",
485 | "execution_count": null,
486 | "metadata": {},
487 | "outputs": [],
488 | "source": [
489 | "primes = ['Implement me!']"
490 | ]
491 | },
492 | {
493 | "cell_type": "markdown",
494 | "metadata": {},
495 | "source": [
496 | "# Numpy\n",
497 | "Numpy ist ein sehr beliebtes Python-Paket, das die Arbeit mit numerischen Arrays erleichtert. Es ist die Grundlage für vieles, was Sie in diesem Kurs sehen werden."
498 | ]
499 | },
500 | {
501 | "cell_type": "markdown",
502 | "metadata": {},
503 | "source": [
504 | "## Importieren von Modulen/Paketen\n",
505 | "\n",
506 | "Um mit numerischen Arrays arbeiten zu können, importieren wir das Paket [NumPy](http://www.numpy.org)."
507 | ]
508 | },
509 | {
510 | "cell_type": "code",
511 | "execution_count": null,
512 | "metadata": {
513 | "tags": []
514 | },
515 | "outputs": [],
516 | "source": [
517 | "import numpy as np"
518 | ]
519 | },
520 | {
521 | "cell_type": "markdown",
522 | "metadata": {},
523 | "source": [
524 | "Jetzt können wir alle NumPy-Funktionen verwenden (durch Voranstellen von \"`np.`\")."
525 | ]
526 | },
527 | {
528 | "cell_type": "code",
529 | "execution_count": null,
530 | "metadata": {},
531 | "outputs": [],
532 | "source": [
533 | "np.zeros(10000)"
534 | ]
535 | },
536 | {
537 | "cell_type": "markdown",
538 | "metadata": {},
539 | "source": [
540 | "## Tabulatorvervollständigung\n",
541 | "\n",
542 | "*Übung:* Tippen Sie \"`np.ze`\" (ohne Anführungszeichen) und drücken Sie dann die *Tab*-Taste ..."
543 | ]
544 | },
545 | {
546 | "cell_type": "code",
547 | "execution_count": null,
548 | "metadata": {},
549 | "outputs": [],
550 | "source": [
551 | "np."
552 | ]
553 | },
554 | {
555 | "cell_type": "markdown",
556 | "metadata": {},
557 | "source": [
558 | "## Array, Vektor, Matrix\n",
559 | "\n",
560 | "Arrays können beliebig viele Dimensionen haben, aber lassen Sie uns für den Moment nur eindimensionale Arrays verwenden.\n",
561 | "Arrays können mit [numpy.array()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html) erstellt werden:"
562 | ]
563 | },
564 | {
565 | "cell_type": "code",
566 | "execution_count": null,
567 | "metadata": {},
568 | "outputs": [],
569 | "source": [
570 | "a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
571 | ]
572 | },
573 | {
574 | "cell_type": "markdown",
575 | "metadata": {},
576 | "source": [
577 | "Beachten Sie, dass das Ergebnis nicht angezeigt wird, wenn Sie einer Variablen einen Wert zuweisen (da die Zuweisung eine *Anweisung* und kein *Ausdruck* ist).\n",
578 | "Um die Daten anzuzeigen, schreiben Sie den Variablennamen separat in die letzte (oder einzige) Zeile einer Codezelle."
579 | ]
580 | },
581 | {
582 | "cell_type": "code",
583 | "execution_count": null,
584 | "metadata": {},
585 | "outputs": [],
586 | "source": [
587 | "a"
588 | ]
589 | },
590 | {
591 | "cell_type": "markdown",
592 | "metadata": {},
593 | "source": [
594 | "Übrigens gibt es einen einfacheren Weg, dieses spezielle Array zu erhalten (mit [numpy.arange()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html)):"
595 | ]
596 | },
597 | {
598 | "cell_type": "code",
599 | "execution_count": null,
600 | "metadata": {},
601 | "outputs": [],
602 | "source": [
603 | "b = np.arange(1,10)\n",
604 | "b"
605 | ]
606 | },
607 | {
608 | "cell_type": "markdown",
609 | "metadata": {},
610 | "source": [
611 | "## Hilfe erhalten\n",
612 | "\n",
613 | "Wenn Sie Einzelheiten über die Verwendung von `np.arange()` und alle unterstützten Argumente wissen wollen, werfen Sie einen Blick in den Hilfetext.\n",
614 | "Hängen Sie einfach ein Fragezeichen an den Funktionsnamen (ohne Klammern!):"
615 | ]
616 | },
617 | {
618 | "cell_type": "code",
619 | "execution_count": null,
620 | "metadata": {},
621 | "outputs": [],
622 | "source": [
623 | "np.arange?"
624 | ]
625 | },
626 | {
627 | "cell_type": "markdown",
628 | "metadata": {},
629 | "source": [
630 | "Im unteren Teil des Browserfensters sollte sich ein Hilfefenster öffnen.\n",
631 | "Dieses Fenster kann durch Drücken der Taste *q* (wie \"quit\") geschlossen werden.\n",
632 | "\n",
633 | "Holen wir uns mehr Hilfe:"
634 | ]
635 | },
636 | {
637 | "cell_type": "code",
638 | "execution_count": null,
639 | "metadata": {},
640 | "outputs": [],
641 | "source": [
642 | "np.zeros?"
643 | ]
644 | },
645 | {
646 | "cell_type": "markdown",
647 | "metadata": {},
648 | "source": [
649 | "Sie können auch Hilfe für das gesamte NumPy-Paket erhalten:"
650 | ]
651 | },
652 | {
653 | "cell_type": "code",
654 | "execution_count": null,
655 | "metadata": {},
656 | "outputs": [],
657 | "source": [
658 | "np?"
659 | ]
660 | },
661 | {
662 | "cell_type": "markdown",
663 | "metadata": {},
664 | "source": [
665 | "Sie können für jedes Objekt Hilfe erhalten, indem Sie ein Fragezeichen an den Namen des Objekts anhängen (oder voranstellen).\n",
666 | "Schauen wir uns an, was das Hilfesystem uns über unsere Variable `a` sagen kann:"
667 | ]
668 | },
669 | {
670 | "cell_type": "code",
671 | "execution_count": null,
672 | "metadata": {},
673 | "outputs": [],
674 | "source": [
675 | "a?"
676 | ]
677 | },
678 | {
679 | "cell_type": "markdown",
680 | "metadata": {},
681 | "source": [
682 | "Das Hilfesystem kann bei der Lösung der folgenden Aufgaben sehr nützlich sein ..."
683 | ]
684 | },
685 | {
686 | "cell_type": "markdown",
687 | "metadata": {},
688 | "source": [
689 | "## `np.arange()`\n",
690 | "\n",
691 | "Wir werden oft Sequenzen von gleichmäßig verteilten Zahlen brauchen, also lasst uns welche erstellen.\n",
692 | "\n",
693 | "*Übung:* Erzeugen Sie eine Zahlenfolge mit `np.arange()`, beginnend mit 0 und bis (aber nicht einschließlich) 6 mit einer Schrittweite von 1."
694 | ]
695 | },
696 | {
697 | "cell_type": "code",
698 | "execution_count": null,
699 | "metadata": {},
700 | "outputs": [],
701 | "source": [
702 | "'Implement me!'"
703 | ]
704 | },
705 | {
706 | "cell_type": "markdown",
707 | "metadata": {},
708 | "source": [
709 | "*Übung:* Erzeugen Sie eine Zahlenfolge mit `np.arange()`, beginnend mit 0 und bis (aber nicht einschließlich) 0,6 mit einer Schrittweite von 0,1."
710 | ]
711 | },
712 | {
713 | "cell_type": "code",
714 | "execution_count": null,
715 | "metadata": {},
716 | "outputs": [],
717 | "source": [
718 | "'Implement me!'"
719 | ]
720 | },
721 | {
722 | "cell_type": "markdown",
723 | "metadata": {},
724 | "source": [
725 | "*Übung:* Erzeugen Sie eine Zahlenfolge mit `np.arange()`, beginnend mit 0,5 bis (aber nicht einschließlich) 1,1 mit einer Schrittweite von 0,1."
726 | ]
727 | },
728 | {
729 | "cell_type": "code",
730 | "execution_count": null,
731 | "metadata": {},
732 | "outputs": [],
733 | "source": [
734 | "'Implement me!'"
735 | ]
736 | },
737 | {
738 | "cell_type": "markdown",
739 | "metadata": {},
740 | "source": [
741 | "Die vorherige Übung ist etwas knifflig.\n",
742 | "Wenn Sie es richtig gemacht haben, schauen Sie unter [arange considered harmful](http://nbviewer.ipython.org/github/mgeier/python-audio/blob/master/misc/arange.ipynb) nach, was Sie falsch gemacht haben *könnten*.\n",
743 | "Wenn Sie ein unerwartetes Ergebnis erhalten haben, schauen Sie unter [arange considered harmful](http://nbviewer.ipython.org/github/mgeier/python-audio/blob/master/misc/arange.ipynb) nach einer Erklärung.\n",
744 | "\n",
745 | "*Übung:* Können Sie das Problem beheben?"
746 | ]
747 | },
748 | {
749 | "cell_type": "code",
750 | "execution_count": null,
751 | "metadata": {},
752 | "outputs": [],
753 | "source": []
754 | },
755 | {
756 | "cell_type": "markdown",
757 | "metadata": {},
758 | "source": [
759 | "Was lernen wir aus all dem?\n",
760 | "$\\Rightarrow$\n",
761 | "`np.arange()` ist großartig, aber verwenden Sie es nur mit ganzzahligen Schrittweiten!"
762 | ]
763 | },
764 | {
765 | "cell_type": "markdown",
766 | "metadata": {},
767 | "source": [
768 | "## `np.linspace()`\n",
769 | "\n",
770 | "Eine andere, etwas andere Methode, um eine Folge von Zahlen mit gleichmäßigen Abständen zu erzeugen, ist [numpy.linspace()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html).\n",
771 | "Werfen Sie einen Blick in die Dokumentation."
772 | ]
773 | },
774 | {
775 | "cell_type": "code",
776 | "execution_count": null,
777 | "metadata": {},
778 | "outputs": [],
779 | "source": [
780 | "np.linspace?"
781 | ]
782 | },
783 | {
784 | "cell_type": "markdown",
785 | "metadata": {},
786 | "source": [
787 | "*Übung:* Erzeugen Sie eine Zahlenfolge mit `np.linspace()`, beginnend mit 0 und bis (einschließlich) 6 mit einer Schrittweite von 1."
788 | ]
789 | },
790 | {
791 | "cell_type": "code",
792 | "execution_count": null,
793 | "metadata": {},
794 | "outputs": [],
795 | "source": [
796 | "'Implement me!'"
797 | ]
798 | },
799 | {
800 | "cell_type": "markdown",
801 | "metadata": {},
802 | "source": [
803 | "Beachten Sie, dass das resultierende Array einen *Gleitkomma*-Datentyp hat, auch wenn alle Eingaben (und die Schrittweite) Ganzzahlen sind.\n",
804 | "Dies ist bei `np.arange()` nicht der Fall.\n",
805 | "\n",
806 | "*Übung:* Erzeugen Sie mit `np.linspace()` eine Folge von Zahlen, beginnend mit 0 und bis (aber nicht einschließlich) 6 mit einer Schrittweite von 1."
807 | ]
808 | },
809 | {
810 | "cell_type": "code",
811 | "execution_count": null,
812 | "metadata": {},
813 | "outputs": [],
814 | "source": [
815 | "'Implement me!'"
816 | ]
817 | },
818 | {
819 | "cell_type": "markdown",
820 | "metadata": {},
821 | "source": [
822 | "*Übung:* Erzeugen Sie eine Zahlenfolge mit `np.linspace()`, beginnend mit 0 und bis (aber nicht einschließlich) 0,6 mit einer Schrittweite von 0,1."
823 | ]
824 | },
825 | {
826 | "cell_type": "code",
827 | "execution_count": null,
828 | "metadata": {},
829 | "outputs": [],
830 | "source": [
831 | "'Implement me!'"
832 | ]
833 | },
834 | {
835 | "cell_type": "markdown",
836 | "metadata": {},
837 | "source": [
838 | "*Übung:* Erzeugen Sie eine Zahlenfolge mit `np.linspace()`, beginnend mit 0,5 und bis zu (aber nicht einschließlich) 1,1 mit einer Schrittweite von 0,1."
839 | ]
840 | },
841 | {
842 | "cell_type": "code",
843 | "execution_count": null,
844 | "metadata": {},
845 | "outputs": [],
846 | "source": [
847 | "'Implement me!'"
848 | ]
849 | },
850 | {
851 | "cell_type": "markdown",
852 | "metadata": {},
853 | "source": [
854 | "Beachten Sie, dass `np.linspace()` nicht das oben erwähnte Problem hat, das wir mit `np.arange()` hatten."
855 | ]
856 | },
857 | {
858 | "cell_type": "markdown",
859 | "metadata": {},
860 | "source": [
861 | "## Erstellen einer Sinuswelle\n",
862 | "\n",
863 | "Erstellen wir nun ein interessanteres Array, das ein digitales Sinussignal darstellt. Das Signal folgt der Gleichung $y(t) = A\\sin(\\omega t)$ mit $\\omega = 2\\pi f$ und $f$ ist die Frequenz des Sinus.\n",
864 | "Die maximale Signalamplitude ist durch $A$ gegeben.\n",
865 | "Die Variable $t$ steht natürlich für die Zeit.\n",
866 | "Wir wollen ein digitales Signal mit gleichmäßig verteilten Werten für $t$ erzeugen.\n",
867 | "\n",
868 | "Wir können die Funktion [numpy.sin()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.sin.html) verwenden, um einen Sinuston zu erzeugen. Schauen wir uns zunächst den Hilfetext an."
869 | ]
870 | },
871 | {
872 | "cell_type": "code",
873 | "execution_count": null,
874 | "metadata": {},
875 | "outputs": [],
876 | "source": [
877 | "np.sin?"
878 | ]
879 | },
880 | {
881 | "cell_type": "markdown",
882 | "metadata": {},
883 | "source": [
884 | "Da wir nun wissen, welche Funktion wir aufrufen müssen, brauchen wir eine geeignete Eingabe.\n",
885 | "Und hier kommen unsere Sequenzen von gleichmäßig verteilten Werten von oben ins Spiel.\n",
886 | "\n",
887 | "Das Schöne an NumPy-Funktionen wie `np.sin()` ist, dass sie auf ganze Arrays auf einmal wirken können, so dass es nicht notwendig ist, die Funktion für jeden einzelnen Wert separat aufzurufen.\n",
888 | "Daher können wir den gesamten Wertebereich für unsere Zeitvariable $t$ in einem Array speichern.\n",
889 | "\n",
890 | "Gemäß der Gleichung muss jeder Wert von $t$ mit (der Konstante) $\\omega$ multipliziert werden.\n",
891 | "Das ist eine weitere nette Sache an NumPy: wir müssen nicht jeden Wert des Arrays $t$ einzeln mit $\\omega$ multiplizieren, wir können das ganze Array auf einmal mit einem Skalar multiplizieren, und NumPy übernimmt die elementweise Multiplikation für uns.\n",
892 | "Dies wird [\"broadcasting\"](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) genannt, falls Sie über dieses Wort in der Dokumentation stolpern.\n",
893 | "Das Array, das von `np.sin()` zurückgegeben wird, kann (wiederum mittels Broadcasting) mit dem konstanten Skalar $A$ multipliziert werden, um das Endergebnis zu erhalten.\n",
894 | "\n",
895 | "Das einzige, was noch fehlt, ist $\\pi$, aber das ist einfach:"
896 | ]
897 | },
898 | {
899 | "cell_type": "code",
900 | "execution_count": null,
901 | "metadata": {},
902 | "outputs": [],
903 | "source": [
904 | "np.pi"
905 | ]
906 | },
907 | {
908 | "cell_type": "markdown",
909 | "metadata": {},
910 | "source": [
911 | "Nun wollen wir eine Sinuswelle mit einer Frequenz von 2 Hz, einer Dauer von 1 Sekunde und einer Amplitude von 0,3 erzeugen.\n",
912 | "Wir verwenden eine Abtastrate von 44,1 kHz."
913 | ]
914 | },
915 | {
916 | "cell_type": "code",
917 | "execution_count": null,
918 | "metadata": {
919 | "tags": []
920 | },
921 | "outputs": [],
922 | "source": [
923 | "dur = 1 # duration in seconds\n",
924 | "amp = 0.3 # maximum amplitude\n",
925 | "freq = 2 # frequency of the sine tone in Hertz\n",
926 | "fs = 44100 # sampling frequency in Hertz\n",
927 | "\n",
928 | "t = np.arange(np.ceil(dur * fs)) / fs\n",
929 | "y = amp * np.sin(2 * np.pi * freq * t)"
930 | ]
931 | },
932 | {
933 | "cell_type": "markdown",
934 | "metadata": {},
935 | "source": [
936 | "## Plotten\n",
937 | "\n",
938 | "Python und NumPy können nicht selbst plotten, sie benötigen die Hilfe von [matplotlib](http://matplotlib.org/)."
939 | ]
940 | },
941 | {
942 | "cell_type": "code",
943 | "execution_count": null,
944 | "metadata": {},
945 | "outputs": [],
946 | "source": [
947 | "import matplotlib.pyplot as plt\n",
948 | "%matplotlib inline"
949 | ]
950 | },
951 | {
952 | "cell_type": "markdown",
953 | "metadata": {},
954 | "source": [
955 | "Jetzt können wir die Daten aus unserem Array aufzeichnen:"
956 | ]
957 | },
958 | {
959 | "cell_type": "code",
960 | "execution_count": null,
961 | "metadata": {},
962 | "outputs": [],
963 | "source": [
964 | "plt.plot(y)"
965 | ]
966 | },
967 | {
968 | "cell_type": "markdown",
969 | "metadata": {},
970 | "source": [
971 | "Wie immer, für weitere Informationen:"
972 | ]
973 | },
974 | {
975 | "cell_type": "code",
976 | "execution_count": null,
977 | "metadata": {},
978 | "outputs": [],
979 | "source": [
980 | "%matplotlib?"
981 | ]
982 | },
983 | {
984 | "cell_type": "markdown",
985 | "metadata": {},
986 | "source": [
987 | "## Verändern des Plots\n",
988 | "\n",
989 | "Schauen wir uns noch einmal unseren Plot an."
990 | ]
991 | },
992 | {
993 | "cell_type": "code",
994 | "execution_count": null,
995 | "metadata": {},
996 | "outputs": [],
997 | "source": [
998 | "plt.plot(y);"
999 | ]
1000 | },
1001 | {
1002 | "cell_type": "markdown",
1003 | "metadata": {},
1004 | "source": [
1005 | "Da wir nur ein einziges Array an die Funktion `plot()` übergeben haben, zeigt die x-Achse den Sample-Index von 0 bis zur Länge des Signals in Samples (minus eins).\n",
1006 | "Es könnte sinnvoller sein, die Zeit in Sekunden anzugeben.\n",
1007 | "\n",
1008 | "Aber lassen Sie uns zuerst die vorherige Darstellung schließen."
1009 | ]
1010 | },
1011 | {
1012 | "cell_type": "code",
1013 | "execution_count": null,
1014 | "metadata": {},
1015 | "outputs": [],
1016 | "source": [
1017 | "plt.close()"
1018 | ]
1019 | },
1020 | {
1021 | "cell_type": "markdown",
1022 | "metadata": {},
1023 | "source": [
1024 | "Wenn wir zwei Arrays an die Funktion `plot()` übergeben, definiert das erste die Zuordnung von Stichprobenindizes zu den tatsächlichen Werten, die auf der x-Achse angezeigt werden, das zweite gibt die entsprechenden y-Werte an."
1025 | ]
1026 | },
1027 | {
1028 | "cell_type": "code",
1029 | "execution_count": null,
1030 | "metadata": {},
1031 | "outputs": [],
1032 | "source": [
1033 | "plt.plot(t, y);"
1034 | ]
1035 | },
1036 | {
1037 | "cell_type": "markdown",
1038 | "metadata": {},
1039 | "source": [
1040 | "Gut, jetzt zeigt die x-Achse die Zeit in Sekunden an.\n",
1041 | "Lassen Sie uns Achsenbeschriftungen erstellen, damit jeder Bescheid weiß."
1042 | ]
1043 | },
1044 | {
1045 | "cell_type": "code",
1046 | "execution_count": null,
1047 | "metadata": {},
1048 | "outputs": [],
1049 | "source": [
1050 | "plt.plot(t, y)\n",
1051 | "plt.xlabel(\"Time / Seconds\")\n",
1052 | "plt.ylabel(\"Amplitude\")\n",
1053 | "plt.title(\"Sine Tone with {} Hz\".format(freq));"
1054 | ]
1055 | },
1056 | {
1057 | "cell_type": "markdown",
1058 | "metadata": {},
1059 | "source": [
1060 | "Weitere Informationen finden Sie unter [Getting Started With `matplotlib`](http://nbviewer.ipython.org/github/mgeier/python-audio/blob/master/plotting/matplotlib.ipynb)."
1061 | ]
1062 | },
1063 | {
1064 | "cell_type": "markdown",
1065 | "metadata": {},
1066 | "source": [
1067 | "## Zweidimensionale Arrays\n",
1068 | "\n",
1069 | "Zweidimensionale Arrays sehen ein wenig aus wie Listen von Listen, aber intern werden sie immer noch in einem zusammenhängenden Speicherbereich gespeichert.\n",
1070 | "\n",
1071 | "Es gibt mehrere Funktionen zur Erstellung von Arrays, mit denen die Anzahl der Zeilen und Spalten angegeben werden kann, z. B. [numpy.zeros()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.zeros.html) und [numpy.ones()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.ones.html)."
1072 | ]
1073 | },
1074 | {
1075 | "cell_type": "code",
1076 | "execution_count": null,
1077 | "metadata": {},
1078 | "outputs": [],
1079 | "source": [
1080 | "np.zeros((4, 2))"
1081 | ]
1082 | },
1083 | {
1084 | "cell_type": "code",
1085 | "execution_count": null,
1086 | "metadata": {},
1087 | "outputs": [],
1088 | "source": [
1089 | "np.ones((4, 2))"
1090 | ]
1091 | },
1092 | {
1093 | "cell_type": "markdown",
1094 | "metadata": {},
1095 | "source": [
1096 | "Arrays können auch aus Listen von Listen (auch bekannt als *verschachtelte* Listen) mit [numpy.array()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html) erstellt werden:"
1097 | ]
1098 | },
1099 | {
1100 | "cell_type": "code",
1101 | "execution_count": null,
1102 | "metadata": {},
1103 | "outputs": [],
1104 | "source": [
1105 | "np.array([[.1, .2], [.3, .4], [.5, .6], [.7, .8]])"
1106 | ]
1107 | },
1108 | {
1109 | "cell_type": "markdown",
1110 | "metadata": {},
1111 | "source": [
1112 | "Beachten Sie, dass die inneren Listen die einzelnen Zeilen des Arrays liefern.\n",
1113 | "\n",
1114 | "Zweidimensionale Arrays können auch durch spaltenweises Verketten einer Liste von eindimensionalen Arrays (oder Listen) mit [numpy.column_stack()](http://docs.scipy.org/doc/numpy/reference/generated/numpy.column_stack.html) erstellt werden:"
1115 | ]
1116 | },
1117 | {
1118 | "cell_type": "code",
1119 | "execution_count": null,
1120 | "metadata": {
1121 | "tags": []
1122 | },
1123 | "outputs": [],
1124 | "source": [
1125 | "a = np.column_stack([[.1, .2, .3, .4], [.5, .6, .7, .8]])\n",
1126 | "a"
1127 | ]
1128 | },
1129 | {
1130 | "cell_type": "markdown",
1131 | "metadata": {},
1132 | "source": [
1133 | "Wenn Sie Zeilen und Spalten umdrehen wollen, können Sie das Array transponieren:"
1134 | ]
1135 | },
1136 | {
1137 | "cell_type": "code",
1138 | "execution_count": null,
1139 | "metadata": {
1140 | "tags": []
1141 | },
1142 | "outputs": [],
1143 | "source": [
1144 | "a.T\n"
1145 | ]
1146 | },
1147 | {
1148 | "cell_type": "markdown",
1149 | "metadata": {},
1150 | "source": [
1151 | "Das transponierte Array ist *nicht* eine Kopie des ursprünglichen Arrays, es ist vielmehr eine andere *Sicht* auf denselben Speicher.\n",
1152 | "Das heißt, wenn Sie ein Element des transponierten Arrays ändern, wird diese Änderung auch im ursprünglichen Array sichtbar!"
1153 | ]
1154 | },
1155 | {
1156 | "cell_type": "code",
1157 | "execution_count": null,
1158 | "metadata": {},
1159 | "outputs": [],
1160 | "source": [
1161 | "b[1, 2] = 0\n",
1162 | "a"
1163 | ]
1164 | },
1165 | {
1166 | "cell_type": "markdown",
1167 | "metadata": {},
1168 | "source": [
1169 | "## Array-Eigenschaften\n",
1170 | "\n",
1171 | "Lassen Sie uns ein zweidimensionales Array erstellen:"
1172 | ]
1173 | },
1174 | {
1175 | "cell_type": "code",
1176 | "execution_count": null,
1177 | "metadata": {
1178 | "tags": []
1179 | },
1180 | "outputs": [],
1181 | "source": [
1182 | "x = np.random.normal(scale=0.2, size=(int(1.5 * fs), 2))\n",
1183 | "x"
1184 | ]
1185 | },
1186 | {
1187 | "cell_type": "markdown",
1188 | "metadata": {},
1189 | "source": [
1190 | "*Übung:* Probieren Sie diese verschiedenen Möglichkeiten aus, um die Größe des Feldes zu erhalten:"
1191 | ]
1192 | },
1193 | {
1194 | "cell_type": "code",
1195 | "execution_count": null,
1196 | "metadata": {
1197 | "tags": []
1198 | },
1199 | "outputs": [],
1200 | "source": [
1201 | "len(a)"
1202 | ]
1203 | },
1204 | {
1205 | "cell_type": "code",
1206 | "execution_count": null,
1207 | "metadata": {
1208 | "tags": []
1209 | },
1210 | "outputs": [],
1211 | "source": [
1212 | "a.shape"
1213 | ]
1214 | },
1215 | {
1216 | "cell_type": "code",
1217 | "execution_count": null,
1218 | "metadata": {
1219 | "tags": []
1220 | },
1221 | "outputs": [],
1222 | "source": [
1223 | "a.size"
1224 | ]
1225 | },
1226 | {
1227 | "cell_type": "code",
1228 | "execution_count": null,
1229 | "metadata": {
1230 | "tags": []
1231 | },
1232 | "outputs": [],
1233 | "source": [
1234 | "a.nbytes"
1235 | ]
1236 | },
1237 | {
1238 | "cell_type": "markdown",
1239 | "metadata": {},
1240 | "source": [
1241 | "*Übung:* Es gibt noch viel mehr Informationen über das Array, probiere die folgenden Befehle aus und finde heraus, was sie bedeuten."
1242 | ]
1243 | },
1244 | {
1245 | "cell_type": "code",
1246 | "execution_count": null,
1247 | "metadata": {},
1248 | "outputs": [],
1249 | "source": [
1250 | "x.ndim"
1251 | ]
1252 | },
1253 | {
1254 | "cell_type": "code",
1255 | "execution_count": null,
1256 | "metadata": {},
1257 | "outputs": [],
1258 | "source": [
1259 | "x.dtype"
1260 | ]
1261 | },
1262 | {
1263 | "cell_type": "code",
1264 | "execution_count": null,
1265 | "metadata": {},
1266 | "outputs": [],
1267 | "source": [
1268 | "x.itemsize"
1269 | ]
1270 | },
1271 | {
1272 | "cell_type": "code",
1273 | "execution_count": null,
1274 | "metadata": {},
1275 | "outputs": [],
1276 | "source": [
1277 | "x.strides"
1278 | ]
1279 | },
1280 | {
1281 | "cell_type": "code",
1282 | "execution_count": null,
1283 | "metadata": {},
1284 | "outputs": [],
1285 | "source": [
1286 | "x.flags"
1287 | ]
1288 | },
1289 | {
1290 | "cell_type": "markdown",
1291 | "metadata": {},
1292 | "source": [
1293 | "*Übung:*\n",
1294 | "Sie können auch einige statistische Werte über die Daten im Array erhalten.\n",
1295 | "Prüfen Sie, ob sie mit dem gegebenen normalverteilten Rauschsignal übereinstimmen."
1296 | ]
1297 | },
1298 | {
1299 | "cell_type": "code",
1300 | "execution_count": null,
1301 | "metadata": {},
1302 | "outputs": [],
1303 | "source": [
1304 | "x.max()"
1305 | ]
1306 | },
1307 | {
1308 | "cell_type": "code",
1309 | "execution_count": null,
1310 | "metadata": {},
1311 | "outputs": [],
1312 | "source": [
1313 | "x.min()"
1314 | ]
1315 | },
1316 | {
1317 | "cell_type": "code",
1318 | "execution_count": null,
1319 | "metadata": {},
1320 | "outputs": [],
1321 | "source": [
1322 | "x.ptp()"
1323 | ]
1324 | },
1325 | {
1326 | "cell_type": "code",
1327 | "execution_count": null,
1328 | "metadata": {},
1329 | "outputs": [],
1330 | "source": [
1331 | "x.mean()"
1332 | ]
1333 | },
1334 | {
1335 | "cell_type": "code",
1336 | "execution_count": null,
1337 | "metadata": {},
1338 | "outputs": [],
1339 | "source": [
1340 | "x.std()"
1341 | ]
1342 | },
1343 | {
1344 | "cell_type": "code",
1345 | "execution_count": null,
1346 | "metadata": {},
1347 | "outputs": [],
1348 | "source": [
1349 | "x.var()"
1350 | ]
1351 | },
1352 | {
1353 | "cell_type": "markdown",
1354 | "metadata": {},
1355 | "source": [
1356 | "Die meisten dieser *Methoden* existieren auch als *Funktionen*, z.B."
1357 | ]
1358 | },
1359 | {
1360 | "cell_type": "code",
1361 | "execution_count": null,
1362 | "metadata": {},
1363 | "outputs": [],
1364 | "source": [
1365 | "np.max(x)"
1366 | ]
1367 | },
1368 | {
1369 | "cell_type": "markdown",
1370 | "metadata": {},
1371 | "source": [
1372 | "Sowohl die Funktionen als auch die Methoden haben ein optionales Argument *Achse*.\n",
1373 | "\n",
1374 | "*Übung:* Versuchen Sie `axis=0` mit allen oben genannten Funktionen/Methoden."
1375 | ]
1376 | },
1377 | {
1378 | "cell_type": "code",
1379 | "execution_count": null,
1380 | "metadata": {},
1381 | "outputs": [],
1382 | "source": [
1383 | "x.std(axis=0)"
1384 | ]
1385 | },
1386 | {
1387 | "cell_type": "code",
1388 | "execution_count": null,
1389 | "metadata": {},
1390 | "outputs": [],
1391 | "source": [
1392 | "np.mean(x, axis=0)"
1393 | ]
1394 | },
1395 | {
1396 | "cell_type": "markdown",
1397 | "metadata": {},
1398 | "source": [
1399 | "*Übung:* Was ist der Unterschied zwischen `axis=0` und `axis=1`?\n",
1400 | "Was bedeutet `axis=-1`?"
1401 | ]
1402 | },
1403 | {
1404 | "cell_type": "code",
1405 | "execution_count": null,
1406 | "metadata": {},
1407 | "outputs": [],
1408 | "source": []
1409 | },
1410 | {
1411 | "cell_type": "markdown",
1412 | "metadata": {},
1413 | "source": [
1414 | "## Broadcasting\n",
1415 | "\n",
1416 | "Wir haben bereits gesehen, dass wenn ein Skalar mit einem Array multipliziert wird, diese Multiplikation elementweise auf dem Array durchgeführt wird.\n",
1417 | "Die NumPy-Leute nennen dies [broadcasting](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html).\n",
1418 | "\n",
1419 | "Das Tolle daran ist, dass es nicht auf Operationen zwischen einem Skalar und einem Array beschränkt ist, sondern auch zwischen Arrays unterschiedlicher Anzahl von Dimensionen.\n",
1420 | "\n",
1421 | "Nehmen wir zum Beispiel ein eindimensionales Array mit zwei Werten und multiplizieren es mit unserem zweidimensionalen Array `x` von vorhin:"
1422 | ]
1423 | },
1424 | {
1425 | "cell_type": "code",
1426 | "execution_count": null,
1427 | "metadata": {},
1428 | "outputs": [],
1429 | "source": [
1430 | "np.array([0.5, 100]) * x"
1431 | ]
1432 | },
1433 | {
1434 | "cell_type": "markdown",
1435 | "metadata": {},
1436 | "source": [
1437 | "Obwohl diese beiden Arrays eindeutig eine unterschiedliche Form und eine unterschiedliche Anzahl von Dimensionen haben, hat die Multiplikation funktioniert.\n",
1438 | "In diesem Fall wurde jedes Element der ersten Spalte von \"x\" mit dem ersten Wert der anderen Matrix multipliziert, und dasselbe gilt für die zweite Spalte und den zweiten Wert der Matrix.\n",
1439 | "\n",
1440 | "In diesem Beispiel hat das Ergebnis die gleiche Form wie einer der Operanden, und der andere Operand wurde entlang seiner einzigen (oder eher fehlenden) Dimension \"gestreckt\".\n",
1441 | "\n",
1442 | "Aber das muss nicht so sein.\n",
1443 | "Erstellen wir ein zweidimensionales Array, das nur aus einer Spalte besteht:"
1444 | ]
1445 | },
1446 | {
1447 | "cell_type": "code",
1448 | "execution_count": null,
1449 | "metadata": {},
1450 | "outputs": [],
1451 | "source": [
1452 | "y = np.random.normal(scale=0.2, size=(int(1.5 * fs), 1))\n",
1453 | "y"
1454 | ]
1455 | },
1456 | {
1457 | "cell_type": "code",
1458 | "execution_count": null,
1459 | "metadata": {},
1460 | "outputs": [],
1461 | "source": [
1462 | "y.shape"
1463 | ]
1464 | },
1465 | {
1466 | "cell_type": "markdown",
1467 | "metadata": {},
1468 | "source": [
1469 | "Wenn wir ein eindimensionales Array mit diesem zweidimensionalen Spaltenarray multiplizieren, hat keine der Dimensionen die gleiche Größe.\n",
1470 | "Dennoch können wir sie multiplizieren und beide Felder werden \"gestreckt\" (entlang ihrer singulären/fehlenden Dimension), was zu einem Ergebnis führt, das eine größere Form hat als einer der Operanden:"
1471 | ]
1472 | },
1473 | {
1474 | "cell_type": "code",
1475 | "execution_count": null,
1476 | "metadata": {},
1477 | "outputs": [],
1478 | "source": [
1479 | "np.array([0.5, 100]) * y"
1480 | ]
1481 | },
1482 | {
1483 | "cell_type": "markdown",
1484 | "metadata": {},
1485 | "source": [
1486 | "Die linke Spalte des Ergebnisses ist \"y\" multipliziert mit dem ersten Element der eindimensionalen Matrix, die rechte Spalte ist das gleiche \"y\" multipliziert mit dem zweiten Element."
1487 | ]
1488 | },
1489 | {
1490 | "cell_type": "markdown",
1491 | "metadata": {},
1492 | "source": [
1493 | "
\n",
1494 | " \n",
1496 | "
\n",
1497 | " \n",
1498 | "
\n",
1499 | " To the extent possible under law,\n",
1500 | " the person who associated CC0\n",
1501 | " with this work has waived all copyright and related or neighboring\n",
1502 | " rights to this work.\n",
1503 | "