Unsupervised Learning – Clustering und Dimensionsreduktion

Fach: Data Science & Artificial Intelligence
Schulstufe: 12. Schulstufe – HTL Informatik
Voraussetzungen: Supervised Learning, Python / scikit-learn, NumPy, Matplotlib
Autor: HTL Pinkafeld – IF/IT



1. Was ist Unsupervised Learning?

Beim Supervised Learning haben wir zu jedem Datenpunkt ein Label – eine bekannte Antwort, auf die das Modell hintrainiert wird. Beim Unsupervised Learning gibt es diese Labels nicht. Der Algorithmus bekommt nur die Eingabedaten und soll selbstständig Strukturen, Muster oder Gruppierungen darin finden.

Vergleich der Lernparadigmen

Supervised Learning Unsupervised Learning
Labels vorhanden ✅ Ja ❌ Nein
Ziel Vorhersage Strukturentdeckung
Bewertung Accuracy, F1, RMSE, ... Schwieriger (kein Referenzwert)
Beispiele Klassifikation, Regression Clustering, Dimensionsreduktion

Typische Anwendungsfälle

Hauptgebiete

Unsupervised Learning
        │
        ├── Clustering
        │       ├── K-Means
        │       ├── DBSCAN
        │       └── Hierarchisches Clustering
        │
        └── Dimensionsreduktion
                ├── PCA (Principal Component Analysis)
                └── t-SNE

2. Clustering – Grundkonzepte

Clustering (dt. Clusteranalyse) bezeichnet das Gruppieren von Datenpunkten so, dass Punkte innerhalb einer Gruppe (Cluster) möglichst ähnlich sind und Punkte aus verschiedenen Gruppen möglichst unähnlich.

Distanzmaße

Ähnlichkeit wird meist über eine Distanz definiert:

Euklidische Distanz (häufigste Wahl):

d(A, B) = √( Σ (aᵢ - bᵢ)² )

Manhattan-Distanz (robuster bei Ausreißern):

d(A, B) = Σ |aᵢ - bᵢ|

Kosinus-Ähnlichkeit (für Texte und Vektoren):

cos(A, B) = (A · B) / (‖A‖ · ‖B‖)

⚠️ Wichtig: Vor dem Clustering müssen Features skaliert werden (z.B. mit StandardScaler), da sonst Features mit großem Wertebereich die Distanzberechnung dominieren.

Qualität eines Clusterings bewerten

Da es keine Labels gibt, brauchen wir andere Bewertungsmaße:

Metrik Bedeutung Bereich
Silhouette Score Wie gut ist jeder Punkt in seinem Cluster? -1 bis +1 (höher = besser)
Inertia (SSE) Summe der quadrierten Abstände zum Clusterzentrum 0 bis ∞ (niedriger = besser)
Davies-Bouldin Index Ähnlichkeit zwischen Clustern 0 bis ∞ (niedriger = besser)

3. Algorithmus: K-Means

3.1 Grundidee

K-Means teilt die Daten in k Cluster auf, indem es iterativ Clusterzentren (Centroids) anpasst.

3.2 Algorithmus Schritt für Schritt

1. Wähle k zufällige Punkte als initiale Centroids

2. Wiederhole bis Konvergenz:
   a) Zuweisung: Weise jeden Datenpunkt dem nächsten Centroid zu
   b) Update:    Berechne neue Centroids als Mittelwert der zugewiesenen Punkte

3. Stoppe, wenn sich die Centroids nicht mehr verändern

Visualisierung eines Iterationsschritts:

Iteration 1:          Iteration 2:          Iteration 3 (konvergiert):
  ×   ·  ·              ×  ·  ·               ×·  ·
·   · ×  ·            · · × ··              ···×··
  ·    ·  ×           ·    · ×              ·   ·×

× = Centroid   · = Datenpunkt (Farbe = zugewiesenes Cluster)

3.3 Implementierung

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score

# Synthetische Daten erstellen (3 Cluster)
X, y_true = make_blobs(n_samples=300, centers=3, cluster_std=0.8, random_state=42)

# Skalieren
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# K-Means Modell
kmeans = KMeans(n_clusters=3, n_init=10, random_state=42)
kmeans.fit(X_scaled)

labels     = kmeans.labels_
centroids  = kmeans.cluster_centers_
inertia    = kmeans.inertia_

print(f"Inertia:          {inertia:.2f}")
print(f"Silhouette Score: {silhouette_score(X_scaled, labels):.3f}")

# Visualisierung
plt.figure(figsize=(8, 5))
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=labels, cmap='tab10', alpha=0.6, s=40)
plt.scatter(centroids[:, 0], centroids[:, 1], c='black', marker='X', s=200, label='Centroids')
plt.title('K-Means Clustering (k=3)')
plt.legend()
plt.tight_layout()
plt.show()

3.4 Stärken und Schwächen

✅ Stärken ❌ Schwächen
Einfach und schnell k muss vorher bekannt sein
Skaliert gut auf große Datensätze Empfindlich auf initiale Centroids
Leicht interpretierbar Nur kugelförmige Cluster
Gut für kompakte, gut getrennte Cluster Empfindlich auf Ausreißer
Nicht geeignet für unterschiedlich große Cluster

4. Algorithmus: DBSCAN

4.1 Grundidee

DBSCAN (Density-Based Spatial Clustering of Applications with Noise) findet Cluster basierend auf der lokalen Datendichte. Er kann beliebig geformte Cluster erkennen und markiert Punkte in dünn besiedelten Regionen automatisch als Ausreißer (Noise).

4.2 Schlüsselbegriffe

4.3 Implementierung

from sklearn.cluster import DBSCAN
from sklearn.datasets import make_moons
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt

# Mondsichelförmige Daten (K-Means würde hier versagen)
X, _ = make_moons(n_samples=300, noise=0.08, random_state=42)
X_scaled = StandardScaler().fit_transform(X)

# DBSCAN
db = DBSCAN(eps=0.3, min_samples=5)
labels = db.fit_predict(X_scaled)

n_cluster  = len(set(labels)) - (1 if -1 in labels else 0)
n_noise    = (labels == -1).sum()

print(f"Gefundene Cluster: {n_cluster}")
print(f"Ausreißer:         {n_noise}")
if n_cluster > 1:
    mask = labels != -1
    print(f"Silhouette Score:  {silhouette_score(X_scaled[mask], labels[mask]):.3f}")

# Visualisierung
plt.scatter(X_scaled[:, 0], X_scaled[:, 1],
            c=labels, cmap='tab10', alpha=0.7, s=40)
# Ausreißer separat markieren
noise_mask = labels == -1
plt.scatter(X_scaled[noise_mask, 0], X_scaled[noise_mask, 1],
            c='red', marker='x', s=80, label='Ausreißer')
plt.title(f'DBSCAN: {n_cluster} Cluster, {n_noise} Ausreißer')
plt.legend()
plt.tight_layout()
plt.show()

4.4 Stärken und Schwächen

✅ Stärken ❌ Schwächen
Keine Angabe von k nötig eps und minPts schwer zu wählen
Beliebig geformte Cluster Probleme bei unterschiedlicher Dichte
Erkennt Ausreißer automatisch Schlecht bei hochdimensionalen Daten
Robust gegenüber Ausreißern Langsamer als K-Means

5. Algorithmus: Hierarchisches Clustering

5.1 Grundidee

Hierarchisches Clustering baut eine Baumstruktur (Dendrogram) auf, die alle Zusammenführungen von Clustern zeigt. Man braucht k nicht vorab festlegen – die Anzahl der Cluster wird durch einen Schnitt im Dendrogram bestimmt.

Agglomeratives Verfahren (bottom-up):

1. Jeder Datenpunkt = eigenes Cluster
2. Füge die zwei ähnlichsten Cluster zusammen
3. Wiederhole bis nur noch 1 Cluster übrig

5.2 Linkage-Methoden

Wie wird die Distanz zwischen zwei Clustern berechnet?

Methode Beschreibung Geeignet für
ward Minimiert Varianzanstieg Kompakte, gleich große Cluster
complete Maximale Distanz zweier Punkte Gut getrennte Cluster
average Mittlere Distanz Ausgewogener Ansatz
single Minimale Distanz (nächstes Paar) Kettenförmige Cluster

5.3 Implementierung mit Dendrogram

from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np

X, _ = make_blobs(n_samples=50, centers=3, random_state=42)

# Dendrogram zeichnen
linked = linkage(X, method='ward')
plt.figure(figsize=(12, 5))
dendrogram(linked, leaf_rotation=90, leaf_font_size=8)
plt.axhline(y=10, color='red', linestyle='--', label='Schnitt → 3 Cluster')
plt.title('Dendrogram – Hierarchisches Clustering')
plt.xlabel('Datenpunkt-Index')
plt.ylabel('Distanz')
plt.legend()
plt.tight_layout()
plt.show()

# Cluster-Labels extrahieren (Schnitt bei k=3)
hc = AgglomerativeClustering(n_clusters=3, linkage='ward')
labels = hc.fit_predict(X)
print(f"Cluster-Größen: {np.bincount(labels)}")

6. Clusteranzahl bestimmen

6.1 Ellbow-Methode

Die Inertia wird für verschiedene k-Werte berechnet. An der „Ellbogen"-Stelle flacht die Kurve ab – das ist ein guter Hinweis auf die optimale Anzahl.

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

X, _ = make_blobs(n_samples=300, centers=4, random_state=42)

inertias = []
k_range = range(1, 11)

for k in k_range:
    km = KMeans(n_clusters=k, n_init=10, random_state=42)
    km.fit(X)
    inertias.append(km.inertia_)

plt.plot(k_range, inertias, marker='o', color='#F6A01D')
plt.axvline(x=4, color='red', linestyle='--', label='Optimales k=4')
plt.xlabel('Anzahl Cluster k')
plt.ylabel('Inertia (SSE)')
plt.title('Elbow-Methode zur Bestimmung von k')
plt.legend()
plt.tight_layout()
plt.show()

6.2 Silhouette-Analyse

Der Silhouette Score misst, wie gut jeder Punkt zu seinem Cluster passt:

s(i) = (b(i) - a(i)) / max(a(i), b(i))

a(i) = mittlere Distanz zu Punkten im eigenen Cluster
b(i) = mittlere Distanz zu Punkten im nächsten Cluster
from sklearn.metrics import silhouette_score, silhouette_samples
import numpy as np

scores = []
for k in range(2, 8):
    km = KMeans(n_clusters=k, n_init=10, random_state=42)
    labels = km.fit_predict(X)
    scores.append(silhouette_score(X, labels))
    print(f"k={k}: Silhouette Score = {scores[-1]:.3f}")

best_k = range(2, 8)[np.argmax(scores)]
print(f"\nBestes k: {best_k}")

7. Dimensionsreduktion – Grundkonzepte

Reale Datensätze haben oft Hunderte oder Tausende von Features (hohe Dimensionalität). Das verursacht mehrere Probleme:

Der Fluch der Dimensionalität

Ziele der Dimensionsreduktion

Viele Features (z.B. 100)
        │
        ▼
Dimensionsreduktion
        │
        ▼
Wenige Features (z.B. 2–3)

Dabei soll möglichst viel Information erhalten bleiben!

Anwendungen:


8. Algorithmus: PCA – Principal Component Analysis

8.1 Grundidee

PCA sucht die Richtungen im Datensatz, in denen die größte Varianz liegt – diese Richtungen heißen Hauptkomponenten (Principal Components). Die Daten werden dann auf diese Richtungen projiziert.

Intuition: Stell dir eine Wolke von Punkten im 3D-Raum vor, die eigentlich auf einer Ebene liegt. PCA findet diese Ebene und projiziert alle Punkte hinein – 3D wird zu 2D, ohne viel Information zu verlieren.

8.2 Mathematischer Hintergrund

  1. Zentrieren: Mittelwert von X abziehen
  2. Kovarianzmatrix berechnen: C = (1/n) · Xᵀ · X
  3. Eigenwertzerlegung: Eigenvektoren = Hauptkomponenten, Eigenwerte = erklärte Varianz
  4. Projektion: Daten auf die k wichtigsten Hauptkomponenten projizieren

8.3 Erklärte Varianz

Ein zentrales Konzept: Wie viel Prozent der ursprünglichen Information bleiben erhalten?

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import load_digits
from sklearn.preprocessing import StandardScaler

# Zifferndatensatz: 1797 Bilder, 64 Features (8×8 Pixel)
digits = load_digits()
X = StandardScaler().fit_transform(digits.data)

# PCA – alle Komponenten berechnen
pca_full = PCA()
pca_full.fit(X)

# Erklärte Varianz pro Komponente und kumulativ
explained = pca_full.explained_variance_ratio_
cumulative = np.cumsum(explained)

plt.figure(figsize=(9, 4))
plt.subplot(1, 2, 1)
plt.bar(range(1, 21), explained[:20], color='#F6A01D')
plt.xlabel('Komponente')
plt.ylabel('Erklärte Varianz')
plt.title('Varianz pro Komponente')

plt.subplot(1, 2, 2)
plt.plot(range(1, len(cumulative)+1), cumulative, color='#F6A01D', marker='.')
plt.axhline(y=0.95, color='red', linestyle='--', label='95% Varianz')
plt.xlabel('Anzahl Komponenten')
plt.ylabel('Kumulierte erklärte Varianz')
plt.title('Kumulierte Varianz')
plt.legend()
plt.tight_layout()
plt.show()

# Wie viele Komponenten für 95%?
n_95 = np.argmax(cumulative >= 0.95) + 1
print(f"Komponenten für 95% Varianz: {n_95} (statt 64)")

8.4 PCA zur Visualisierung

# Reduktion auf 2 Komponenten für Visualisierung
pca_2d = PCA(n_components=2)
X_2d = pca_2d.fit_transform(X)

plt.figure(figsize=(8, 6))
scatter = plt.scatter(X_2d[:, 0], X_2d[:, 1],
                      c=digits.target, cmap='tab10', alpha=0.6, s=20)
plt.colorbar(scatter, label='Ziffer')
plt.xlabel(f'PC1 ({pca_2d.explained_variance_ratio_[0]:.1%} Varianz)')
plt.ylabel(f'PC2 ({pca_2d.explained_variance_ratio_[1]:.1%} Varianz)')
plt.title('Zifferndatensatz – PCA auf 2 Komponenten')
plt.tight_layout()
plt.show()

8.5 PCA als Preprocessing

PCA kann vor einem Klassifikations-Algorithmus eingesetzt werden, um die Dimensionalität zu reduzieren:

from sklearn.pipeline import Pipeline
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_digits

digits = load_digits()
X, y = digits.data, digits.target

# Pipeline: Skalierung → PCA → kNN
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('pca',    PCA(n_components=30)),   # 64 → 30 Features
    ('knn',    KNeighborsClassifier(n_neighbors=5))
])

scores = cross_val_score(pipeline, X, y, cv=5)
print(f"CV Accuracy mit PCA (30 Komp.): {scores.mean():.2%}")

# Vergleich ohne PCA
pipeline_nopca = Pipeline([
    ('scaler', StandardScaler()),
    ('knn',    KNeighborsClassifier(n_neighbors=5))
])
scores_nopca = cross_val_score(pipeline_nopca, X, y, cv=5)
print(f"CV Accuracy ohne PCA (64 Feat): {scores_nopca.mean():.2%}")

8.6 Stärken und Schwächen

✅ Stärken ❌ Schwächen
Rauschen wird reduziert Komponenten schwer interpretierbar
Korrelierte Features werden kombiniert Nur lineare Zusammenhänge
Schnell und deterministisch Informationsverlust unvermeidbar
Gut als Preprocessing-Schritt Skalierung zwingend notwendig

9. Algorithmus: t-SNE

9.1 Grundidee

t-SNE (t-distributed Stochastic Neighbor Embedding) ist eine nichtlineare Dimensionsreduktionsmethode, die speziell für die Visualisierung hochdimensionaler Daten entwickelt wurde. Im Gegensatz zu PCA versucht t-SNE, die lokale Struktur (Nachbarschaften) zu erhalten.

Achtung: t-SNE ist ausschließlich zur Visualisierung geeignet, nicht als Preprocessing für nachgelagerte Algorithmen!

9.2 Implementierung

from sklearn.manifold import TSNE
from sklearn.datasets import load_digits
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt

digits = load_digits()
X = StandardScaler().fit_transform(digits.data)

# t-SNE (dauert etwas länger als PCA)
tsne = TSNE(n_components=2, perplexity=30, n_iter=1000, random_state=42)
X_tsne = tsne.fit_transform(X)

plt.figure(figsize=(9, 7))
scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1],
                      c=digits.target, cmap='tab10', alpha=0.7, s=20)
plt.colorbar(scatter, label='Ziffer')
plt.title('Zifferndatensatz – t-SNE Visualisierung')
plt.xlabel('t-SNE Dimension 1')
plt.ylabel('t-SNE Dimension 2')
plt.tight_layout()
plt.show()

9.3 PCA vs. t-SNE

PCA t-SNE
Methode Linear Nichtlinear
Geschwindigkeit Sehr schnell Langsam
Ziel Maximale Varianz erhalten Lokale Struktur erhalten
Reproduzierbar ✅ Ja ⚠️ Nur mit random_state
Als Preprocessing ✅ Ja ❌ Nein
Für Visualisierung Gut Sehr gut
Großer Datensatz ✅ Ja ⚠️ Begrenzt (< 10.000)

Tipp: Bei großen Datensätzen erst mit PCA auf 50 Komponenten reduzieren, dann t-SNE anwenden – das spart deutlich Rechenzeit.

# Empfohlene Kombination für große Datensätze:
pca_pre = PCA(n_components=50)
X_pca   = pca_pre.fit_transform(X)
X_tsne  = TSNE(n_components=2, random_state=42).fit_transform(X_pca)

10. Anwendungsbeispiel: Kundensegmentierung

10.1 Aufgabenstellung

Ein Online-Shop möchte seine Kunden anhand ihres Kaufverhaltens in Segmente einteilen, um gezielte Marketingmaßnahmen durchzuführen.

10.2 Vollständige Pipeline

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score

# ── 1. Synthetische Kundendaten erstellen ─────────────────────────────────
np.random.seed(42)
n = 400

# Drei Kundengruppen simulieren
gruppen = {
    'Gelegenheitskäufer':   {'n': 150, 'ausgaben': (20, 10),  'besuche': (2, 1)},
    'Stammkunden':           {'n': 150, 'ausgaben': (80, 20),  'besuche': (8, 2)},
    'Premium-Kunden':        {'n': 100, 'ausgaben': (200, 40), 'besuche': (5, 1)},
}

dfs = []
for name, params in gruppen.items():
    n_g = params['n']
    df_g = pd.DataFrame({
        'monatliche_ausgaben':  np.random.normal(*params['ausgaben'], n_g).clip(5),
        'besuche_pro_monat':    np.random.normal(*params['besuche'],  n_g).clip(1),
        'kundenzufriedenheit':  np.random.uniform(2, 5, n_g).round(1),
        'tage_seit_letztkauf':  np.random.exponential(15, n_g).clip(1, 90).astype(int),
    })
    dfs.append(df_g)

kunden = pd.concat(dfs, ignore_index=True).sample(frac=1, random_state=42)
print(kunden.describe().round(2))

# ── 2. Preprocessing ──────────────────────────────────────────────────────
X = kunden.values
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# ── 3. Optimales k bestimmen (Elbow + Silhouette) ─────────────────────────
inertias, silhouettes = [], []
k_range = range(2, 9)

for k in k_range:
    km = KMeans(n_clusters=k, n_init=10, random_state=42)
    labels = km.fit_predict(X_scaled)
    inertias.append(km.inertia_)
    silhouettes.append(silhouette_score(X_scaled, labels))

fig, axes = plt.subplots(1, 2, figsize=(11, 4))
axes[0].plot(k_range, inertias, marker='o', color='#F6A01D')
axes[0].set_title('Elbow-Methode'); axes[0].set_xlabel('k'); axes[0].set_ylabel('Inertia')
axes[1].plot(k_range, silhouettes, marker='o', color='#F6A01D')
axes[1].set_title('Silhouette Score'); axes[1].set_xlabel('k'); axes[1].set_ylabel('Score')
plt.tight_layout(); plt.show()

# ── 4. K-Means mit k=3 ────────────────────────────────────────────────────
kmeans = KMeans(n_clusters=3, n_init=10, random_state=42)
kunden['segment'] = kmeans.fit_predict(X_scaled)

# ── 5. Segmente analysieren ───────────────────────────────────────────────
print("\nSegment-Profile:")
print(kunden.groupby('segment').mean().round(2))

# ── 6. Visualisierung mit PCA ─────────────────────────────────────────────
pca = PCA(n_components=2)
X_2d = pca.fit_transform(X_scaled)

plt.figure(figsize=(8, 6))
for seg in sorted(kunden['segment'].unique()):
    mask = kunden['segment'] == seg
    plt.scatter(X_2d[mask, 0], X_2d[mask, 1], label=f'Segment {seg}', alpha=0.6, s=40)

# Centroids im PCA-Raum einzeichnen
centroids_2d = pca.transform(kmeans.cluster_centers_)
plt.scatter(centroids_2d[:, 0], centroids_2d[:, 1],
            c='black', marker='X', s=200, zorder=5, label='Centroids')
plt.xlabel(f'PC1 ({pca.explained_variance_ratio_[0]:.1%})')
plt.ylabel(f'PC2 ({pca.explained_variance_ratio_[1]:.1%})')
plt.title('Kundensegmentierung – K-Means (k=3) visualisiert mit PCA')
plt.legend(); plt.tight_layout(); plt.show()

11. Vergleich der Algorithmen

Clustering-Algorithmen

K-Means DBSCAN Hierarchisch
k vorab nötig ✅ Ja ❌ Nein ❌ Nein (Schnitt wählen)
Clusterform Nur kugelförmig Beliebig Beliebig
Ausreißer Werden zugewiesen Werden erkannt Werden zugewiesen
Geschwindigkeit Schnell Mittel Langsam (bei großen n)
Skalierbarkeit Sehr gut Gut Schlecht
Einfache Parameter ✅ ❌ (eps schwer) ✅
Wann einsetzen Kompakte Cluster, große Daten Unbekannte Formen, Ausreißer Explorative Analyse, kleines n

Dimensionsreduktionsmethoden

PCA t-SNE
Typ Linear Nichtlinear
Hauptzweck Preprocessing + Visualisierung Nur Visualisierung
Geschwindigkeit Sehr schnell Langsam
Neue Datenpunkte transformierbar ✅ ❌
Interpretierbarkeit Mittel (Varianzanteil) Gering
Wann einsetzen Immer als erster Schritt Finale Visualisierung

12. Zusammenfassung und Ausblick

Überblick

Unsupervised Learning
│
├── Clustering
│     ├── K-Means       → schnell, kompakte Cluster, k vorab nötig
│     ├── DBSCAN        → beliebige Formen, Ausreißer, kein k nötig
│     └── Hierarchisch  → Dendrogram, explorativ, langsam
│
└── Dimensionsreduktion
      ├── PCA   → linear, schnell, Preprocessing + Visualisierung
      └── t-SNE → nichtlinear, langsam, nur Visualisierung

Entscheidungshilfe

Clustering oder Dimensionsreduktion?
    → Daten gruppieren:           Clustering
    → Daten visualisieren/vereinf.: Dimensionsreduktion

Welcher Clustering-Algorithmus?
    → Ich weiß, wie viele Cluster: K-Means
    → Unbekannte Clusterform:       DBSCAN
    → Explorative Analyse:          Hierarchisch

Welche Dimensionsreduktion?
    → Als Preprocessing:     PCA
    → Nur Visualisierung:    t-SNE (ggf. nach PCA)

Checkliste

✅ Features vor Clustering/PCA immer skalieren (StandardScaler)
✅ Clusteranzahl mit Elbow + Silhouette bestimmen
✅ Ergebnis immer visualisieren (PCA oder t-SNE)
✅ Cluster inhaltlich interpretieren (Mittelwerte pro Cluster)
✅ PCA: erklärte Varianz prüfen (Ziel: 90–95%)
✅ t-SNE nur zur Visualisierung, nicht als Preprocessing

Ausblick: Nächste Themen


Anhang: Schnellreferenz

# ── Clustering ────────────────────────────────────────────────────────────
from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering

km = KMeans(n_clusters=3, n_init=10, random_state=42)
db = DBSCAN(eps=0.5, min_samples=5)
hc = AgglomerativeClustering(n_clusters=3, linkage='ward')

labels = km.fit_predict(X_scaled)   # Für alle drei gleich

# ── Bewertung ─────────────────────────────────────────────────────────────
from sklearn.metrics import silhouette_score, davies_bouldin_score

sil = silhouette_score(X_scaled, labels)   # höher = besser
db_score = davies_bouldin_score(X_scaled, labels)  # niedriger = besser

# ── Dimensionsreduktion ───────────────────────────────────────────────────
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE

pca   = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
print(pca.explained_variance_ratio_)   # Varianzanteil je Komponente

tsne   = TSNE(n_components=2, perplexity=30, random_state=42)
X_tsne = tsne.fit_transform(X_scaled)  # Nur fit_transform, kein transform!

# ── Dendrogram ────────────────────────────────────────────────────────────
from scipy.cluster.hierarchy import dendrogram, linkage
linked = linkage(X_scaled, method='ward')
dendrogram(linked)

HTL Pinkafeld – IF/IT | Data Science & AI | 12. Schulstufe

Vorheriges ThemaEnsemble-Methoden Nächstes ThemaDeep Learning