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
In dieser Aufgabe wollen wir einen hochdimensionalen Datensatz in 2D
(oder 3D) plotten. Die Daten werden schon geladen und eine
Plotting-Funktion ist schon vorbereitet. *Hinweis: Der Code benötigt
einen Jupyter-Kontext, also Jupyter Lab oder VS Code mit interaktivem
Modus.*
Plotting-Funktion ist schon vorbereitet.
%% 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 matplotlib.pyplot as plt
import os
import numpy as np
import pandas as pd
import PIL
import plotly.express as px
from plotly import graph_objects as go
from ipywidgets import VBox, Box, Image, Layout
from tensorflow.keras.datasets.mnist import load_data
from keras.datasets.mnist import load_data
import bokeh
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
"""
assert X_high.shape[0] == X_low.shape[0] == y.shape[0], 'Arrays should have the same number of samples'
assert X_high.shape[1] > X_low.shape[1], 'First array should bei original images, second with reduced dimension'
x_name, y_name = 0, 1 if not isinstance(X_low, pd.DataFrame) else X_low.columns[:2]
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)
scatter.update_yaxes(title_text=None)
# show image on hover
img = Image(format='png', width=56)
def update(trace, points, state):
# index relative to this trace (trace = color group)
trace_index = points.point_inds
if len(trace_index) == 0:
# this returns for traces not having the data point
return
# absolute indices of this trace
digit_indices = trace['customdata']
data_index = digit_indices[trace_index]
# 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')
rawBytes.seek(0)
img.value = rawBytes.read()
fig = go.FigureWidget(data=scatter.data, layout=scatter.layout)
# figure contains for each color a data trace and for each we have to define the on_hover function
for fig_data in fig.data:
fig_data.on_hover(update)
# layout of plot and centered image
return VBox([fig, Box([img], layout=Layout(display='flex', flex_flow='column', align_items='center'))])
assert X_high.ndim >= 3, 'Original images should be shaped as images e. g. (n_samples, height, width)'
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'
assert np.prod(X_high.shape[1:]) > X_low.shape[1], 'First array should be original images, second with reduced dimension'
if not isinstance(X_low, pd.DataFrame):
X_low = pd.DataFrame(X_low, columns=['x', 'y'])
X_low['class'] = y_int.astype(str)
X_low['image'] = [img_to_base64(x) for x in X_high]
datasource = bokeh.models.ColumnDataSource(X_low)
color_mapping = bokeh.models.CategoricalColorMapper(
factors=np.unique(X_low['class']),
palette=bokeh.palettes.Spectral[X_low['class'].nunique()]
)
plot_figure = bokeh.plotting.figure(
title=title,
width=1000,
height=1000,
tools=('pan, wheel_zoom, reset, zoom_in')
)
plot_figure.add_tools(bokeh.models.HoverTool(tooltips="""
<div>
<div>
<img src='@image' width='96' style='float: left; margin: 5px 5px 5px 5px'/>
</div>
<div>
<span style='font-size: 16px; color: #224499'>Class:</span>
<span style='font-size: 18px'>@class</span>
</div>
</div>
"""))
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
(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
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
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
imgs = np.empty((50, 10, 28, 28))
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.update_xaxes(showticklabels=False)
fig.update_yaxes(showticklabels=False)
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
Transformierten Daten als Scatter-Plot mit `y_test` als
Transformieren Sie die Daten in 2D (oder 3D) und plotten die
transformierten Daten als Scatter-Plot mit `y_test_int` als
Farbunterscheidung. Für PCA ist es schon vorbereitet, aber probieren Sie
auch andere Techniken.
*Hinweis: Falls Sie UMAP verwenden wollen und es nicht installiert ist,
installieren Sie es mit `mamba install umap-learn`. Sie können es dann
mit `from umap import UMAP` importieren und wie jedes andere
Scikit-Learn-Modell verwenden.*
%% Cell type:code id:0007-ae5f11cf01a3212244c7bf86638455d0d6a145258c3112beb4c12633405 tags:
%% Cell type:code id:0009-8f4cb7ad5313b8b11707eac44fb277bcac2da77b123fc2d06542453784b tags:
```
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
plot = interactive_scatter_plot(X, X_pca, y_test)
display(plot) # display from IPython.display implicitly in Jupyter imported, which is required anyway
fig = interactive_scatter_plot(X_test, X_pca, y_test_int)
bokeh.plotting.show(fig)
```
%% Cell type:markdown id:0009-96b725bb9f2f51ff66328e5e9a5fc2dd4e69320f643fa34ea6db4da4c4a tags:
%% Cell type:markdown id:0011-2ea29f1d1ac0466469de63febbc098721eca721cd7a2798db189d242db7 tags:
## 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
umap = UMAP(n_neighbors=20, metric='manhattan', min_dist=0.1)
X_umap = umap.fit_transform(X)
plot = interactive_scatter_plot(X, X_umap, y_test)
display(plot) # display from IPython.display implicitly in Jupyter imported, which is required anyway
fig = interactive_scatter_plot(X_test, X_umap, y_test_int)
bokeh.plotting.show(fig)
```
......
%% Cell type:markdown id:0001-d947a237f8749d5a07e6b16afc9277567861c9725260e81c2bffa0ec68d tags:
%% Cell type:markdown id:0003-7f7af66911fa1dbbd53a09cf8eb63d7bbae02ca052ea151d8b799a02d83 tags:
# MNIST visualisieren
In dieser Aufgabe wollen wir einen hochdimensionalen Datensatz in 2D
(oder 3D) plotten. Die Daten werden schon geladen und eine
Plotting-Funktion ist schon vorbereitet. *Hinweis: Der Code benötigt
einen Jupyter-Kontext, also Jupyter Lab oder VS Code mit interaktivem
Modus.*
Plotting-Funktion ist schon vorbereitet.
%% 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 matplotlib.pyplot as plt
import os
import numpy as np
import pandas as pd
import PIL
import plotly.express as px
from plotly import graph_objects as go
from ipywidgets import VBox, Box, Image, Layout
from tensorflow.keras.datasets.mnist import load_data
from keras.datasets.mnist import load_data
import bokeh
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
"""
assert X_high.shape[0] == X_low.shape[0] == y.shape[0], 'Arrays should have the same number of samples'
assert X_high.shape[1] > X_low.shape[1], 'First array should bei original images, second with reduced dimension'
x_name, y_name = 0, 1 if not isinstance(X_low, pd.DataFrame) else X_low.columns[:2]
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)
scatter.update_yaxes(title_text=None)
# show image on hover
img = Image(format='png', width=56)
def update(trace, points, state):
# index relative to this trace (trace = color group)
trace_index = points.point_inds
if len(trace_index) == 0:
# this returns for traces not having the data point
return
# absolute indices of this trace
digit_indices = trace['customdata']
data_index = digit_indices[trace_index]
# 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')
rawBytes.seek(0)
img.value = rawBytes.read()
fig = go.FigureWidget(data=scatter.data, layout=scatter.layout)
# figure contains for each color a data trace and for each we have to define the on_hover function
for fig_data in fig.data:
fig_data.on_hover(update)
# layout of plot and centered image
return VBox([fig, Box([img], layout=Layout(display='flex', flex_flow='column', align_items='center'))])
assert X_high.ndim >= 3, 'Original images should be shaped as images e. g. (n_samples, height, width)'
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'
assert np.prod(X_high.shape[1:]) > X_low.shape[1], 'First array should be original images, second with reduced dimension'
if not isinstance(X_low, pd.DataFrame):
X_low = pd.DataFrame(X_low, columns=['x', 'y'])
X_low['class'] = y_int.astype(str)
X_low['image'] = [img_to_base64(x) for x in X_high]
datasource = bokeh.models.ColumnDataSource(X_low)
color_mapping = bokeh.models.CategoricalColorMapper(
factors=np.unique(X_low['class']),
palette=bokeh.palettes.Spectral[X_low['class'].nunique()]
)
plot_figure = bokeh.plotting.figure(
title=title,
width=1000,
height=1000,
tools=('pan, wheel_zoom, reset, zoom_in')
)
plot_figure.add_tools(bokeh.models.HoverTool(tooltips="""
<div>
<div>
<img src='@image' width='96' style='float: left; margin: 5px 5px 5px 5px'/>
</div>
<div>
<span style='font-size: 16px; color: #224499'>Class:</span>
<span style='font-size: 18px'>@class</span>
</div>
</div>
"""))
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
(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
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
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
imgs = np.empty((50, 10, 28, 28))
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.update_xaxes(showticklabels=False)
fig.update_yaxes(showticklabels=False)
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
Transformierten Daten als Scatter-Plot mit `y_test` als
Transformieren Sie die Daten in 2D (oder 3D) und plotten die
transformierten Daten als Scatter-Plot mit `y_test_int` als
Farbunterscheidung. Für PCA ist es schon vorbereitet, aber probieren Sie
auch andere Techniken.
*Hinweis: Falls Sie UMAP verwenden wollen und es nicht installiert ist,
installieren Sie es mit `mamba install umap-learn`. Sie können es dann
mit `from umap import UMAP` importieren und wie jedes andere
Scikit-Learn-Modell verwenden.*
%% Cell type:code id:0007-ae5f11cf01a3212244c7bf86638455d0d6a145258c3112beb4c12633405 tags:
%% Cell type:code id:0009-8f4cb7ad5313b8b11707eac44fb277bcac2da77b123fc2d06542453784b tags:
```
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
plot = interactive_scatter_plot(X, X_pca, y_test)
display(plot) # display from IPython.display implicitly in Jupyter imported, which is required anyway
fig = interactive_scatter_plot(X_test, X_pca, y_test_int)
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