Skip to content
Snippets Groups Projects
Commit dc640d4c authored by Christof Kaufmann's avatar Christof Kaufmann
Browse files

Notebooks from applied-cs/data-science@7b0e547e

parent f016e066
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
# Code zu Folien
Dieses Skript bzw. Jupyter-Notebook enthält den Code, der auch auf den Folien "Python Grundlagen" enthalten ist. Zum Vorbereiten, Mitmachen oder Nacharbeiten.
%% Cell type:code id: tags:
```
a = 10 # Datentypen werden implizit bestimmt
print(type(a)) # type() gibt den Typ aus
A = 20 / 2 # Groß- / Kleinschreibung wird unterschieden
print(type(A))
print(a ** 2, 7 // 2) # ∗∗ ist der Potenzoperator, // steht für floor Division
```
%% Cell type:code id: tags:
```
print(A == 10) # Vergleichsoperatoren: <, <=, >, >=, ==, !=
print(A == 10 and a == 10) # Verknüpfungsoperatoren: not, and, or
print((A == 10) + 1) # implizite Konvertierung: False → 0, True → 1
print(isinstance(A, (int, float))) # ist A vom Typ int oder float? wichtig um Überladung nachbilden zu können
```
%% Cell type:code id: tags:
```
a = 'Hello'
b = "world"
print(a, b) # print gibt mehrere Argumente mit Leerzeichen getrennt aus
c = """Hello,
you are my "world"!"""
print(c)
c = 'Hello,\nyou are my "world"!'
print(c)
```
%% Cell type:code id: tags:
```
a = 'Hello,' + ' world' # Leerzeichen zwischen Komma und world im String
print(a)
print(a + str(123))
print(len('vier'))
print(a.replace('ello', 'i'))
print(a.lower())
print(a.endswith('.png'))
```
%% Cell type:code id: tags:
```
b = 'Beispiel'
print(b[7], b[2], b[6], b[3])
f = 'logo.pdf'
print(f[-3] + f[-2] + f[-1])
# f[0] = 'L' # TypeError
```
%% Cell type:code id: tags:
```
f = 'logo.pdf'
print(f[0:4])
print(f[:-4], f[-3:])
print(f[0:6:2])
print(f[::2])
```
%% Cell type:code id: tags:
```
path = '../images/logo.pdf'
file_pos = path.rfind('/') + 1
print(file_pos)
dir = path[:file_pos]
file = path[file_pos:]
print('dir:', dir, ' file:', file)
```
%% Cell type:code id: tags:
```
print(8 + 4)
print(8, 4)
print(8); print(4)
print(8, 4, 2, sep=' > ', end=' (richtige Aussage)\n\n')
```
%% Cell type:code id: tags:
```
print('Hi {}!'.format(5)) # formatierte(r) String / Ausgabe
print('{0} {1} {0}!'.format('First', 'Things')) # {n} referenziert Parameter n
print('named: {test}!'.format(test=42)) # {varname} definiert Namen
print('significant digits: {:.2}'.format(20/3)) # {...:.2} 2 signifikante Stellen
print('Fill: {:04}'.format(3)) # {...:0s} reserviert s Zeichen und füllt mit 0
print('Fixed point: {:.2f}'.format(3)) # {...:f} gibt Zahl als fixed point aus
```
%% Cell type:code id: tags:
```
print(f'Explicit: {3:.2f}') # f'\{var:...\}' ersetzt '{:...}'.format(var)
print('old style: %d %.2f' % (2, 3)) # formatierte(r) String / Ausgabe
print('bad style: %d %d' % (2.3, 3.8)) # Typspezifizierer könnten falsch sein! ⚡
ip = '127.0.0.1'
port = 8888
# port = '8888' # ergibt Fehler beim alten Formatierungsstil.
server = ip + ':%d' % port # Wurde port vielleicht als String gegeben? ⚡
print(server)
server = f'{ip}:{port}' # Besser! Funktioniert mit strings und ints 👍
print(server)
```
%% Cell type:code id: tags:
```
if A > 10:
print('too big')
elif A > 5: # es kann mehrere elif-Zweige geben
print('correct')
else:
print('too small')
print()
if 's' in 'Hellas':
print('It is')
```
%% Cell type:code id: tags:
```
for c in 'bla':
print('Buchstabe:', c)
print()
for i in range(3):
print('It:', i)
print()
for i, c in enumerate('bla'):
print('It:', i, 'Buchstabe:', c)
print()
for c, s in zip('ABC', 'abc'):
print(c + s)
```
%% Cell type:code id: tags:
```
for c in 'AKIS':
if c == 'I':
break
print(c)
print()
for c in 'AKIS':
if c == 'I':
continue
print(c)
print()
while True:
prompt = input('> ')
if prompt == 'exit':
break
print(prompt)
```
%% Cell type:code id: tags:
```
def greet(name):
print('Hello', name)
greet('and goodbye!') # Ausgabe: Hello and goodbye!
def greet(name='my sunshine!'):
print('Hello', name)
greet() # Ausgabe: Hello my sunshine!
greet('you') # Ausgabe: Hello you
```
%% Cell type:code id: tags:
```
def f(x, y):
return x**2 - y**2
print(f(1, 2))
print(f(y=2, x=1)) # Reihenfolge ist egal
def f(x=0, y=0):
return x**2 - y**2
print(f(y=2)) # x=0, y=2
```
%% Cell type:code id: tags:
```
import math
def pq_formel(p, q):
x1 = -p / 2 + math.sqrt(p**2 / 4 - q)
x2 = -p / 2 - math.sqrt(p**2 / 4 - q)
return x1, x2
lsg1, lsg2 = pq_formel(2, 0) # Ausgabe:
print('Lösungen:') # Lösungen:
print('x1 =', lsg1) # x1 = 0.0
print('x2 =', lsg2) # x2 = -2.0
```
%% Cell type:code id: tags:
```
liste = [1, 'text', 1/3] # Listenelemente können verschiede Typen haben
liste[0] = 2 # Listen sind veränderbar
liste.append(42) # Listen sind erweiterbar
print(liste)
liste = ['tag', 'monat', 'jahr']
print(liste.index('monat')) # Stelle bzw. Index des Elements 'monat'
liste = [1, 2, 3] * 2 # Ergibt: liste = [1, 2, 3, 1, 2, 3]
print(liste)
```
%% Cell type:code id: tags:
```
t = (3, 'text') # Tupel-Elemente können auch verschiedene Typen haben
print(t[1]) # Lesen geht
# t[1] = 5 # Schreiben nicht (TypeError)
print((3, 4) + (6, 8)) # Ergibt: (3, 4, 6, 8)
c, d = 5, 7 # c ist 5 und d ist 7 (``unpacking''), 5, 7 ist hier ein Tupel
print(c, d)
```
%% Cell type:code id: tags:
```
s = {11, 7, 3, 13, 2, 6} # #*set* wird definiert mit #*\{...\}*
print(s)
print(s & set(range(4,10))) # Schnittmenge
print(s | set(range(4,10))) # Vereinigungsmenge
print(s - set(range(4,10))) # Differenzmenge
print(s ^ set(range(4,10))) # sym. Differenzmenge (XOR)
```
%% Cell type:code id: tags:
```
tele = {'alice': 213, 'bob': 558} # Dictionary: Zuordnung von Keys zu Values
print(tele['bob'])
tele['charlie'] = 666 # Einträge können hinzugefügt oder verändert werden
print(tele)
d = {42: [1, 2, 3], 2.4: 31, 'valid': True}
print(d) # Reihenfolge bleibt erhalten
```
%% Cell type:code id: tags:
```
for name in tele.keys():
print(name)
print()
for nummer in tele.values():
print(nummer)
print()
for name, nummer in tele.items():
print(name, ': ', nummer, sep='')
print()
```
%% Cell type:code id: tags:
```
squares = [i ** 2 for i in range(-4, 5)]
print(squares)
squares = []
for i in range(-4, 5):
squares.append(i ** 2)
print(squares)
squares = [i ** 2 for i in range(-4, 5) if i % 2 == 0]
print(squares)
squares = []
for i in range(-4, 5):
if i % 2 == 0:
squares.append(i ** 2)
print(squares)
unique_squares = {i ** 2 for i in range(-4, 5) if i % 2 == 0}
print(unique_squares)
```
%% Cell type:code id: tags:
```
print({word: len(word) for word in ('hey', 'world')})
names = ['Alice', 'Bob', 'Charlie', 'David']
numbers = [333, 558, 666, 696]
tele = {name: no for name, no in zip(names, numbers)}
print(tele)
backward_search = {no: name for name, no in tele.items()}
print(backward_search[666])
```
# %% [markdown]
# # Code zu Folien
#
# Dieses Skript bzw. Jupyter-Notebook enthält den Code, der auch auf den Folien "Python Grundlagen" enthalten ist. Zum Vorbereiten, Mitmachen oder Nacharbeiten.
# %% Variablen
a = 10 # Datentypen werden implizit bestimmt
print(type(a)) # type() gibt den Typ aus
A = 20 / 2 # Groß- / Kleinschreibung wird unterschieden
print(type(A))
print(a ** 2, 7 // 2) # ∗∗ ist der Potenzoperator, // steht für floor Division
# %% Boolesche Operationen
print(A == 10) # Vergleichsoperatoren: <, <=, >, >=, ==, !=
print(A == 10 and a == 10) # Verknüpfungsoperatoren: not, and, or
print((A == 10) + 1) # implizite Konvertierung: False → 0, True → 1
print(isinstance(A, (int, float))) # ist A vom Typ int oder float? wichtig um Überladung nachbilden zu können
# %% Strings erstellen
a = 'Hello'
b = "world"
print(a, b) # print gibt mehrere Argumente mit Leerzeichen getrennt aus
c = """Hello,
you are my "world"!"""
print(c)
c = 'Hello,\nyou are my "world"!'
print(c)
# %% Stringkonkatenation und Methoden
a = 'Hello,' + ' world' # Leerzeichen zwischen Komma und world im String
print(a)
print(a + str(123))
print(len('vier'))
print(a.replace('ello', 'i'))
print(a.lower())
print(a.endswith('.png'))
# %% Indizierung von Strings
b = 'Beispiel'
print(b[7], b[2], b[6], b[3])
f = 'logo.pdf'
print(f[-3] + f[-2] + f[-1])
# f[0] = 'L' # TypeError
# %% Slicing von Strings
f = 'logo.pdf'
print(f[0:4])
print(f[:-4], f[-3:])
print(f[0:6:2])
print(f[::2])
# %% Beispiel für Slicing
path = '../images/logo.pdf'
file_pos = path.rfind('/') + 1
print(file_pos)
dir = path[:file_pos]
file = path[file_pos:]
print('dir:', dir, ' file:', file)
# %% Ausgabe mit der print-Funktion
print(8 + 4)
print(8, 4)
print(8); print(4)
print(8, 4, 2, sep=' > ', end=' (richtige Aussage)\n\n')
# %% Formatierung
print('Hi {}!'.format(5)) # formatierte(r) String / Ausgabe
print('{0} {1} {0}!'.format('First', 'Things')) # {n} referenziert Parameter n
print('named: {test}!'.format(test=42)) # {varname} definiert Namen
print('significant digits: {:.2}'.format(20/3)) # {...:.2} 2 signifikante Stellen
print('Fill: {:04}'.format(3)) # {...:0s} reserviert s Zeichen und füllt mit 0
print('Fixed point: {:.2f}'.format(3)) # {...:f} gibt Zahl als fixed point aus
# %% f-Strings und alter Formatierungsstil
print(f'Explicit: {3:.2f}') # f'\{var:...\}' ersetzt '{:...}'.format(var)
print('old style: %d %.2f' % (2, 3)) # formatierte(r) String / Ausgabe
print('bad style: %d %d' % (2.3, 3.8)) # Typspezifizierer könnten falsch sein! ⚡
ip = '127.0.0.1'
port = 8888
# port = '8888' # ergibt Fehler beim alten Formatierungsstil.
server = ip + ':%d' % port # Wurde port vielleicht als String gegeben? ⚡
print(server)
server = f'{ip}:{port}' # Besser! Funktioniert mit strings und ints 👍
print(server)
# %% Verzweigung
if A > 10:
print('too big')
elif A > 5: # es kann mehrere elif-Zweige geben
print('correct')
else:
print('too small')
print()
if 's' in 'Hellas':
print('It is')
# %% for-Schleifen
for c in 'bla':
print('Buchstabe:', c)
print()
for i in range(3):
print('It:', i)
print()
for i, c in enumerate('bla'):
print('It:', i, 'Buchstabe:', c)
print()
for c, s in zip('ABC', 'abc'):
print(c + s)
# %% break und continue und while-Schleifen
for c in 'AKIS':
if c == 'I':
break
print(c)
print()
for c in 'AKIS':
if c == 'I':
continue
print(c)
print()
while True:
prompt = input('> ')
if prompt == 'exit':
break
print(prompt)
# %% Funktionen definieren und aufrufen
def greet(name):
print('Hello', name)
greet('and goodbye!') # Ausgabe: Hello and goodbye!
def greet(name='my sunshine!'):
print('Hello', name)
greet() # Ausgabe: Hello my sunshine!
greet('you') # Ausgabe: Hello you
# %% Rückgabewerte und benannte Argumente
def f(x, y):
return x**2 - y**2
print(f(1, 2))
print(f(y=2, x=1)) # Reihenfolge ist egal
def f(x=0, y=0):
return x**2 - y**2
print(f(y=2)) # x=0, y=2
# %% Mehrere Rückgabewerte
import math
def pq_formel(p, q):
x1 = -p / 2 + math.sqrt(p**2 / 4 - q)
x2 = -p / 2 - math.sqrt(p**2 / 4 - q)
return x1, x2
lsg1, lsg2 = pq_formel(2, 0) # Ausgabe:
print('Lösungen:') # Lösungen:
print('x1 =', lsg1) # x1 = 0.0
print('x2 =', lsg2) # x2 = -2.0
# %% Listen
liste = [1, 'text', 1/3] # Listenelemente können verschiede Typen haben
liste[0] = 2 # Listen sind veränderbar
liste.append(42) # Listen sind erweiterbar
print(liste)
liste = ['tag', 'monat', 'jahr']
print(liste.index('monat')) # Stelle bzw. Index des Elements 'monat'
liste = [1, 2, 3] * 2 # Ergibt: liste = [1, 2, 3, 1, 2, 3]
print(liste)
# %% Tupel
t = (3, 'text') # Tupel-Elemente können auch verschiedene Typen haben
print(t[1]) # Lesen geht
# t[1] = 5 # Schreiben nicht (TypeError)
print((3, 4) + (6, 8)) # Ergibt: (3, 4, 6, 8)
c, d = 5, 7 # c ist 5 und d ist 7 (``unpacking''), 5, 7 ist hier ein Tupel
print(c, d)
# %% Mengen
s = {11, 7, 3, 13, 2, 6} # #*set* wird definiert mit #*\{...\}*
print(s)
print(s & set(range(4,10))) # Schnittmenge
print(s | set(range(4,10))) # Vereinigungsmenge
print(s - set(range(4,10))) # Differenzmenge
print(s ^ set(range(4,10))) # sym. Differenzmenge (XOR)
# %% Dictionaries
tele = {'alice': 213, 'bob': 558} # Dictionary: Zuordnung von Keys zu Values
print(tele['bob'])
tele['charlie'] = 666 # Einträge können hinzugefügt oder verändert werden
print(tele)
d = {42: [1, 2, 3], 2.4: 31, 'valid': True}
print(d) # Reihenfolge bleibt erhalten
# %% Schleifen über Dictionaries
for name in tele.keys():
print(name)
print()
for nummer in tele.values():
print(nummer)
print()
for name, nummer in tele.items():
print(name, ': ', nummer, sep='')
print()
# %% List und Set Comprehension
squares = [i ** 2 for i in range(-4, 5)]
print(squares)
squares = []
for i in range(-4, 5):
squares.append(i ** 2)
print(squares)
squares = [i ** 2 for i in range(-4, 5) if i % 2 == 0]
print(squares)
squares = []
for i in range(-4, 5):
if i % 2 == 0:
squares.append(i ** 2)
print(squares)
unique_squares = {i ** 2 for i in range(-4, 5) if i % 2 == 0}
print(unique_squares)
# %% Dictionary Comprehension
print({word: len(word) for word in ('hey', 'world')})
names = ['Alice', 'Bob', 'Charlie', 'David']
numbers = [333, 558, 666, 696]
tele = {name: no for name, no in zip(names, numbers)}
print(tele)
backward_search = {no: name for name, no in tele.items()}
print(backward_search[666])
This diff is collapsed.
This diff is collapsed.
03-numpy-und-matplotlib/zwinkersmiley.bmp

1.32 KiB

%% Cell type:markdown id:0001-d947a237f8749d5a07e6b16afc9277567861c9725260e81c2bffa0ec68d tags: %% Cell type:markdown id:0003-7f7af66911fa1dbbd53a09cf8eb63d7bbae02ca052ea151d8b799a02d83 tags:
# MNIST visualisieren # MNIST visualisieren
In dieser Aufgabe wollen wir einen hochdimensionalen Datensatz in 2D In dieser Aufgabe wollen wir einen hochdimensionalen Datensatz in 2D
(oder 3D) plotten. Die Daten werden schon geladen und eine (oder 3D) plotten. Die Daten werden schon geladen und eine
Plotting-Funktion ist schon vorbereitet. *Hinweis: Der Code benötigt Plotting-Funktion ist schon vorbereitet.
einen Jupyter-Kontext, also Jupyter Lab oder VS Code mit interaktivem
Modus.*
%% Cell type:code id:0002-bbdfcc807a677cb51c1861eff7e69e8889bcc9c56d11ca63b972d0d11c7 tags: *Hinweis: Sie benötigen `bokeh`, was Sie einfach mit
`mamba install bokeh` installieren können.*
*Hinweis: Der vorbereitete Code benötigt aktuell einen Jupyter-Kontext,
also Jupyter Lab oder VS Code mit interaktivem Modus. Wenn Sie den Code
im Script-Modus nutzen wollen, müssen Sie den Code oder mit dem
auskommentierten Code, der mit `bokeh.plotting.output_file` anfängt,
dekommentieren.*
%% Cell type:code id:0004-5dcaf1cd1786238c4749189d6237574dbb5addb57128548dbe84d900608 tags:
``` ```
import base64
import io import io
import matplotlib.pyplot as plt import os
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import PIL
import plotly.express as px import plotly.express as px
from plotly import graph_objects as go from keras.datasets.mnist import load_data
from ipywidgets import VBox, Box, Image, Layout import bokeh
from tensorflow.keras.datasets.mnist import load_data import bokeh.plotting
import bokeh.models
import bokeh.palettes
title = 'MNIST 2D'
# either INTERACTIVE MODE: directly show in interactive window / notebook
bokeh.plotting.output_notebook()
# or SCRIPT MODE: output to file and open in browser
# filename = os.path.join('images', 'mnist2d.html')
# bokeh.plotting.output_file(filename=filename, title=title)
def img_to_base64(img_array):
assert np.issubdtype(img_array.dtype, 'uint8'), 'Pillow expects an image array to have uint8 format'
img = PIL.Image.fromarray(img_array.squeeze())
buffer = io.BytesIO()
img.save(buffer, format='WebP')
return 'data:image/webp;base64,' + base64.b64encode(buffer.getvalue()).decode()
def interactive_scatter_plot(X_high, X_low, y): def interactive_scatter_plot(X_high, X_low, y_int):
""" """
Make a scatter plot reacting on hover by showing the image Make a scatter plot reacting on hover by showing the image
""" """
assert X_high.shape[0] == X_low.shape[0] == y.shape[0], 'Arrays should have the same number of samples' assert X_high.ndim >= 3, 'Original images should be shaped as images e. g. (n_samples, height, width)'
assert X_high.shape[1] > X_low.shape[1], 'First array should bei original images, second with reduced dimension' assert X_low.ndim == 2, 'Reduced dimension should be 2D (n_samples, n_components)'
assert X_high.shape[0] == X_low.shape[0] == y_int.shape[0], 'Arrays should have the same number of samples'
x_name, y_name = 0, 1 if not isinstance(X_low, pd.DataFrame) else X_low.columns[:2] assert np.prod(X_high.shape[1:]) > X_low.shape[1], 'First array should be original images, second with reduced dimension'
scatter = px.scatter(X_low, x=x_name, y=y_name, color=y, hover_data={'idx': np.arange(len(X_low))})
scatter.update_xaxes(title_text=None) if not isinstance(X_low, pd.DataFrame):
scatter.update_yaxes(title_text=None) X_low = pd.DataFrame(X_low, columns=['x', 'y'])
X_low['class'] = y_int.astype(str)
# show image on hover X_low['image'] = [img_to_base64(x) for x in X_high]
img = Image(format='png', width=56)
def update(trace, points, state): datasource = bokeh.models.ColumnDataSource(X_low)
# index relative to this trace (trace = color group) color_mapping = bokeh.models.CategoricalColorMapper(
trace_index = points.point_inds factors=np.unique(X_low['class']),
if len(trace_index) == 0: palette=bokeh.palettes.Spectral[X_low['class'].nunique()]
# this returns for traces not having the data point )
return
plot_figure = bokeh.plotting.figure(
# absolute indices of this trace title=title,
digit_indices = trace['customdata'] width=1000,
data_index = digit_indices[trace_index] height=1000,
tools=('pan, wheel_zoom, reset, zoom_in')
# convert image to PNG bytes and set image to it )
rawBytes = io.BytesIO()
plt.imsave(rawBytes, X_high[data_index].reshape((28, 28)), format='png', cmap='gray') plot_figure.add_tools(bokeh.models.HoverTool(tooltips="""
rawBytes.seek(0) <div>
img.value = rawBytes.read() <div>
<img src='@image' width='96' style='float: left; margin: 5px 5px 5px 5px'/>
fig = go.FigureWidget(data=scatter.data, layout=scatter.layout) </div>
<div>
# figure contains for each color a data trace and for each we have to define the on_hover function <span style='font-size: 16px; color: #224499'>Class:</span>
for fig_data in fig.data: <span style='font-size: 18px'>@class</span>
fig_data.on_hover(update) </div>
</div>
# layout of plot and centered image """))
return VBox([fig, Box([img], layout=Layout(display='flex', flex_flow='column', align_items='center'))])
plot_figure.scatter(
'x',
'y',
source=datasource,
color=dict(field='class', transform=color_mapping),
line_alpha=0.6,
fill_alpha=0.6,
size=4
)
return plot_figure
# load data # load data
(x_train, y_train), (x_test, y_test) = load_data() (X_train, y_train_int), (X_test, y_test_int) = load_data()
# reshape test set to 10 000 x 784 # reshape test set to 10 000 x 784
X = x_test.reshape(-1, 28 * 28) X = X_test.reshape(-1, 28 * 28)
``` ```
%% Cell type:markdown id:0003-8683c8202e9f2668b92e0aa78e49a38198e4d638b65ac30ec6020531315 tags: %% Cell type:markdown id:0005-8683c8202e9f2668b92e0aa78e49a38198e4d638b65ac30ec6020531315 tags:
Wenn Sie mögen ist hier ein Plot von verschiedenen Bildern der gleichen Wenn Sie mögen ist hier ein Plot von verschiedenen Bildern der gleichen
Klasse. So können Sie ein Blick in den Datensatz werfen. Klasse. So können Sie ein Blick in den Datensatz werfen.
%% Cell type:code id:0004-c879d58b500c83a0364d8680cc6b05c9cc97d36d3ea3743e112c56644db tags: %% Cell type:code id:0006-55d5e2344dc9d02ca2bfa1b0c375229ad58016396aa7d7cf5a61050d2d3 tags:
``` ```
# plot 50 examples for each digit # plot 50 examples for each digit
imgs = np.empty((50, 10, 28, 28)) imgs = np.empty((50, 10, 28, 28))
for j in range(10): for j in range(10):
imgs[:, j] = x_test[y_test == j][:50] imgs[:, j] = X_test[y_test_int == j][:50]
fig = px.imshow(imgs, animation_frame=0, facet_col=1, facet_col_wrap=5, binary_string=True) fig = px.imshow(imgs, animation_frame=0, facet_col=1, facet_col_wrap=5, binary_string=True)
fig.update_xaxes(showticklabels=False) fig.update_xaxes(showticklabels=False)
fig.update_yaxes(showticklabels=False) fig.update_yaxes(showticklabels=False)
fig.show() fig.show()
``` ```
%% Cell type:markdown id:0006-80f9722cacf3b6426928b4bbdb5fcb32d9d50cc0aaccb011c37c93b7f19 tags: %% Cell type:markdown id:0008-a567fb8b0d99e19468231f138dc3f8c24df37b96f4a7e1ef8fee53d2cd8 tags:
Transformieren Sie die Daten in 2D (ode 3D) und plotten die Transformieren Sie die Daten in 2D (oder 3D) und plotten die
Transformierten Daten als Scatter-Plot mit `y_test` als transformierten Daten als Scatter-Plot mit `y_test_int` als
Farbunterscheidung. Für PCA ist es schon vorbereitet, aber probieren Sie Farbunterscheidung. Für PCA ist es schon vorbereitet, aber probieren Sie
auch andere Techniken. auch andere Techniken.
*Hinweis: Falls Sie UMAP verwenden wollen und es nicht installiert ist, *Hinweis: Falls Sie UMAP verwenden wollen und es nicht installiert ist,
installieren Sie es mit `mamba install umap-learn`. Sie können es dann installieren Sie es mit `mamba install umap-learn`. Sie können es dann
mit `from umap import UMAP` importieren und wie jedes andere mit `from umap import UMAP` importieren und wie jedes andere
Scikit-Learn-Modell verwenden.* Scikit-Learn-Modell verwenden.*
%% Cell type:code id:0007-ae5f11cf01a3212244c7bf86638455d0d6a145258c3112beb4c12633405 tags: %% Cell type:code id:0009-8f4cb7ad5313b8b11707eac44fb277bcac2da77b123fc2d06542453784b tags:
``` ```
from sklearn.decomposition import PCA from sklearn.decomposition import PCA
pca = PCA(n_components=2) pca = PCA(n_components=2)
X_pca = pca.fit_transform(X) X_pca = pca.fit_transform(X)
plot = interactive_scatter_plot(X, X_pca, y_test) fig = interactive_scatter_plot(X_test, X_pca, y_test_int)
display(plot) # display from IPython.display implicitly in Jupyter imported, which is required anyway bokeh.plotting.show(fig)
``` ```
%% Cell type:markdown id:0009-96b725bb9f2f51ff66328e5e9a5fc2dd4e69320f643fa34ea6db4da4c4a tags: %% Cell type:markdown id:0011-2ea29f1d1ac0466469de63febbc098721eca721cd7a2798db189d242db7 tags:
## Lösung ## Lösung
Hier der Code für UMAP: Hier der Code für UMAP (Ausführung dauert etwas länger, ca. 1 min):
%% Cell type:code id:0010-7e298e46cd6eb14f0920a2bed338fa02b756553adb499afb357944d32ae tags: %% Cell type:code id:0012-45ec0cf146b8998fa17e4fe7c5ae1bacbf4ab8c523e43e32e1233c63ecb tags:
``` ```
from umap import UMAP from umap import UMAP
umap = UMAP(n_neighbors=20, metric='manhattan', min_dist=0.1) umap = UMAP(n_neighbors=20, metric='manhattan', min_dist=0.1)
X_umap = umap.fit_transform(X) X_umap = umap.fit_transform(X)
plot = interactive_scatter_plot(X, X_umap, y_test) fig = interactive_scatter_plot(X_test, X_umap, y_test_int)
display(plot) # display from IPython.display implicitly in Jupyter imported, which is required anyway bokeh.plotting.show(fig)
``` ```
......
%% Cell type:markdown id:0001-d947a237f8749d5a07e6b16afc9277567861c9725260e81c2bffa0ec68d tags: %% Cell type:markdown id:0003-7f7af66911fa1dbbd53a09cf8eb63d7bbae02ca052ea151d8b799a02d83 tags:
# MNIST visualisieren # MNIST visualisieren
In dieser Aufgabe wollen wir einen hochdimensionalen Datensatz in 2D In dieser Aufgabe wollen wir einen hochdimensionalen Datensatz in 2D
(oder 3D) plotten. Die Daten werden schon geladen und eine (oder 3D) plotten. Die Daten werden schon geladen und eine
Plotting-Funktion ist schon vorbereitet. *Hinweis: Der Code benötigt Plotting-Funktion ist schon vorbereitet.
einen Jupyter-Kontext, also Jupyter Lab oder VS Code mit interaktivem
Modus.*
%% Cell type:code id:0002-bbdfcc807a677cb51c1861eff7e69e8889bcc9c56d11ca63b972d0d11c7 tags: *Hinweis: Sie benötigen `bokeh`, was Sie einfach mit
`mamba install bokeh` installieren können.*
*Hinweis: Der vorbereitete Code benötigt aktuell einen Jupyter-Kontext,
also Jupyter Lab oder VS Code mit interaktivem Modus. Wenn Sie den Code
im Script-Modus nutzen wollen, müssen Sie den Code oder mit dem
auskommentierten Code, der mit `bokeh.plotting.output_file` anfängt,
dekommentieren.*
%% Cell type:code id:0004-5dcaf1cd1786238c4749189d6237574dbb5addb57128548dbe84d900608 tags:
``` ```
import base64
import io import io
import matplotlib.pyplot as plt import os
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import PIL
import plotly.express as px import plotly.express as px
from plotly import graph_objects as go from keras.datasets.mnist import load_data
from ipywidgets import VBox, Box, Image, Layout import bokeh
from tensorflow.keras.datasets.mnist import load_data import bokeh.plotting
import bokeh.models
import bokeh.palettes
title = 'MNIST 2D'
# either INTERACTIVE MODE: directly show in interactive window / notebook
bokeh.plotting.output_notebook()
# or SCRIPT MODE: output to file and open in browser
# filename = os.path.join('images', 'mnist2d.html')
# bokeh.plotting.output_file(filename=filename, title=title)
def img_to_base64(img_array):
assert np.issubdtype(img_array.dtype, 'uint8'), 'Pillow expects an image array to have uint8 format'
img = PIL.Image.fromarray(img_array.squeeze())
buffer = io.BytesIO()
img.save(buffer, format='WebP')
return 'data:image/webp;base64,' + base64.b64encode(buffer.getvalue()).decode()
def interactive_scatter_plot(X_high, X_low, y): def interactive_scatter_plot(X_high, X_low, y_int):
""" """
Make a scatter plot reacting on hover by showing the image Make a scatter plot reacting on hover by showing the image
""" """
assert X_high.shape[0] == X_low.shape[0] == y.shape[0], 'Arrays should have the same number of samples' assert X_high.ndim >= 3, 'Original images should be shaped as images e. g. (n_samples, height, width)'
assert X_high.shape[1] > X_low.shape[1], 'First array should bei original images, second with reduced dimension' assert X_low.ndim == 2, 'Reduced dimension should be 2D (n_samples, n_components)'
assert X_high.shape[0] == X_low.shape[0] == y_int.shape[0], 'Arrays should have the same number of samples'
x_name, y_name = 0, 1 if not isinstance(X_low, pd.DataFrame) else X_low.columns[:2] assert np.prod(X_high.shape[1:]) > X_low.shape[1], 'First array should be original images, second with reduced dimension'
scatter = px.scatter(X_low, x=x_name, y=y_name, color=y, hover_data={'idx': np.arange(len(X_low))})
scatter.update_xaxes(title_text=None) if not isinstance(X_low, pd.DataFrame):
scatter.update_yaxes(title_text=None) X_low = pd.DataFrame(X_low, columns=['x', 'y'])
X_low['class'] = y_int.astype(str)
# show image on hover X_low['image'] = [img_to_base64(x) for x in X_high]
img = Image(format='png', width=56)
def update(trace, points, state): datasource = bokeh.models.ColumnDataSource(X_low)
# index relative to this trace (trace = color group) color_mapping = bokeh.models.CategoricalColorMapper(
trace_index = points.point_inds factors=np.unique(X_low['class']),
if len(trace_index) == 0: palette=bokeh.palettes.Spectral[X_low['class'].nunique()]
# this returns for traces not having the data point )
return
plot_figure = bokeh.plotting.figure(
# absolute indices of this trace title=title,
digit_indices = trace['customdata'] width=1000,
data_index = digit_indices[trace_index] height=1000,
tools=('pan, wheel_zoom, reset, zoom_in')
# convert image to PNG bytes and set image to it )
rawBytes = io.BytesIO()
plt.imsave(rawBytes, X_high[data_index].reshape((28, 28)), format='png', cmap='gray') plot_figure.add_tools(bokeh.models.HoverTool(tooltips="""
rawBytes.seek(0) <div>
img.value = rawBytes.read() <div>
<img src='@image' width='96' style='float: left; margin: 5px 5px 5px 5px'/>
fig = go.FigureWidget(data=scatter.data, layout=scatter.layout) </div>
<div>
# figure contains for each color a data trace and for each we have to define the on_hover function <span style='font-size: 16px; color: #224499'>Class:</span>
for fig_data in fig.data: <span style='font-size: 18px'>@class</span>
fig_data.on_hover(update) </div>
</div>
# layout of plot and centered image """))
return VBox([fig, Box([img], layout=Layout(display='flex', flex_flow='column', align_items='center'))])
plot_figure.scatter(
'x',
'y',
source=datasource,
color=dict(field='class', transform=color_mapping),
line_alpha=0.6,
fill_alpha=0.6,
size=4
)
return plot_figure
# load data # load data
(x_train, y_train), (x_test, y_test) = load_data() (X_train, y_train_int), (X_test, y_test_int) = load_data()
# reshape test set to 10 000 x 784 # reshape test set to 10 000 x 784
X = x_test.reshape(-1, 28 * 28) X = X_test.reshape(-1, 28 * 28)
``` ```
%% Cell type:markdown id:0003-8683c8202e9f2668b92e0aa78e49a38198e4d638b65ac30ec6020531315 tags: %% Cell type:markdown id:0005-8683c8202e9f2668b92e0aa78e49a38198e4d638b65ac30ec6020531315 tags:
Wenn Sie mögen ist hier ein Plot von verschiedenen Bildern der gleichen Wenn Sie mögen ist hier ein Plot von verschiedenen Bildern der gleichen
Klasse. So können Sie ein Blick in den Datensatz werfen. Klasse. So können Sie ein Blick in den Datensatz werfen.
%% Cell type:code id:0004-c879d58b500c83a0364d8680cc6b05c9cc97d36d3ea3743e112c56644db tags: %% Cell type:code id:0006-55d5e2344dc9d02ca2bfa1b0c375229ad58016396aa7d7cf5a61050d2d3 tags:
``` ```
# plot 50 examples for each digit # plot 50 examples for each digit
imgs = np.empty((50, 10, 28, 28)) imgs = np.empty((50, 10, 28, 28))
for j in range(10): for j in range(10):
imgs[:, j] = x_test[y_test == j][:50] imgs[:, j] = X_test[y_test_int == j][:50]
fig = px.imshow(imgs, animation_frame=0, facet_col=1, facet_col_wrap=5, binary_string=True) fig = px.imshow(imgs, animation_frame=0, facet_col=1, facet_col_wrap=5, binary_string=True)
fig.update_xaxes(showticklabels=False) fig.update_xaxes(showticklabels=False)
fig.update_yaxes(showticklabels=False) fig.update_yaxes(showticklabels=False)
fig.show() fig.show()
``` ```
%% Cell type:markdown id:0006-80f9722cacf3b6426928b4bbdb5fcb32d9d50cc0aaccb011c37c93b7f19 tags: %% Cell type:markdown id:0008-a567fb8b0d99e19468231f138dc3f8c24df37b96f4a7e1ef8fee53d2cd8 tags:
Transformieren Sie die Daten in 2D (ode 3D) und plotten die Transformieren Sie die Daten in 2D (oder 3D) und plotten die
Transformierten Daten als Scatter-Plot mit `y_test` als transformierten Daten als Scatter-Plot mit `y_test_int` als
Farbunterscheidung. Für PCA ist es schon vorbereitet, aber probieren Sie Farbunterscheidung. Für PCA ist es schon vorbereitet, aber probieren Sie
auch andere Techniken. auch andere Techniken.
*Hinweis: Falls Sie UMAP verwenden wollen und es nicht installiert ist, *Hinweis: Falls Sie UMAP verwenden wollen und es nicht installiert ist,
installieren Sie es mit `mamba install umap-learn`. Sie können es dann installieren Sie es mit `mamba install umap-learn`. Sie können es dann
mit `from umap import UMAP` importieren und wie jedes andere mit `from umap import UMAP` importieren und wie jedes andere
Scikit-Learn-Modell verwenden.* Scikit-Learn-Modell verwenden.*
%% Cell type:code id:0007-ae5f11cf01a3212244c7bf86638455d0d6a145258c3112beb4c12633405 tags: %% Cell type:code id:0009-8f4cb7ad5313b8b11707eac44fb277bcac2da77b123fc2d06542453784b tags:
``` ```
from sklearn.decomposition import PCA from sklearn.decomposition import PCA
pca = PCA(n_components=2) pca = PCA(n_components=2)
X_pca = pca.fit_transform(X) X_pca = pca.fit_transform(X)
plot = interactive_scatter_plot(X, X_pca, y_test) fig = interactive_scatter_plot(X_test, X_pca, y_test_int)
display(plot) # display from IPython.display implicitly in Jupyter imported, which is required anyway bokeh.plotting.show(fig)
``` ```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment