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

Notebooks from applied-cs/data-science@0b15b897

parent 07077bd8
Branches
No related tags found
No related merge requests found
%% Cell type:markdown id:0001-a3ae08f5a4a259687b176e7ee5d142ca2207e5ace1aada9d73aa8abe333 tags:
# Trägheitsmoment
Gegeben sind folgende Daten:
%% Cell type:code id:0002-c8ceb98996d092532358b219fb962ede51c887f4bbaf30a4a2a9fa39712 tags:
```
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles
X, y1 = make_circles(1000, noise=0.1, factor=0.55)
y2 = np.asarray(X[:, 0] > 0, dtype=int)
```
%% Cell type:markdown id:0003-3d78bcf9122a2a1bb3e1681a8c95f29db1a5e142a429a286e2f70f5ab28 tags:
Hier ein Plot der Daten:
%% Cell type:code id:0004-2738953bffe1a6a1bf6958471b829f9f4cf355ce4d038f06451f55017ae tags:
```
fig, axs = plt.subplots(1, 2, sharey=True)
axs[0].scatter(X[:, 0], X[:, 1], c=y1)
axs[1].scatter(X[:, 0], X[:, 1], c=y2)
axs[0].set_box_aspect(1)
axs[1].set_box_aspect(1)
axs[0].set_title('y1')
axs[0].set_title('y2')
plt.show()
```
%% Cell type:markdown id:0008-2d3d0ac1dc306d99dffc90565a9e0335c9d741efdf70aa228dc53c54c66 tags:
Dabei stellen `y1` die tatsächlich gewünschte, aber nicht konvexe
Clusterung und `y2` eine konvexe Clusterung dar. Berechnen Sie das
Gesamtträgheitsmoment. Beachten Sie dabei, dass Sie für beide
Clusterungen nicht die Formel für einen konvergierten $k$-Means
Algorithmus verwenden können. Hier Ihr Code:
## Lösung
Wir geben zwei Lösungsvorschläge an. In beiden wird jeweils das
Trägheitsmoment von `y` berechnet, was in einer äußeren `for`-Schleife
im ersten Durchlauf `y1` und im zweiten `y2` ist.
Im ersten Ansatz durchlaufen wir mit `j` die Cluster und betrachten mit
`X_j` nur die Samples, die zu Cluster `j` gehören. Damit berechnen wir
dessen Repräsentanten `mu_j` und bilden die Differenzen von `X_j` zu
deren Repräsentanten. Wenn man die Differenzen quadriert und zeilenweise
aufsummiert, erhält man die Distanzen. Wenn man die wiederrum
aufsummiert, erhält man das Trägheitsmoment für Cluster `j`. Daher kann
man auch direkt über beide Achsen summieren.
%% Cell type:code id:0009-2a402c7b8cd559ae7dcb8bb3ec30f9029fb26c37ee966558437ace37014 tags:
```
inertia_loop = []
for y in [y1, y2]:
total_inertia = 0
for j in range(max(y) + 1):
X_j = X[y == j]
mu_j = X_j.mean(axis=0)
diff = X_j - mu_j
inertia = np.sum(diff ** 2)
total_inertia += inertia
inertia_loop.append(total_inertia)
```
%% Cell type:code id:0010-312845f479b003bfe4db2fc5e3c7f7b7f42c593739d43473d785c47586a tags:
```
inertia_loop
```
%% Output
[663.5525861044789, 420.48555691708304]
%% Cell type:markdown id:0011-f01157f3b95bd8a3730718503771b0bfdc3571b74ca13b9939f17eb58ab tags:
Im zweiten Ansatz arbeiten wir ohne (innere) `for`-Schleife und
verwenden anstatt dessen `list`-Comprehensions. Zunächst berechnen wir
die Repräsentanten für alle Cluster `mu` im Prinzip analog zum ersten
Ansatz. Dann berechnen wir die quadrierte Distanzmatrix
`sqr_dist_matrix`, analog zu den Folien (nur halt ohne Wurzel).
Anschließend wählen wir per Indizierung die Abstände der Samples, die zu
Cluster `j` gehören, zu $\mu_j$ (Spalte `j`) und summieren sie auf. Das
wird in der `list`-Comprehension für jedes Cluster `j` gemacht und diese
Trägheitsmomente werden zum Gesamtträgheitsmoment `total_inertia`
aufsummiert.
%% Cell type:code id:0012-fe2cf201c04462c6164ddc58d877a6d58d84dc101e5c31b244951544183 tags:
```
inertia_comp = []
for y in [y1, y2]:
k = max(y) + 1
mu = np.array([X[y == j].mean(axis=0) for j in range(k)])
diff = X[:, np.newaxis, :] - mu[np.newaxis, :, :]
sqr_dist_matrix = np.sum(diff ** 2, axis=2)
total_inertia = sum([np.sum(sqr_dist_matrix[y == j, j]) for j in range(k)])
inertia_comp.append(total_inertia)
```
%% Cell type:code id:0013-54434e150ebc898aa6628247bbd58911180b2dd5b07d06ab7fd7306f86b tags:
```
inertia_comp
```
%% Output
[663.552586104479, 420.48555691708304]
%% Cell type:markdown id:0001-a3ae08f5a4a259687b176e7ee5d142ca2207e5ace1aada9d73aa8abe333 tags:
# Trägheitsmoment
Gegeben sind folgende Daten:
%% Cell type:code id:0002-c8ceb98996d092532358b219fb962ede51c887f4bbaf30a4a2a9fa39712 tags:
```
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles
X, y1 = make_circles(1000, noise=0.1, factor=0.55)
y2 = np.asarray(X[:, 0] > 0, dtype=int)
```
%% Cell type:markdown id:0003-3d78bcf9122a2a1bb3e1681a8c95f29db1a5e142a429a286e2f70f5ab28 tags:
Hier ein Plot der Daten:
%% Cell type:code id:0004-2738953bffe1a6a1bf6958471b829f9f4cf355ce4d038f06451f55017ae tags:
```
fig, axs = plt.subplots(1, 2, sharey=True)
axs[0].scatter(X[:, 0], X[:, 1], c=y1)
axs[1].scatter(X[:, 0], X[:, 1], c=y2)
axs[0].set_box_aspect(1)
axs[1].set_box_aspect(1)
axs[0].set_title('y1')
axs[0].set_title('y2')
plt.show()
```
%% Cell type:markdown id:0005-ed9bf2c1f0a2b4ef60c708c0ac574e49b137ccf2393010d4a84a8e8e968 tags:
Dabei stellen `y1` die tatsächlich gewünschte, aber nicht konvexe
Clusterung und `y2` eine konvexe Clusterung dar. Berechnen Sie das
Gesamtträgheitsmoment. Beachten Sie dabei, dass Sie für beide
Clusterungen nicht die Formel für einen konvergierten $k$-Means
Algorithmus verwenden können. Hier Ihr Code:
%% Cell type:code id:0006-44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 tags:
```
```
%% Cell type:markdown id:0001-1a3c130f07a751c8ea5b72e8d2a5a34dbd13a7537e082b96e6e49115171 tags:
# Elbow Curve
Gegeben sind folgende Daten:
%% Cell type:code id:0002-068063fc1a2e0782cb21fdb20b731cd396412cd0c1e0c33510188cc5fad tags:
```
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
X1, y = make_blobs(n_samples=[100, 100, 400, 400], random_state=1)
X2, y = make_blobs(n_samples=1000, random_state=42)
X3, y = make_blobs(n_samples=[1000], random_state=1)
X4, y = make_blobs(n_samples=10000, centers=7, random_state=42)
```
%% Cell type:markdown id:0006-2951e6f38bd99c99442f6c969884a29efb57da373470865482352a59a3e tags:
Vervollständigen Sie folgende Funktion, indem Sie
[`KMeans`](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html)
für die verschiedenen $k$ in `ks` laufen lassen und mit dem Attribut
`inertia_` die Gesamtträgheit in `inertias` hinzufügen. Der Code zum
Plotten ist bereits fertig.
Probieren Sie es an den vier gegebenen Datensätzen aus und überlegen
Sie, wie man damit die Anzahl der Cluster bestimmen könnte.
## Lösung
Wir fügen eine `for`-Schleife über `ks` hinzu und initialisieren ein
`KMeans`-Objekt mit `n_clusters=k`. Dann rufen wir `fit` auf und
anschließend steht im Attribut `inertia_` das Gesamtträgheitsmoment.
%% Cell type:code id:0007-f24988a2e5d0eb16d4920cd550507417ce9a5b5922b9a41d8261ce46f3b tags:
```
def elbow_plot(X):
inertias = []
ks = np.arange(1, 15)
for k in ks:
kmeans = KMeans(n_clusters=k, n_init=5)
kmeans.fit(X)
inertias.append(kmeans.inertia_)
inertias = np.array(inertias)
log_reductions = np.log(inertias[:-1] / inertias[1:])
improvement = log_reductions / inertias[1:]
improvement /= np.max(improvement)
fig, axs = plt.subplots(1, 2, figsize=(9, 4))
axs[0].scatter(X[:, 0], X[:, 1])
axs[1].plot(ks[1:], inertias[1:], c='gray')
axs[1].scatter(ks[1:], inertias[1:], c=log_reductions, cmap='brg', s=improvement * 100)
axs[0].set_title('data')
axs[1].set_title('elbow curve')
```
%% Cell type:markdown id:0010-d14915689fec3f521698aed18439260e8d369cb5df36e417228479bfe9c tags:
Mit den Plots unten lässt sich darauf schließen, dass diejenige
Clusteranzahl geeignet ist, bei der es noch einen starken Abfall des
Gesamtträgheitsmoments gab, aber danach keine große Verbesserung mehr.
Das ist quasi der namensgebende Ellenbogen. In den vorbereiteten Plots
ist dieser Punkt auch farblich abgehoben zu den darauffolgenden Punkten
und der Marker vergrößert. Das ganze funktioniert nur gut für konvexe
Cluster.
## Tests
Hier die Plots:
%% Cell type:code id:0011-4e7cbe8184375d0a6989ad51b06c108c305f5cbefea444528be5512526f tags:
```
elbow_plot(X1)
elbow_plot(X2)
elbow_plot(X3)
elbow_plot(X4)
```
%% Cell type:markdown id:0001-1a3c130f07a751c8ea5b72e8d2a5a34dbd13a7537e082b96e6e49115171 tags:
# Elbow Curve
Gegeben sind folgende Daten:
%% Cell type:code id:0002-068063fc1a2e0782cb21fdb20b731cd396412cd0c1e0c33510188cc5fad tags:
```
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
X1, y = make_blobs(n_samples=[100, 100, 400, 400], random_state=1)
X2, y = make_blobs(n_samples=1000, random_state=42)
X3, y = make_blobs(n_samples=[1000], random_state=1)
X4, y = make_blobs(n_samples=10000, centers=7, random_state=42)
```
%% Cell type:markdown id:0003-e51ef15b6bc7dd1274d3315e9810bfba0975804d79ae5f2978f4d8c904a tags:
Vervollständigen Sie folgende Funktion, indem Sie
[`KMeans`](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html)
für die verschiedenen $k$ in `ks` laufen lassen und mit dem Attribut
`inertia_` die Gesamtträgheit in `inertias` hinzufügen. Der Code zum
Plotten ist bereits fertig.
%% Cell type:code id:0004-9700539d6d88f68b0c24b391384a0c6d7a6d7d3b58e751ed98bf47a2aff tags:
```
def elbow_plot(X):
inertias = []
ks = np.arange(1, 15)
# TODO: collect inertias for clusterings with varying k
inertias = np.array(inertias)
reductions = inertias[:-1] / inertias[1:]
fig, axs = plt.subplots(1, 2, figsize=(10, 6))
axs[0].scatter(X[:, 0], X[:, 1])
axs[1].plot(ks[1:], inertias[1:], c='gray')
axs[1].scatter(ks[1:], inertias[1:], c=np.log(reductions), cmap='brg')
```
%% Cell type:markdown id:0006-cb8fc7d72755f52d3e72b456da76d7e5b30e6799278749023b02b7df4c0 tags:
Probieren Sie es an den vier gegebenen Datensätzen aus und überlegen
Sie, wie man damit die Anzahl der Cluster bestimmen könnte.
Hier Ihr Code:
%% Cell type:code id:0007-44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 tags:
```
```
%% Cell type:markdown id:0009-fe1bda9a49d27437b792fc1096fa669f2e5b826a1e60b25f2452a4bbcbf tags:
## Tests
Hier die Plots:
%% Cell type:code id:0010-4e7cbe8184375d0a6989ad51b06c108c305f5cbefea444528be5512526f tags:
```
elbow_plot(X1)
elbow_plot(X2)
elbow_plot(X3)
elbow_plot(X4)
```
%% Cell type:markdown id:0001-f51edf4079cb1b470c271c788df582594acbcaaaaa1ec62e3286ad082e3 tags:
# Mosaic
In dieser Aufgabe soll ein Bild `target` aus vielen kleinen Bildern
zusammengesetzt werden. Dazu werden im Startcode bereits die
CIFAR100-Bilder geladen und in der Variable `imgs` gespeichert.
%% Cell type:code id:0002-6e8318925ecf9f50d56d73b2ed5ffb3d3ba92762c1fbfa2ad105e6b65fe tags:
```
import matplotlib.pyplot as plt
import numpy as np
from sklearn.neighbors import NearestNeighbors
from tensorflow import keras
rng = np.random.default_rng()
(x_train, y_train), (x_test, y_test) = keras.datasets.cifar100.load_data()
imgs = np.vstack((x_train, x_test))
target = plt.imread('frochte.webp')
```
%% Cell type:markdown id:0003-941da6218559043f35279a4c335f50e5b68c0c514e67ffbd4322530f8f5 tags:
Es sind 60000 32x32 RGB-Bilder, was man an der Shape schön erkennt:
%% Cell type:code id:0004-1229e2d8dc8e1728d3048fefc550fc060b1f1de9193f0f5a46dca3238ec tags:
```
imgs.shape
```
%% Output
(60000, 32, 32, 3)
%% Cell type:markdown id:0005-22c3afb3e0a561db8a3de73e91fd6bcc6390eaf182dee0c35bf37ed31ce tags:
Das Zielbild hat hier folgende Dimensionen:
%% Cell type:code id:0006-2d221d7ec0ae34f32bfa5ed8787519ea66338bd40130f2f54827c73740d tags:
```
target.shape
```
%% Output
(68, 50, 3)
%% Cell type:markdown id:0009-de978f4ff20b8c801097dd510fc91fbafff5599b0738a4427307471b77a tags:
Bilden Sie von jedem Bild den Mittelwert, aber nur über die Pixel, nicht
über die Farben. Ihr Ziel ist also eine Shape von (60000, 3). Suchen Sie
anschließend zu jedem Pixel von `target` das Bild mit den ähnlichsten
Farben. *Bonus: Suchen Sie z. B. die 10 Bilder mit den ähnlichsten
Farben und wählen Sie ein zufälliges aus.* Setzen Sie anschließend die
gefundenen Bilder als `mosaic` zusammen, sodass ein großes Bild 32-mal
so groß wie das ursprüngliche `target`-Bild erhalten, also hier
$(68 \cdot 32, 50 \cdot 32, 3)$.
## Lösung
Leider noch ohne Erklärung, sorry!
%% Cell type:code id:0010-1af355aab8dd3341d7a01273fc3536afcd2422c84d1688ecc9b968450a4 tags:
```
X = imgs.mean(axis=(1, 2))
# # just the single nearest neighbor (lots of repetition)
ind = NearestNeighbors(n_neighbors=1).fit(X).kneighbors(target.reshape((-1, 3)), return_distance=False)
# select one out of the ten nearest neighbors
ind = NearestNeighbors(n_neighbors=12).fit(X).kneighbors(target.reshape((-1, 3)), return_distance=False)
ind = ind[np.arange(ind.shape[0]), rng.choice(ind.shape[1], size=ind.shape[0])]
ind2d = ind.reshape(target.shape[:2])
tiles = imgs[ind2d]
mosaic = np.hstack(np.hstack(tiles)) # this is hard to understand! First dimension vanishes and third is buffed. Inner call uses the vertical tiles and stacks them vertically, second used the horizontal tiles and stacks them horizontally...
# This is more straightforward:
mosaic = np.vstack([np.hstack(tiles[row]) for row in range(tiles.shape[0])])
```
%% Cell type:markdown id:0012-c5712a3895bf6d089e3023df66a35ce6cdebc2bb919c5f5b7fd3bae4f27 tags:
## Tests
Die Dimensionen von `mosaic` sind:
%% Cell type:code id:0013-6117ace787b35b15ec90c0b04bef2dee6442176716271b8bdf9775313cc tags:
```
mosaic.shape
```
%% Output
(2176, 1600, 3)
%% Cell type:markdown id:0014-63c76eaa9d35584bc36e3f2ca577bfc94f8834910dab8da4a980df5f86c tags:
und sollten sein:
%% Cell type:code id:0015-0516c0ef5eb482707621327f31354b03bfd194cf6e37a97de4db231e3b4 tags:
```
target.shape[0] * 32, target.shape[1] * 32, 3
```
%% Output
(2176, 1600, 3)
%% Cell type:markdown id:0016-7fe0b7441cce862b7e35b9f32c45195a35b532bd6aaa1f6d82bcefec760 tags:
Hier lässt sich das Mosaic-Bild plotten:
%% Cell type:code id:0017-c81f1b00d2217b3ef3a541a3bf0969c691e633f1c550f30d84efc918327 tags:
```
plt.figure(figsize=(16, 10))
plt.imshow(mosaic)
```
%% Cell type:markdown id:0001-f51edf4079cb1b470c271c788df582594acbcaaaaa1ec62e3286ad082e3 tags:
# Mosaic
In dieser Aufgabe soll ein Bild `target` aus vielen kleinen Bildern
zusammengesetzt werden. Dazu werden im Startcode bereits die
CIFAR100-Bilder geladen und in der Variable `imgs` gespeichert.
%% Cell type:code id:0002-6e8318925ecf9f50d56d73b2ed5ffb3d3ba92762c1fbfa2ad105e6b65fe tags:
```
import matplotlib.pyplot as plt
import numpy as np
from sklearn.neighbors import NearestNeighbors
from tensorflow import keras
rng = np.random.default_rng()
(x_train, y_train), (x_test, y_test) = keras.datasets.cifar100.load_data()
imgs = np.vstack((x_train, x_test))
target = plt.imread('frochte.webp')
```
%% Cell type:markdown id:0003-941da6218559043f35279a4c335f50e5b68c0c514e67ffbd4322530f8f5 tags:
Es sind 60000 32x32 RGB-Bilder, was man an der Shape schön erkennt:
%% Cell type:code id:0004-1229e2d8dc8e1728d3048fefc550fc060b1f1de9193f0f5a46dca3238ec tags:
```
imgs.shape
```
%% Output
(60000, 32, 32, 3)
%% Cell type:markdown id:0005-22c3afb3e0a561db8a3de73e91fd6bcc6390eaf182dee0c35bf37ed31ce tags:
Das Zielbild hat hier folgende Dimensionen:
%% Cell type:code id:0006-2d221d7ec0ae34f32bfa5ed8787519ea66338bd40130f2f54827c73740d tags:
```
target.shape
```
%% Output
(68, 50, 3)
%% Cell type:markdown id:0008-ed2a543c286667ee3711dcf37d5ebf4923818e7172044500e2e1aef94f4 tags:
Bilden Sie von jedem Bild den Mittelwert, aber nur über die Pixel, nicht
über die Farben. Ihr Ziel ist also eine Shape von (60000, 3). Suchen Sie
anschließend zu jedem Pixel von `target` das Bild mit den ähnlichsten
Farben. *Bonus: Suchen Sie z. B. die 10 Bilder mit den ähnlichsten
Farben und wählen Sie ein zufälliges aus.* Setzen Sie anschließend die
gefundenen Bilder als `mosaic` zusammen, sodass ein großes Bild 32-mal
so groß wie das ursprüngliche `target`-Bild erhalten, also hier
$(68 \cdot 32, 50 \cdot 32, 3)$.
Hier Ihr Code:
%% Cell type:code id:0009-44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 tags:
```
```
%% Cell type:markdown id:0011-c5712a3895bf6d089e3023df66a35ce6cdebc2bb919c5f5b7fd3bae4f27 tags:
## Tests
Die Dimensionen von `mosaic` sind:
%% Cell type:code id:0012-6117ace787b35b15ec90c0b04bef2dee6442176716271b8bdf9775313cc tags:
```
mosaic.shape
```
%% Output
(2176, 1600, 3)
%% Cell type:markdown id:0013-63c76eaa9d35584bc36e3f2ca577bfc94f8834910dab8da4a980df5f86c tags:
und sollten sein:
%% Cell type:code id:0014-0516c0ef5eb482707621327f31354b03bfd194cf6e37a97de4db231e3b4 tags:
```
target.shape[0] * 32, target.shape[1] * 32, 3
```
%% Output
(2176, 1600, 3)
%% Cell type:markdown id:0015-7fe0b7441cce862b7e35b9f32c45195a35b532bd6aaa1f6d82bcefec760 tags:
Hier lässt sich das Mosaic-Bild plotten:
%% Cell type:code id:0016-c81f1b00d2217b3ef3a541a3bf0969c691e633f1c550f30d84efc918327 tags:
```
plt.figure(figsize=(16, 10))
plt.imshow(mosaic)
```
06-clustering/frochte.webp

4.88 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment