Files
cas-pml/SL/notizen/L3_Notizen.md
T

368 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Notizen SL Lektion 3
> Thema: Feature Engineering
> Datum: 28.05.2026
> Dozentin: Violeta Vogel
## Recap
- Sandbox Prinzip
- Daten werden immer als Kopie bearbeitet (`data = ori_data.copy()`), damit Transformationsschritte sich nicht gegenseitig beeinflussen und die Ausgangsdaten nicht neu geladen werden müssen
- hohe Kardinalität
- bezeichnet eine hohe Anzahl an eindeutigen Werten
## Arten von Variablen
- Numerische Variablen
- messbare Zahlen
- **Stetig** (kontinuierlich)
- Können jeden beliebigen Wert annehmen und unendlich fein unterteilt werden.
- Beispiele: Körpergröße, Gewicht, Temperatur, Zeit
- **Diskret**
- Können nur in bestimmten, meist ganzzahligen Schritten gezählt werden.
- Beispiele: Anzahl der Kinder, Autoverkäufe, Besucher eines Konzerts
- Kategoriale Variablen
- Gruppen oder Eigenschaften
- Diese Variablen teilen Beobachtungen in verschiedene Gruppen oder Kategorien ein. Sie geben eine Eigenschaft an.
- **Nominal**
- Die Kategorien haben keine logische Reihenfolge.
- Beispiele: Geschlecht, Haarfarbe, Augenfarbe, Postleitzahlen.
- **Ordinal**
- Die Kategorien haben eine natürliche Rangordnung oder Reihenfolge.
- Beispiele: Zufriedenheitsgrade (sehr zufrieden, zufrieden, unzufrieden), Schulnoten (1 bis 6)
## Transformationen: Numerisieren Kategorialer Variablen
- Numerisieren
- Numerische Darstellung einer Variablen, damit ML damit rechnen kann
- Verschiedene Methoden
- Faktorisieren
- Ordinal Encodieren
- Nominal Encodieren
- Faustregel: nominal → One-Hot, ordinal → Ordinal Encoding, reines Label ohne Bedeutung → Faktorisieren
### Faktorisieren
- Jeder Kategorie einer kategorialen Variablen wird ein Integer-Wert zugeordnet, beginnend bei 0
- `data.job = pd.factorize(data.job)[0]`
- `pd.factorize()` gibt ein Tupel zurück:
- `[0]` → faktorisierte Werte (`numpy.ndarray`), beginnend bei 0
- `[1]` → Index mit der Zuordnung der Werte zu den Ausgangswerten
- Werte werden per Default in **Reihenfolge des Auftretens** im Dataset vergeben (nicht sortiert)
- mit `sort=True` werden sie lexikografisch (bezogen auf die Ausgangswerte) vergeben
- **Schwäche:** die numerische Zuordnung ist im Grunde willkürlich (Reihenfolge im Datensatz) → es wird eine Ordnung impliziert, die inhaltlich keine ist. Taugt sauber nur für nominale Daten, wo die Zahl reines Label ist.
### Ordinal Encodieren
- Behebt die Faktorisier-Schwäche: bei einer **tatsächlich ordinalen** Variable werden die Zahlen gezielt der natürlichen Rangordnung zugeordnet
- Beispiel `education`:
- `illiterate → 0`
- `unknown → 0`
- `basic.4y → 1`
- `basic.6y → 2`
- `basic.9y → 3`
- `professional.course → 4`
- `high.school → 5`
- `university.degree → 6`
- Umsetzung über `.replace()` mit einem (verschachtelten) Dictionary, das vorher definiert wird:
```python
data.replace(replace_nums, inplace=True)
```
- Hinweis: `sklearn.preprocessing.OrdinalEncoder` macht in Wahrheit nur eine Faktorisierung — echtes ordinales Mapping erfordert deutlich aufwändigere Parametrisierung.
#### Spezialfall: 0-1 Encodieren
- Bei nur zwei Kategorien reicht `np.where`:
```python
data['contact'] = np.where(data.contact == 'cellular', 1, 0)
```
- Achtung: alles, was *nicht* `cellular` ist, wird 0 (inkl. NAs)
- Danach ggf. Spalte umbenennen für Transparenz:
```python
data.rename(columns={'contact': 'contact_cellular'}, inplace=True)
```
### Nominal Encodieren (One-Hot)
- Für Variablen **ohne** Rangordnung — hier wäre eine ordinale Zahl irreführend
- `pd.get_dummies()` erstellt pro Kategorie eine neue Dummy-Variable (0/1) **und entfernt die Ausgangsvariable**
- Wichtige Parameter:
- `drop_first=True` → eine Dummy weniger als Kategorien (vermeidet perfekte Multikollinearität / Dummy-Trap)
- `prefix='marital'` → benennt die neuen Spalten mit Präfix (sinnvoll bei mehreren Variablen)
- `columns=[...]` → mehrere Variablen auf einmal
- Trick für alle kategorialen Spalten außer Target:
```python
target = 'y'
sel_vars = data.select_dtypes(include=['object']).columns.drop(target)
data = pd.get_dummies(data, columns=sel_vars, drop_first=True)
```
## Transformationen: Numerische Variablen
> Hinweis: Normalisieren und Standardisieren sind **Unterarten** von Skalieren, nicht drei gleichrangige Methoden.
- Methoden
- Skalieren
- Normalisieren
- Standardisieren
- Binning
### Skalieren
- Bringt numerische Variablen auf vergleichbare Wertebereiche
- Nur sinnvoll, wenn auf **alle** relevanten Variablen gleich angewendet
- Muss ggf. für spätere neue Daten gespeichert werden → daher in der Praxis `sklearn.preprocessing` statt Handformel:
- `MinMaxScaler` → Normalisierung
- `StandardScaler` → Standardisierung
- `.set_output(transform="pandas")` behält den DataFrame, statt ein numpy-Array zurückzugeben:
```python
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler().set_output(transform="pandas")
data = scaler.fit_transform(data)
```
#### Normalisieren
- Skaliert auf festen Bereich [0, 1]
- Formel: `(x - min) / (max - min)`
- min → 0, max → 1
#### Standardisieren
- Zentriert auf Mittelwert 0, Standardabweichung 1 (z-Transformation)
- Formel: `(x - mean) / std`
- danach: mean ≈ 0, std = 1
> **Wichtig:** Keines der beiden Verfahren ändert die *Form* der Verteilung — nur die Skala der x-Achse. Schiefe bleibt schief.
### Binning
- Numerische Variable in Klassen/Bins zusammenfassen → wird quasi (ordinal-)kategorial
- **Equal Binning:** teilt minmax in gleich breite Bereiche
```python
bins = 10
data.age = pd.cut(data.age, bins=bins, labels=list(range(1, bins + 1)))
```
- **Custom Bins:** eigene Grenzen, nützlich bei stark schiefen Verteilungen
```python
data.campaign = pd.cut(
data.campaign,
bins=[0, 1, 2, 3, 4, 5, 10, 1000],
labels=[1, 2, 3, 4, 5, '6-10', '>10'])
```
- Zur optimalen Bin-Anzahl gibt es keinen Konsens (Freedman-Diaconis, Sturges, …) → experimentell ermitteln
## Konstruktion
- Neue Variablen aus bestehenden ableiten
- Ziele: Komplexität reduzieren, Korrelationen vermeiden
- Beispiel **zyklische Daten** (Windrichtung): 359° und 1° sind nah beieinander, numerisch aber weit weg → Zerlegung in sin/cos-Komponenten löst das
```python
data['x'] = np.sin(data.direction * np.pi / 180) * data.speed
data['y'] = np.cos(data.direction * np.pi / 180) * data.speed
```
- allgemein relevant für alles Zyklische (Stunden, Monate, Winkel)
- Beispiel **Datum**: String → `pd.to_datetime()`, dann Komponenten extrahieren
```python
data['date_dt'] = pd.to_datetime(data.Date, format="%d/%m/%Y")
data['year'] = data.date_dt.dt.year
data['month'] = data.date_dt.dt.month
data['day'] = data.date_dt.dt.day
```
- oder Differenzen zu einem Startdatum (`(data.date_dt - start_date).dt.days`)
## Bereinigen von Variablennamen
- Nach One-Hot entstehen Namen mit Leerzeichen / Bindestrichen / Punkten (`job_blue collar`, `emp.var.rate`), die manche ML-Frameworks als Bezeichner ablehnen
- Erlaubte Zeichen: `a-z`, `A-Z`, `0-9`, `_`
- Per Regex unerlaubte Zeichen durch `_` ersetzen:
```python
new_names = old_names.str.replace('[^a-zA-Z0-9_]', '_', regex=True)
```
## Dekomposition
- Informatik: Kernmethode um grosse Probleme in kleine, handhabbare Teilaufgaben aufzuteilen
- Wirtschaft und Mathematik: Analyse von Daten und Prozesse in einzelne Komponenten aufteilen, Trends, Zeitreihenanalyse und Restrauschen
- In der Datenanalyse:
- Saisonbereinigung vs. Trend
- Prognose/Forecasting -> Aus Trend und Saisonalität kann Zukunft abgeleitet werden
- Fehleranalyse -> Ist das "Restrauschen" normal oder hat es plötzliche Ausschläge?
### Beispiel: Eisverkauf
- Saisonalität ist eindeutig
- Wird die Saisonalität herausgerechnet, sieht man den Trend
- Zufälle: Bspw Firmenfeier oder Schulabschluss
## Merkmals-Dekomposition
- Standardverfahren zur Dimensionsreduktion
- Viele Features können zu wenigen aussagekräftigen Hauptfaktoren zusammengelegt werden
- Die wichtigsten Algorithmen
- PCA (principlan component analysis)
- Sucht nach den Richtungen (Achsen) in denen die Daten die grösste Varianz aufweisen
- t-SNE (t-distributed Stochastic Neighbor Embedding)
- Besonders gut darin nicht lineare Daten abzubilden
- Faktorenanalyse
- Geht davon aus, dass es latente Variablen gibt
### PCA
- Zentrierung: Man schiebt die Datenwolke (Pixelhaufen) so, dass ihr Mittelpunkt genau bei Null liegt
- Berechnung der Hauptkomponenten
- Die 1. Hauptkomponente PC1 ist die Linie die so mitten durch die Daten gelegt wird, dass die Punkte so weit wie möglich darauf verteilt sind
- Die 2. Hauptkomponente PC2 steht im rechten Winkel zur ersten und fängt den rest der Infromation ein
- Vereinfacht einen riesigen Datensatz so, dass
- nur die wichtigsten Merkmale bleiben
- ohne das Gesamtbild zu verlieren
- Visualisierung
- Daten mit 10 oder 50 Merkmalen kann man nicht zeichnen
- Nach PCA hat man 2 Hauptkomponenten und
- man kann sie als Punkte darstellen
- Geschwindigkeit: KI-Modelle lernen viel schneller wenn sie statt 1000 nur noch 10 komprimierte Merkmale verarbeiten müssen
- Rauschunterdrückung: Kleine unwichtige Schwankungen (Rauschen) gehen verloren!
- Voraussetzungen
- keine Missing values
- keine numerischen Daten
- bereinigung anderer möglichen Anomalien
- Features -> X
- Target -> Y
```python
from sklearn.decomposition import PCA
model = PCA()
pred = model.fit_transform(X) # train and apply trainer on data
print(pred[:3,:]) # check result
```
- Interessant: Scatterplot PC1 vs PC2
## Stichproben
- Eie Stichprobe ist ein vollständiges, verkleinertes Spiegelbild der Grundgesamtheit.
- Sie gibt damit auch alle wesentlichen Eigenschaften der Grundgesamtheit wieder
- Mit eine Probeziehung wird ein repräsentativer Teil einer Population ausgewählt um Rückschlüsse auf die Gesamtheit zu ziehen
- Repräsentativ
- Eine Stichprobe ist dann repräsentativ wenn alle Beobachtungen der Grundgesamtheit die gleiche Chance besessen haben, Teil dieser Stichprobe zu werden
### Stichprobengrösse
- Maschinelles Lernen: Als Faustregel gilt, dass Sie mindestens zehnmalso viele Datenpunkte/Beobachtungen benötigen, wie Ihr Datensatz Features enthält
- Art des Ziehens
- Mit oder ohne zurücklegen
### Einfache Stichprobe (Zufallsstichprobe)
- Rein zufällige Features werden gezogen
- Jede Beobachtung hat die gleiche Chance gezogen zu werden
- Vorteil
- Ist die Zufallsstichprobe gross genug werden automatisch alle Beobachtungen in der Stichprobe auftauchen
### Geschichtete Stichprobenziehung (Stratifizierung)
- Ziel
- Die Grundgesamtheit so genau wie möglich darzustellen
- Anforderungen an die Schichten
- Sie sollten sich gegenseitig ausschliessen und gemeinsam erschöpfend sein
- Vorgehen
- relevante Variablen identifizieren
- alter, geschlecht, einkommen, standort
- Grundgesamtheit wird auf Grundlage dieser Variablen in Untergruppen (schichten) eingeteilt
- Zufallsstichprobe aus jeder Schicht wählen:
- Proportional -> entsprechend dem Anteil der Schicht an der Grundgesamtheit
- Disproportional -> etwa Gleich grosse Stichproben aus jeder Schicht
### Proportionale Stratifizierung
- Die schichten werden originalgetreu gewichtet
- Vorteile
- Repräsentativität -> die Grundgesamtheit ist in der Stichprobe gut abgebildet
- Präzise Schätzungen möglich
- Nachteile
- Aufwand
- Komplexität
### Disproportionale Stratifizierung
- Die Schichten werden unterschiedlich stark gewichtet
- Verwendung wenn
- bestimmte Schichten von besonderem Interesse sind
- Kosten der Datenerhebung in den veschiedenen Schichten variieren
- Ziel: Ausreichende Anzahl von Elementen jeder Schicht zu haben
- Gewichtung: Faktor der die ursprüngliche Verteilung der Grundgesamtheit berücksichtigt
- Vorteile:
- Genauigkeit
- Effizienz
- Berücksichtigt Heterogenität
- Detailiertere Analyse der unterschiedlichen Schichten möglich
- Nachteile:
- Verzerrte Ergebnisse
- Aufwändige Analyse
### Klumpenstichprobe
- Grundgesamtheit zunächst hinsichtlich eines Merkmals in natürliche Klumpen einteilen
- Wie bspw. Klassen in einer Schule
- Klumpen untereinander Homogen
- Jeder Klumpen ist ein verkleinertes Abbild der Population
- Alle Klumpen können sich stark ähneln
## Algorithmen
- Wichtig
- Distanzmasse
- Overfitting
- Training vs Anwenden
## Euklidisches Distanzmass
- Wird am häufigsten verwendet in der Clusteranalyse
- "Luftlinie", die den geometrischen Abstand zwischen zwei Punkten in einem Koordinatensystem misst
- Für zwei Punkte P und Q in einem mehrdimensionalen Raum berechnet sich die Distanz nach dem Satz des Pythagoras
- Optische Verzerrung
- Nicht alle Features fallen gleich stark ins Gewicht
- Lösung: Standardisierung
## Manhattan-Distanz (Taxi Prinzip)
- Summe der absoluten Differenzen ihrer Einzelmasse und keine "Luftlinie"
- Wenig anfälliger für Ausreisser
## Overfitting
- Ein ML-Model lernen die Trainingsdaten zu gut auswendig und lernt
- Zufallsschwankungen und Rauschen
- Es wirkt intelligent aber in Wahrheit ist es nicht mehr generalisierungsfähig
- Modell sieht Muster wo keine sind
- Passiert wenn das Modell
- zu komplex ist
- zu wenig Daten hat
- zu lange trainiert wure
- Rauschen in den Daten als echtes Muster interpretiert wird
- Ein Entscheidungsbaum könnte so stark wachsen, dass er jeden einzelnen Trainingspunkt perfekt trennt, sogar Ausreisser
- Wie verhindert man das?
- Cross-Validation
- bei kleinen Datensätzen wichtig
- Teilung des Datensatz in bestimmte Mengen
- Bspw: Ten-fold cross validation (10:1 Trainings zu Testdaten)
- Regularisierungen (L1,L2)
- Frühzeitiges Stoppen
- Pruning bei Entscheidungsbäumen
- Mehr Trainingsdaten
- Dropout bei neuronalen Netzen
- Modell vereinfachen
- Wenn sich Test Error und Training Error stark unterscheiden
- Ist das fast immer ein Zeichen für Overfitting
## Modeltraining vs Modelanwendung
- Modelltraining
- Input
- Daten
- Antworten (Zielvariable)
- Algorithmus aussuchen
- Algorithmen lernen Regeln
- Auswählen des Algorithmus der am besten performed
- Modelanwendung
- Das Modell bekommt neue unbekannte Daten
- Macht eine Vorhersage basierend auf den Trainingsdaten