Files
DissLiteratur/storage/MV9DQ2RR/.zotero-ft-cache
Johannes Paehr 929f905886 update
2025-11-20 21:21:20 +01:00

3264 lines
190 KiB
Plaintext
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.
Benny Botsch
Maschinelles Lernen Grundlagen und Anwendungen
Mit Beispielen in Python
Maschinelles Lernen Grundlagen und Anwendungen
Benny Botsch
Maschinelles Lernen Grundlagen und Anwendungen
Mit Beispielen in Python
Benny Botsch Berlin, Deutschland
ISBN 978-3-662-67276-1
ISBN 978-3-662-67277-8 (eBook)
https://doi.org/10.1007/978-3-662-67277-8
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.
© Der/die Herausgeber bzw. der/die Autor(en), exklusiv lizenziert an Springer-Verlag GmbH, DE, ein Teil von Springer Nature 2023
Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Jede Verwertung, die nicht ausdrücklich vom Urheberrechtsgesetz zugelassen ist, bedarf der vorherigen Zustimmung des Verlags. Das gilt insbesondere für Vervielfältigungen, Bearbeitungen, Übersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in elektronischen Systemen. Die Wiedergabe von allgemein beschreibenden Bezeichnungen, Marken, Unternehmensnamen etc. in diesem Werk bedeutet nicht, dass diese frei durch jedermann benutzt werden dürfen. Die Berechtigung zur Benutzung unterliegt, auch ohne gesonderten Hinweis hierzu, den Regeln des Markenrechts. Die Rechte des jeweiligen Zeicheninhabers sind zu beachten. Der Verlag, die Autoren und die Herausgeber gehen davon aus, dass die Angaben und Informationen in diesem Werk zum Zeitpunkt der Veröffentlichung vollständig und korrekt sind. Weder der Verlag noch die Autoren oder die Herausgeber übernehmen, ausdrücklich oder implizit, Gewähr für den Inhalt des Werkes, etwaige Fehler oder Äußerungen. Der Verlag bleibt im Hinblick auf geografische Zuordnungen und Gebietsbezeichnungen in veröffentlichten Karten und Institutionsadressen neutral.
Planung/Lektorat: Andreas Ruedinger Springer Spektrum ist ein Imprint der eingetragenen Gesellschaft Springer-Verlag GmbH, DE und ist ein Teil von Springer Nature. Die Anschrift der Gesellschaft ist: Heidelberger Platz 3, 14197 Berlin, Germany
Inhaltsverzeichnis
1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 Was ist maschinelles Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Überwachtes Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2.1 Klassifikation und Regression . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2.2 Generalisierung, Überanpassung und Unteranpassung . . . . . 4 1.3 Unüberwachtes Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.4 Bestärkendes Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.5 Teilüberwachtes Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.6 Herausforderungen des maschinellen Lernens . . . . . . . . . . . . . . . . . . . . 7 1.6.1 Unzureichende Menge an Trainingsdaten . . . . . . . . . . . . . . . . . 7 1.6.2 Nicht repräsentative Trainingsdaten . . . . . . . . . . . . . . . . . . . . . . . 8 1.6.3 Daten von schlechter Qualität . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.6.4 Irrelevante Merkmale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.6.5 Explainable Artificial Intelligence . . . . . . . . . . . . . . . . . . . . . . . . 10 1.7 Bewertung und Vergleich von Algorithmen . . . . . . . . . . . . . . . . . . . . . . 11 1.7.1 Kreuzvalidierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.7.2 Messfehler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.7.3 Intervallschätzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.7.4 Hypothesenprüfung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.8 Werkzeuge und Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.8.1 Installation von Python mit Anaconda . . . . . . . . . . . . . . . . . . . . 16 1.8.2 Entwicklungsumgebungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.8.3 Python-Bibliotheken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.8.4 Grundlagen in Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2 Lineare Algebra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.1 Skalare, Vektoren und Matrizen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.1.1 Operationen mit Skalaren und Vektoren . . . . . . . . . . . . . . . . . . . 27 2.1.2 Operationen mit Vektoren und Matrizen . . . . . . . . . . . . . . . . . . 29 2.1.3 Die Inverse einer Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 2.2 Lineare Gleichungssysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.2.1 Gauß-Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.2.2 Numerische Lösungsmethoden linearer Gleichungssysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
V
VI
Inhaltsverzeichnis
3 Wahrscheinlichkeit und Statistik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.1 Grundbegriffe der Wahrscheinlichkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.2 Zufallsgrößen und Verteilungsfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . 37 3.3 Momente einer Verteilung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3.3.1 Erwartungswert und Streuung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.3.2 Schiefe und Exzess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3.4 Bedingte Wahrscheinlichkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 3.5 Deskriptive Statistik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3.6 Einfache statistische Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 3.6.1 Ablauf eines statistischen Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 3.6.2 Parametertests bei normalverteilter Grundgesamtheit . . . . . . 46 3.6.3 Mittelwerttest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 3.6.4 χ 2-Streuungstest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4 Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.1 Grundlagen der Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.1.1 Univariate Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.1.2 Bivariate Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.1.3 Multivariate Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.2 Gradient Descent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.2.1 Momentum-Based Learning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.2.2 AdaGrad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.2.3 Adam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.3 Newton-Methode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
5 Parametrische Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 5.1 Regressionsanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 5.1.1 Lineare Regression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 5.1.2 Logistische Regression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 5.2 Lineare Support Vector Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 5.2.1 Die optimale Trennebene . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 5.2.2 Soft-Margin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.2.3 Kernfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 5.3 Der Bayessche Schätzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 5.3.1 Stochastische Unabhängigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.3.2 Bayessche Netze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 5.4 Neuronale Netze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 5.4.1 Das künstliche Neuron . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 5.4.2 Mehrschichtige neuronale Netze . . . . . . . . . . . . . . . . . . . . . . . . . . 85 5.4.3 Lernvorgang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 5.5 Deep Learning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 5.5.1 Convolutional Neural Networks . . . . . . . . . . . . . . . . . . . . . . . . . . 97 5.5.2 Rekurrent Neural Networks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 5.5.3 Generative Modelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Inhaltsverzeichnis
VII
6 Nichtparametrische Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6.1 Nichtparametrische Dichteschätzung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 6.1.1 Histogrammschätzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 6.1.2 Kernschätzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 6.1.3 k-Nächste-Nachbarn-Schätzer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 6.2 Entscheidungsbäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 6.2.1 Univariate Bäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 6.2.2 Multivariate Bäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 6.2.3 Pruning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 6.2.4 Random Forest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
7 Bestärkendes Lernen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 7.1 Was ist bestärkendes Lernen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 7.1.1 Belohnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 7.1.2 Der Agent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 7.1.3 Die Umgebung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 7.1.4 Aktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 7.1.5 Beobachtungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 7.2 Theoretische Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 7.2.1 Markov-Entscheidungsprozesse . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 7.2.2 Markov-Prozess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 7.2.3 Markov-Belohnungsprozess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 7.2.4 Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 7.3 Wertebasierte Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 7.3.1 Grundlagen der Wertefunktion und der Bellman-Gleichung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 7.3.2 Q-Learning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 7.3.3 SARSA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 7.3.4 Deep Q-Networks (DQN) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 7.4 Policy-basierte Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 7.4.1 Policy Gradient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 7.4.2 Actor-Critic-Verfahren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 7.4.3 Soft Actor-Critic (SAC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
8 Custeranalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 8.1 k-Means-Clustermethode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 8.2 Hierarchische Clustermethode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 8.3 Gaußsche Mischmodelle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
9 Anwendungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 9.1 Regelungstechnik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 9.1.1 Systemidentifikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 9.1.2 Neuronaler Regler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 9.1.3 Regelung eines inversen Pendels . . . . . . . . . . . . . . . . . . . . . . . . . . 170 9.2 Bildverarbeitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 9.2.1 Klassifikation von Zahlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
VIII
Inhaltsverzeichnis
9.2.2 Segmentierung von Bruchflächen . . . . . . . . . . . . . . . . . . . . . . . . . 181 9.2.3 Objekterkennung mit Vision Transformers . . . . . . . . . . . . . . . . 188 9.2.4 Künstliche Generierung von Bildern . . . . . . . . . . . . . . . . . . . . . . 196 9.2.5 Interpretierbarkeit von Vision-Modellen mit
Grad-CAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 9.3 Chemie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
9.3.1 Klassifizierung von Wein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 9.3.2 Vorhersage von Eigenschaften organischer Moleküle . . . . . . 207 9.4 Physik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 9.4.1 Statistische Versuchsplanung optimieren . . . . . . . . . . . . . . . . . . 211 9.4.2 Vorhersage von RANS-Strömungen . . . . . . . . . . . . . . . . . . . . . . . 212 9.5 Generierung von Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 9.5.1 Textgenerierung mit einem Miniatur-GPT . . . . . . . . . . . . . . . . . 221 9.5.2 Englisch-Spanisch-Übersetzung mit TensorFlow . . . . . . . . . . 231 9.6 Audiodatenverarbeitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 9.6.1 Automatische Spracherkennung mit CTC . . . . . . . . . . . . . . . . . 244 9.6.2 Klassifizierung von Sprechern mit FFT . . . . . . . . . . . . . . . . . . . 251
Literatur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Stichwortverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Einführung
1
Zusammenfassung
Maschinelles Lernen erfreut sich in vielen Bereichen immer größerer Beliebtheit. Das resultiert aufgrund der fortschreitenden Computertechnologie. Durch immer größere und schnellere Speichermedien können große Datenmengen lokal bzw. über ein Computernetzwerk effizient gespeichert und verarbeitet werden. Ebenso verbessert sich stetig die Performance der Prozessoren in CPU und GPU, wodurch sich die Trainingszeiten der Algorithmen immer weiter reduzieren lassen. Kap. 1 beschäftigt sich zunächst mit den verschiedenen Verfahren des maschinellen Lernens. Darüber hinaus werden einige Begriffe erläutert, welche in den späteren Kapiteln noch wichtig werden. In diesem Buch wird es neben den Übungen auch Programmierbeispiele geben, daher werden in Abschn. 1.8 einige Werkzeuge und Ressourcen vorgestellt, die für die Entwicklung des Python-Codes benötigt werden.
1.1 Was ist maschinelles Lernen
Maschinelles Lernen (ML) ist ein Teilgebiet der künstlichen Intelligenz (KI) und befasst sich mit der Entwicklung lernfähiger Systeme und Algorithmen. Die Algorithmen lernen anhand von ausreichend Daten verschiedene Zusammenhänge. Das somit entstandene Modell kann anschließend auf neue, unbekannte Daten derselben Art angewendet werden. Maschinelles Lernen wird mittlerweile in vielen Bereichen erfolgreich eingesetzt. Speziell, wenn bestimmte Prozesse zu kompliziert sind, um sie analytisch zu beschreiben. Eine der häufigsten Anwendungen von maschinellem Lernen ist die Erkennung von Mustern in großen Datenmengen. Diese Technologie wird in vielen Bereichen wie Finanzen, Marketing, Medizin und Wissenschaft eingesetzt, um die Ergebnisse aus Daten zu interpretieren. Ein weiteres Anwendungsgebiet ist die automatisierte Spracherkennung. Mit Hilfe von maschinellem Lernen können Computerprogramme dazu befähigt werden, menschliche Sprache zu verstehen und auf bestimmte Befehle zu reagieren. Diese Technologie wird häufig in der Kundenun-
© Der/die Autor(en), exklusiv lizenziert an Springer-Verlag GmbH, DE, ein Teil von
1
Springer Nature 2023
B. Botsch, Maschinelles Lernen Grundlagen und Anwendungen,
https://doi.org/10.1007/978-3-662-67277-8_1
2
1 Einführung
Eingabedaten
Maschinelles Lernen -Zusammenhänge -Muster -Abhängigkeiten
Ausgabe
Abb. 1.1 Schematische Darstellung des ML-Prozesses
terstützung, im Gesundheitswesen und in der Robotik eingesetzt. Schließlich wird maschinelles Lernen auch in der Computer Vision eingesetzt. Diese Technologie kann Computerprogramme dazu befähigen, Bilder und Videos zu analysieren und bestimmte Objekte zu erkennen. Diese Technologie wird in vielen Bereichen eingesetzt, z. B. in der autonomen Fahrzeugtechnologie, in der Sicherheitstechnologie und in der Medizintechnik.
Wie man in Abb. 1.1 sehen kann, werden für das Training eines Lernalgorithmus Eingabedaten benötigt. Das sind im Allgemeinen wert- bzw. zeitdiskrete Daten. Diese nutzt der jeweilige Algorithmus, um eine mathematische Funktion zu erlernen. Funktionen bzw. Abbildungen sind eindeutige Zuordnungen zwischen zwei Mengen X und Y .
f :X →Y
(1.1)
Es wird öfters vorkommen, dass aufgrund von Messfehlern oder statistischen Effekten Widersprüche in den Daten auftreten. So kann z. B. einem Element aus X mehrere Elemente aus Y zugeordnet werden. Aus diesem Grund werden verschiedene Metriken (Verlustfunktion oder auch „loss function“ genannt) benötigt, wonach sich der Algorithmus bei seiner Optimierung richten kann.
Es gibt im Wesentlichen vier verschiedene Kategorien von Lernverfahren, welche in den nachfolgenden Kapiteln ausführlich beschrieben werden.
1.2 Überwachtes Lernen
Beim überwachten Lernen wird dem Algorithmus eine hinreichend große Menge von Eingabe- und Ausgabedaten zur Verfügung gestellt, siehe Abb. 1.2. Man spricht bei diesen Datensätzen von gelabelten oder markierten Datensätzen. Beim Training lernt der Algorithmus die Muster und Zusammenhänge bezüglich der Eingangsdaten und der Ausgangsdaten. Der gewünschte Funktionswert kann nun eine Klasse (Hund oder Katze) oder ein numerischer Wert (Aktienkurs) sein. Nach dem erfolgreichen Training kann das Modell dazu verwendet werden, um die Funktionswerte von neuen Eingangsdaten vorherzusagen.
Das überwachte Lernen lässt sich in zwei Problemstellungen einteilen, nämlich die Regression und die Klassifikation.
1.2 Überwachtes Lernen
Eingabedaten Ausgabedaten
Training
ML-Modell :
3 Vorhersage
Testdaten
Abb. 1.2 Überwachtes Lernen mit Eingabe- und Ausgabedaten beim Training
1.2.1 Klassifikation und Regression
Die Hauptaufgabe der Klassifikation besteht darin, aus einer vordefinierten Liste von Möglichkeiten eine Klassenzugehörigkeit vorherzusagen. Die Klassifikation kann in eine binäre Klassifikation unterteilt werden, also die Unterscheidung zwischen zwei Klassen, oder in eine Mehrklassen-Klassifikation. Die Klassifikation von E-Mails als Spam oder kein Spam ist beispielsweise ein binäres Klassifikationsproblem. Ein Beispiel für die Mehrklassen-Klassifikation ist die Identifizierung von Objekten in Bildern. Das könnte z. B. die Unterscheidung von verschiedenen Tieren oder Pflanzen sein. Wollen wir nun Bilder klassifizieren und verwenden dabei die klassische Mustererkennung, so müssen zunächst sogenannte Feature (Merkmale) aus den Daten berechnet werden. Das können im Falle von Bildern z. B. Texturmerkmale oder eine Gradientenverteilung sein. Sind die Feature linear trennbar, wie in Abb. 1.3 dargestellt, dann können auch lineare Lernalgorithmen verwendet werden. Ist dies nicht der Fall, müssen Nichtlinearitäten dem Lernalgorithmus hinzugefügt werden. Nichtlinearitäten kann man beispielsweise durch polynominale Feature erzeugen. Dabei werden die Feature untereinander multipliziert und die so neu entstandenen Feature werden zu den bereits vorhandenen hinzugefügt.
Für Regressionsaufgaben versucht man dagegen, eine kontinuierliche Zahl vorherzusagen („floating-point“ in der Programmierung oder reelle Zahl in der Mathematik). Diese Form der Analyse schätzt die Koeffizienten einer Gleichung mit einem oder mehreren unabhängigen Features. Betrachtet man die lineare Regression, dann liefert diese eine Linie, welche die Abweichungen zwischen den vorhergesagten und
Abb. 1.3 Lineare und nichtlineare Trennung einer binären Klassifikation
4
1 Einführung
Unteranpassung Überanpassung
Fehler
Validierungsfehler Trainingsfehler
Modellkomplexität
Abb. 1.4 Darstellung der Unter- bzw. Überanpassung anhand einer Lernkurve
den tatsächlichen Ausgabewerten minimiert. Die lineare Regression kann z. B. verwendet werden, um das durchschnittliche Jahresgehalt eines Arbeitnehmers (abhängige Variable) anhand von unabhängigen Variablen wie Alter, Bildung oder Berufserfahrung vorherzusagen. Eine weitere Anwendung ist die Analyse im Sport. So hängt beispielsweise die Anzahl der gewonnenen Spiele eines Fußballteams in einer Saison eng mit der durchschnittlichen Punktzahl der Mannschaft pro Spiel zusammen. Steigt die Anzahl der gewonnenen Spiele, sinkt die durchschnittliche Punktzahl, die der Gegner erzielt hat. Diese Beziehung kann verwendet werden, um vorherzusagen, wie viele Spiele die Teams gewinnen werden.
1.2.2 Generalisierung, Überanpassung und Unteranpassung
Das Ziel beim maschinellen Lernen besteht darin, Vorhersagen für neue unbekannte Daten zu treffen. Dazu muss zunächst ein Modell mit einem Trainingsdatensatz angelernt werden. Anschließend verwendet man einen Validierungsdatensatz, also Daten, die das Modell noch nicht kennt, um die Vorhersagequalität von neuen Daten zu überprüfen. Ist das Modell nun in der Lage, eine ähnlich gute Vorhersagequalität wie bei den Trainingsdaten zu erreichen, dann spricht man von der Generalisierung.
Die bestmögliche Generalisierung eines Modells erhalten wir, wenn die Komplexität des Modells eine ähnliche Mächtigkeit aufweist wie die des zu untersuchenden Problems bzw. der Funktion. Ist das Modell weniger komplex als die Funktion, dann spricht man von einer Unteranpassung („underfitting“), siehe Abb. 1.4. Verwendet man beispielsweise ein lineares Modell für einen Datensatz, welcher von einem Polynom dritten Grades stammt, dann wird man sowohl einen hohen Trainings- als auch Validierungsfehler bekommen. Wird die Komplexität nun stetig erhöht, verringert sich der Trainings- und auch der Validierungsfehler. Die Komplexität kann aber nicht ewig vergrößert werden, da ab einem bestimmten Punkt der Validierungsfehler anfängt zu steigen. Das ist der Punkt, wenn das Modell komplexer als die Funktion ist. Sollte zusätzlich Rauschen in den Daten vorhanden sein, dann würde das komplexe Modell dieses ebenfalls lernen. Die Folge ist eine schlechtere Generalisierung. Man spricht folglich von einer Überanpassung („overfitting“).
1.4 Bestärkendes Lernen
5
Abb. 1.5 Beispiel einer Clusteranalyse, bei der sich zwei signifikannte Cluster finden lassen
Bei allen Lernalgorithmen gibt es einen Kompromiss zwischen der Komplexität eines Modells, die Menge an vorhandenen Daten und dem Generalisierungsfehler bei neuen Daten. Nimmt die Menge an Daten zu, dann nimmt der Generalisierungsfehler ab. Erhöht sich die Komplexität des Modells, verringert sich zunächst der Generalisierungsfehler, nimmt dann aber dann wieder zu. Erhöht man allerdings die Anzahl der Trainingsdaten, dann kann ein Ansteigen des Generalisierungsfehlers reduziert werden [10].
1.3 Unüberwachtes Lernen
Im Vergleich zum überwachten Lernen sind beim unüberwachten Lernen die Ausgabedaten nicht bekannt. Es sind lediglich Eingabedaten vorhanden, wobei man versuchen möchte, Regelmäßigkeiten in den Eingabedaten zu finden. Man überprüft quasi den Eingaberaum auf mögliche Strukturen und ob diese öfters auftreten als andere. Ein Ansatz ist die sogenannte Dichteschätzung.
Eine Möglichkeit zur Dichteschätzung ist die Clusteranalyse (siehe Abb. 1.5). Man versucht, dabei Häufungen bzw. Cluster in den Eingabedaten zu finden. Ein Anwendungbeispiel ist die Verwendung im Bereich des Marketings. Unternehmen wollen ihre neuen Kunden möglichst genau analysieren und in bestimmte Zielgruppen einordnen. Es werden daraufhin ähnliche Kunden aus dem gesamten Kundenbestand identifiziert, um individuelle Werbestrategien für diesen Kunden zu entwickeln.
Eine weitere Anwendung ist die Anomalie-Erkennung. Unüberwachtes Lernen wird an dieser Stelle eingesetzt, um Abweichungen von bestimmten Normen in Echtzeit zu erkennen und direkt eingreifen zu können. Selbst komplexe, automatisierte Prozesse können so durchgehend überwacht werden.
1.4 Bestärkendes Lernen
Bestärkendes Lernen beschäftigt sich damit, automatisch optimale Entscheidungen mit der Zeit zu treffen. Dieses allgemeine Problem wird in vielen wissenschaftlichen und technischen Fachgebieten untersucht. Viele Aufgaben beim maschinellen Lernen
6
1 Einführung
Aktionen
Agent
Belohnung
Umgebung
Beobachtung
Abb. 1.6 Interaktion eines Agenten mit seiner Umgebung
besitzen eine verborgene zeitliche Dimension. Diese kann bei einem Produktivsystem allerdings zu Problemen führen. Bestärkendes Lernen ist ein Ansatz, der diese zusätzliche Dimension (im Allgemeinen die Zeit) beim Training berücksichtigt.
Im Gegensatz zum überwachten Lernen wissen wir nicht bei jedem Schritt genau, was das Richtige ist. Wir wissen nur das letztendliche Ziel, welches wir erreichen wollen. Wie man dieses Ziel erreicht, lernt der Algorithmus im Laufe der Zeit. Betrachten wir ein kleines Beispiel. Es sei ein Agent (Robotermaus) gegeben, der in einer Umgebung (Labyrinth) bestimmte Aktionen ausführen soll. Die Robotermaus kann sich dabei nach links bzw. rechts drehen oder sich vorwärts bewegen. Des Weiteren ist sie in der Lage, zu jedem Zeitpunkt den kompletten Zustand der Umgebung zu beobachten, siehe Abb. 1.6. Anhand der Beobachtung kann sie nun entscheiden, welche Aktion ausgeführt werden soll. Der Agent hat nun das Ziel, seine Belohnung zu maximieren. Es können ebenfalls negative Belohnungen auftreten, beispielsweise wenn der Agent Aktionen ausführt, die nicht erwünscht sind, oder in einen Zustand gelangt, den man nicht erreichen möchte. Bestärkendes Lernen bietet hier nun eine Lösung, die sich vom überwachten und unüberwachten Lernen unterscheidet. Es gibt keine vordefinierten Labels wie beim überwachten Lernen.
1.5 Teilüberwachtes Lernen
Teilüberwachtes Lernen ist ein Ansatz, der während des Trainings eine kleine Menge gelabelter Daten mit einer großen Menge nicht gelabelter Daten kombiniert. Teilüberwachtes Lernen fällt zwischen unüberwachtes Lernen (ohne gelabelten Trainingsdaten) und überwachtes Lernen (nur mit gelabelten Trainingsdaten).
In Abb. 1.7 ist das Prinzip des teilüberwachten Lernens dargestellt. Ausgangsbasis sind wenig gelabelte Daten. Mit diesen wird zunächst ein Modell trainiert, das kann z. B. ein SVM-Klassifizierer sein. Eine genaue Erläuterung zu diesem Klassifizierer finden Sie in Kap. 5. Dieses Modell wird dann anschließend verwendet, um die vielen verfügbaren ungelabelten Daten zu klassifizieren und somit zu kennzeichnen. Die neu gelabelten Daten werden mit den ursprünglich verfügbaren Daten kombiniert, um das Modell mit viel mehr Daten neu zu trainieren und somit ein besseres Modell zu erhalten [4].
1.6 Herausforderungen des maschinellen Lernens
7
Wenig gelabelte
Daten
Klassifizieren
Initiale KlassifikatorOptimierung
von ungelabelten Daten
mit dem trainierten
+
Klassifikator erneut
trainieren
Klassifizierer
Viele ungelabelte
Daten
Abb. 1.7 Prinzip des teilüberwachten Lernens
1.6 Herausforderungen des maschinellen Lernens
Das Maschinelle Lernen hat in den letzten Jahren eine unglaubliche Entwicklung erfahren und wird zunehmend in vielen Bereichen eingesetzt, von der Spracherkennung bis hin zur Gesichtserkennung. Dennoch sind viele Herausforderungen und Schwierigkeiten vorhanden, die es zu überwinden gilt, um das volle Potenzial des maschinellen Lernens zu nutzen. Eine solche Herausforderung ist die Qualität der Daten, die für das Training von Modellen benötigt werden. Ungenaue oder unvollständige Daten können zu unzuverlässigen Ergebnissen führen und das Vertrauen in das System verringern. Ein weiteres Problem ist die Übertragbarkeit von Modellen auf neue Daten und Situationen. Modelle, die in einem bestimmten Kontext gut funktionieren, können in einem anderen Kontext völlig unbrauchbar sein. Schließlich ist auch die Interpretierbarkeit von Modellen ein wichtiger Faktor. Wenn wir nicht verstehen, wie ein Modell zu seinen Entscheidungen kommt, kann es schwierig sein, es in kritischen Anwendungen wie der Medizin oder dem Rechtswesen einzusetzen. Diese und andere Herausforderungen sind Gegenstand intensiver Forschung und Entwicklung, um das maschinelle Lernen weiter voranzutreiben und seine Anwendung in einer Vielzahl von Anwendungen zu verbessern.
1.6.1 Unzureichende Menge an Trainingsdaten
Ein zentrales Problem beim maschinellen Lernen ist die unzureichende Menge an Trainingsdaten. Im Allgemeinen gilt, dass der Erfolg von maschinellen Lernsystemen stark von der Menge und Qualität der Daten abhängt, die zur Verfügung stehen. Wenn nicht genügend Daten vorhanden sind, kann dies zu Überanpassung („overfitting“) führen, was bedeutet, dass das Modell zu komplex wird und nicht mehr in der Lage ist, neue Daten sinnvoll zu verarbeiten. Um dieses Problem zu lösen, gibt es verschiedene Ansätze. Einer davon ist das sogenannte Transfer Learning, bei dem Modelle auf einer großen Menge von Daten trainiert werden und anschließend auf
8
1 Einführung
eine andere, kleinere Menge von Daten angewendet werden. Ein anderer Ansatz ist die Verwendung von generativen Modellen, die versuchen, neue Daten zu erzeugen, um die Menge der Trainingsdaten zu erweitern.
Ein weiteres Problem bei der Verwendung von unzureichenden Trainingsdaten ist das sogenannte Data Snooping. Hierbei werden die Modelle auf den Trainingsdaten überoptimiert, was dazu führen kann, dass das Modell auf zufällige Muster in den Daten reagiert, die keine tatsächliche Vorhersagekraft haben. Dies kann zu einer Verschlechterung der Leistung des Modells führen, wenn es auf neue Daten angewendet wird, da diese möglicherweise nicht die gleichen zufälligen Muster aufweisen. Eine Möglichkeit, Data Snooping zu vermeiden, besteht darin, die Daten in Trainings-, Validierungs- und Testdaten aufzuteilen. Die Trainingsdaten werden verwendet, um das Modell zu trainieren, während die Validierungsdaten verwendet werden, um die Hyperparameter des Modells (z. B. die Anzahl der versteckten Schichten in einem neuronalen Netzwerk) zu optimieren. Die Testdaten werden schließlich verwendet, um die Leistung des Modells auf neuen Daten zu bewerten.
1.6.2 Nicht repräsentative Trainingsdaten
Die Qualität der Trainingsdaten ist ein kritischer Faktor für den Erfolg von maschinellen Lernsystemen. Eine der Herausforderungen besteht darin, Trainingsdaten zu finden, die repräsentativ für die gesamte Datenverteilung sind. Wenn die Trainingsdaten nicht repräsentativ sind, kann dies zu Verzerrungen und schlechter Leistung des Modells führen. Ein Grund dafür, dass nicht repräsentative Trainingsdaten zu einer schlechten Leistung von maschinellen Lernsystemen führen können, ist der sogenannte Bias. Dies bezieht sich auf eine systematische Abweichung des Modells von der wahren Beziehung zwischen den Eingabedaten und den Ausgaben. Wenn das Modell auf Basis von Trainingsdaten trainiert wird, die nicht die volle Bandbreite der möglichen Eingabedaten abdecken, kann es zu einem Verzerrungseffekt kommen. Das Modell neigt dazu, die Eigenschaften der Trainingsdaten zu generalisieren, was zu Vorhersagen führt, die nicht auf die breitere Population von Eingabedaten zutreffen. Ein Beispiel für einen Bias-Effekt tritt auf, wenn eine Klassifikationsaufgabe mit einem ungleichmäßig verteilten Klassenverhältnis behandelt wird. Wenn die Trainingsdaten hauptsächlich eine Klasse enthalten und die andere Klasse nur sehr selten vorkommt, kann das Modell dazu neigen, die häufige Klasse zu bevorzugen und die seltenere Klasse zu ignorieren.
Ein weiterer Effekt von nicht repräsentativen Trainingsdaten ist die Varianz. Dieser Effekt tritt auf, wenn das Modell sehr empfindlich auf kleine Unterschiede in den Trainingsdaten reagiert. Wenn die Trainingsdaten nicht repräsentativ sind, kann es zu einer hohen Varianz kommen, da das Modell auf Muster in den Trainingsdaten reagiert, die nicht in der breiteren Population von Eingabedaten vorkommen. Dadurch wird das Modell anfällig für Überanpassung, was bedeutet, dass es sehr gut auf den Trainingsdaten abschneidet, aber schlecht auf neuen Daten. Um diese Effekte zu minimieren, gibt es verschiedene Ansätze. Ein Ansatz besteht darin, mehr Trainingsdaten zu sammeln, um sicherzustellen, dass die Trainingsdaten repräsentativ für die gesamte Datenverteilung sind. Dies kann jedoch schwierig sein, insbesondere wenn
1.6 Herausforderungen des maschinellen Lernens
9
die Daten teuer oder schwierig zu sammeln sind. Ein weiterer Ansatz besteht darin, die vorhandenen Trainingsdaten zu erweitern, indem synthetische Daten generiert werden, um sicherzustellen, dass das Modell auf eine breitere Palette von Eingabedaten reagieren kann. Die Generierung von synthetischen Daten kann durch Techniken wie Data Augmentation erreicht werden, bei der zufällige Transformationen auf den vorhandenen Trainingsdaten angewendet werden, um neue Datenpunkte zu generieren.
Es gibt auch Ansätze, die speziell darauf abzielen, den Bias-Effekt zu minimieren. Einer dieser Ansätze besteht darin, eine Gewichtung der Trainingsdaten vorzunehmen, bei der Datenpunkten, die in der breiteren Population seltener vorkommen, ein höheres Gewicht zugewiesen wird. Dadurch wird sichergestellt, dass das Modell gleichermaßen auf alle relevanten Kategorien von Eingabedaten reagiert.
1.6.3 Daten von schlechter Qualität
Ein weiteres Problem sind inkonsistente oder unvollständige Daten. Inkonsistente Daten können aufgrund von Fehlern bei der Datenerfassung oder bei der Integration von Daten aus verschiedenen Quellen auftreten. Unvollständige Daten können beispielsweise auftreten, wenn eine wichtige Eingabevariable nicht erfasst wurde oder wenn Daten nur für einen Teil der Beobachtungszeit verfügbar sind. Inkonsistente oder unvollständige Daten können dazu führen, dass das Modell falsche Beziehungen zwischen den Eingabevariablen und der Zielvariable herstellt und daher ungenaue Vorhersagen trifft.
Ein weiteres Problem sind Daten von geringer Qualität, bei denen die Messgenauigkeit oder die Messmethode selbst unsicher oder fehlerhaft ist. Daten von geringer Qualität können dazu führen, dass das Modell falsche Beziehungen zwischen den Eingabevariablen und der Zielvariable herstellt und daher ungenaue Vorhersagen trifft.
Um die Auswirkungen von Daten von schlechter Qualität auf das maschinelle Lernen zu minimieren, gibt es verschiedene Schritte, die unternommen werden können. Eine Möglichkeit besteht darin, die Daten sorgfältig zu bereinigen, indem Ausreißer und fehlende Daten entfernt werden. Eine andere Möglichkeit besteht darin, die Daten auf Inkonsistenzen zu prüfen und diese zu korrigieren. Darüber hinaus können verschiedene Techniken eingesetzt werden, um die Qualität der Daten zu verbessern, wie beispielsweise die Erhöhung der Messgenauigkeit oder die Verbesserung der Datenerfassungsmethoden.
1.6.4 Irrelevante Merkmale
Das maschinelle Lernen nutzt die Merkmale oder Eigenschaften von Daten, um Vorhersagen bzw. Klassifizierungen durchzuführen. Allerdings können irrelevante Merkmale, die keinen Einfluss auf die Zielvariable haben, die Leistung des Modells erheblich beeinträchtigen. Irrelevante Merkmale können auf verschiedene Arten ent-
10
1 Einführung
stehen. Ein häufiges Problem sind redundante Merkmale, die die gleiche Information wie andere Merkmale enthalten. Redundante Merkmale können dazu führen, dass das Modell überangepasst wird, da sie das Modell dazu verleiten, bestimmte Merkmale stärker zu gewichten als andere, obwohl sie die gleiche Information enthalten. Ein weiteres Problem sind uninformative Merkmale, die keinen Einfluss auf die Zielvariable haben und daher keine Vorhersagekraft besitzen. Uninformative Merkmale können dazu führen, dass das Modell weniger effektiv wird, da es sich auf irrelevante Informationen konzentriert.
Ein weiteres Problem sind kollineare Merkmale, die hoch miteinander korreliert sind. Kollinearität kann dazu führen, dass das Modell das Vorhandensein eines Merkmals überschätzt, wenn es in Verbindung mit anderen Merkmalen steht. Dies kann zu ungenauen Vorhersagen führen, wenn sich die Beziehung zwischen dem Merkmal und der Zielvariable ändert. Eine Möglichkeit, dieses Problem zu lösen, besteht darin, die Bedeutung der Merkmale zu gewichten, um diejenigen zu identifizieren, die am stärksten zur Zielvariable beitragen. Man schätzt sogenannte Merkmalsgewichte, indem eine Regressionsanalyse durchgeführt wird. Die Merkmalsgewichte können dann verwendet werden, um die wichtigen Merkmale zu identifizieren und die unwichtigen zu entfernen oder zu transformieren.
1.6.5 Explainable Artificial Intelligence
Das maschinelle Lernen hat in den letzten Jahren eine exponentielle Entwicklung erfahren und wird in vielen Bereichen eingesetzt, von der Spracherkennung bis hin zur Gesichtserkennung. Während diese Technologie enorme Chancen für die Gesellschaft bietet, sind auch zahlreiche Risiken und Herausforderungen damit verbunden. Eine dieser Herausforderungen betrifft die Interpretierbarkeit von Maschinen, auch bekannt als Explainable Artificial Intelligence (XAI).
XAI bezieht sich auf die Fähigkeit von Maschinen, ihre Entscheidungen und Handlungen auf eine verständliche und nachvollziehbare Weise zu erklären. Es geht darum sicherzustellen, dass Benutzer und andere Interessengruppen verstehen können, wie Maschinen zu ihren Entscheidungen kommen und welche Faktoren diese Entscheidungen beeinflussen. Dadurch können Benutzer das Vertrauen in die Maschinen und ihre Entscheidungen stärken und die Anwendung von Maschinen in kritischen Anwendungen wie der Medizin oder dem Rechtswesen verbessern.
Eine der wichtigsten Herausforderungen bei XAI ist die Komplexität von Maschinen. Moderne Maschinen sind oft sehr komplex und verwenden Algorithmen, die schwer zu verstehen sind. Um dieses Problem zu lösen, müssen Entwickler Techniken wie die Erklärbarkeit von Modellen und die Aufzeichnung von Entscheidungen verwenden, um sicherzustellen, dass Benutzer die Entscheidungen von Maschinen nachvollziehen können. Eine Möglichkeit, dies zu tun, besteht darin, Entscheidungsbäume zu erstellen, die zeigen, wie Maschinen zu ihren Entscheidungen kommen.
Ein weiteres Problem bei XAI ist die Balance zwischen Komplexität und Verständlichkeit. Um sicherzustellen, dass Maschinen erklärt werden können, müssen Entwickler ihre Modelle vereinfachen und abstrahieren. Eine Möglichkeit, dies zu
1.7 Bewertung und Vergleich von Algorithmen
11
tun, besteht darin, Techniken wie Feature Selection zu verwenden, so dass nur relevante Informationen in das Modell einbezogen werden.
Ein weiteres Problem bei XAI ist die Sicherheit von Maschinen. Wenn wir Maschinen erklären können, wie sie zu ihren Entscheidungen kommen, kann dies auch dazu führen, dass diese Entscheidungen manipuliert werden können. Um dieses Problem zu lösen, müssen Entwickler sicherstellen, dass ihre Modelle sicher und robust sind und dass sie gegen Angriffe wie Adversarial Attacks geschützt sind.
XAI bezieht sich auch auf die Verantwortlichkeit von Entwicklern. Entwickler müssen sicherstellen, dass ihre Modelle ethisch und verantwortungsvoll eingesetzt werden und dass sie gegen Vorurteile und Diskriminierung geschützt sind. Dazu gehört auch die Gewährleistung der Privatsphäre und des Datenschutzes von Benutzern. Entwickler müssen sicherstellen, dass die Daten, die von Maschinen gesammelt werden, sicher und geschützt sind, um die Privatsphäre von Benutzern zu schützen.
Ein weiterer wichtiger Aspekt von XAI ist die Interaktion zwischen Benutzern und Maschinen. Benutzer müssen in der Lage sein, mit Maschinen zu interagieren und Feedback zu geben, um sicherzustellen, dass die Maschinen ihre Bedürfnisse und Anforderungen verstehen. Hierzu können Techniken wie Natural Language Processing (NLP) oder Dialogsysteme eingesetzt werden, um eine natürlichere Interaktion zwischen Benutzern und Maschinen zu ermöglichen.
Insgesamt gibt es viele Herausforderungen bei XAI, aber es gibt auch viele Möglichkeiten, um diese Herausforderungen zu bewältigen. Ein wichtiger Schritt besteht darin sicherzustellen, dass Entwickler sich der Bedeutung von XAI bewusst sind und dass sie entsprechende Techniken und Tools verwenden, so dass ihre Maschinen erklärt werden können. Darüber hinaus müssen Regulierungsbehörden und andere Interessengruppen sicherstellen, dass Maschinen ethisch und verantwortungsvoll eingesetzt werden und dass sie gegen Vorurteile und Diskriminierung geschützt sind. Durch eine gemeinsame Anstrengung können wir sicherstellen, dass Maschinen sicher, vertrauenswürdig und erklärt werden können und dass sie uns bei der Lösung wichtiger gesellschaftlicher Herausforderungen unterstützen können.
1.7 Bewertung und Vergleich von Algorithmen
Dieses Kapitel widmet sich der Frage, wie der Fehler eines Algorithmus bewertet werden kann. Speziell möchte man wissen, ob der zu erwartende Fehler bei neuen Daten sich innerhalb einer gewissen Toleranz befindet. Der Fehler ist grundsätzlich bei den Trainingsdaten immer kleiner als bei den Testdaten. Aufgrund dessen eignet sich der Trainingsfehler nicht für den Vergleich von Algorithmen. Es wird ein sogenannter Validierungsdatensatz benötigt, der sich vom Trainingsdatensatz unterscheidet.
12
1 Einführung
Iteration 1
Testdaten
Trainingsdaten Trainingsdaten
1
Iteration 2 Trainingsdaten Testdaten Trainingsdaten
2
Iteration 3 Trainingsdaten Trainingsdaten Testdaten
3
Abb. 1.8 Darstellung einer 3-fachen Kreuzvalidierung. Bei jeder Iteration resultiert ein Fehler ei . Der Gesamtfehler errechnet sich als Durchschnitt aus den Einzelfehlern
1.7.1 Kreuzvalidierung
Die Kreuzvalidierung eignet sich zur Bewertung der Leistung eines Algorithmus. Es wird ein Teil des vorhandenen Datensatzes separiert, um damit die Güte der Vorhersage zu überprüfen. Jeder Durchlauf der Kreuzvalidierung umfasst eine zufällige Aufteilung des originalen Datensatzes in einem Trainings- und Testdatensatz. Mit dem Trainingsdatensatz wird der Algorithmus trainiert. Der Testdatensatz wird zur Bewertung der Leistung verwendet. Dieser Vorgang wird nun mehrmals wiederholt. Daraufhin resultiert ein mittlerer Kreuzvalidierungsfehler als Leistungsindikator.
Der Kreuzvalidierung stehen verschiedene Techniken zur Verfügung. Am häufigsten wird die k-fache Kreuzvalidierung verwendet. Die Daten werden zufällig in k ausgewählte Teilmengen ungefähr gleicher Größe aufgeteilt. Dabei wird nun eine Teilmenge zum Validieren verwendet und der Rest zum Trainieren. Dieser Vorgang wird k-mal wiederholt, so dass jede Teilmenge einmal zum Validieren verwendet wird, siehe Abb. 1.8.
Die Daten kann man ebenso für Training und Validierung in genau zwei Teilmengen aufteilen. Diese Technik nennt sich Holdout. Hier werden Training und Validierung nur einmal ausgeführt, was die Ausführungszeit bei großen Datensätzen beachtlich verkürzt, allerdings sollte der ausgegebene Fehler mit Bedacht interpretiert werden.
Eine weitere Technik ist die Leave-One-Out-Kreuzvaliderung. Die Leave-OneOut-Kreuzvalidierung ist eine Technik zur Bewertung der Leistung von MLModellen. Im Wesentlichen geht es darum, ein Modell auf einer Stichprobe von Daten zu trainieren und es dann auf einer anderen Stichprobe zu testen, um zu sehen, wie gut es generalisiert. Diese Prozedur wird für jede einzelne Beobachtung in den Daten durchgeführt, wobei jede Beobachtung einmal aus der Stichprobe entfernt wird und das Modell auf den verbleibenden Daten trainiert und getestet wird. Ein wichtiger Vorteil der Leave-One-Out-Kreuzvaliderung ist die Genauigkeit, da sie eine große Anzahl von Tests durchführt. Bei einer Stichprobe von n Beobachtungen wird das Modell n-mal trainiert und getestet, wobei jeweils eine andere Beobachtung aus der Stichprobe entfernt wird. Dies ermöglicht es, eine sehr genaue Schätzung der Vorhersageleistung des Modells zu erhalten. Ein Nachteil ist jedoch, dass sie sehr rechenintensiv sein kann, insbesondere bei großen Datensätzen. Da jedes Modell n-mal trainiert und getestet wird, kann dies sehr zeitaufwendig sein. Aus diesem Grund wird diese Technik in der Praxis oft nur bei kleineren Datensätzen verwendet.
Die Kreuzvalidierung ist eine rechenintensive Methode, da das Training und die Validierung mehrmals durchgeführt werden. Vor allem ist die Kreuzvaliderung in
1.7 Bewertung und Vergleich von Algorithmen
13
Abb. 1.9 Darstellung der Konfusionsmatrix für eine binäre Klassifikation
der Modellentwicklung ein wichtiger Faktor, da eine mögliche Unter- bzw. Überanpassung identifiziert werden kann.
1.7.2 Messfehler
Um Modelle evaluieren zu können, werden sogenannte Metriken benötigt. Metriken geben einem Informationen darüber, wie gut die Performance eines Modells ist. Wir betrachten zunächst einige Metriken im Bereich der Klassifikation. Zur Bewertung von Klassifikationsergebnissen wird häufig die Konfusionsmatrix herangezogen. Die Zeilen stellen den tatsächlichen Wert dar, während die Spalten den vorhergesagten Wert ausdrücken. In Abb. 1.9 ist die allgemeine Konfusionsmatrix dargestellt. Diese beinhaltet als Elemente die Anzahl an korrekten positiven (True Positives tp), korrekten negativen (True Negatives tn), falschen positiven (False Positives f p) und falschen negativen (False Negatives fn) Vorhersagen. Durch die Konfusionsmatrix lassen sich nun verschiedene Metriken ableiten. Die wohl einfachste PerformanceMetrik für eine Klassifikation ist die Accuracy (Genauigkeit). Diese lässt sich mit der Gleichung
acc =
tp
+
tp + tn fp + fn
+ tn
(1.2)
berechnen und gibt den Anteil an richtigen Vorhersagen an. Je näher der Wert an 1 liegt, desto besser.
Die Precision gibt den Anteil an richtig vorhergesagten positiven Ergebnissen (tp) bezogen auf die Gesamtheit aller als positiv vorhergesagten Ergebnisse an. Zum Beispiel sollte beim Spam-Filter die Precision sehr hoch sein, da wichtige E-Mails besser nicht als Spam klassifiziert werden sollten.
precision
=
tp
tp +
fp
(1.3)
Der Recall gibt den Anteil der korrekt als positiv klassifizierten Ergebnisse (tp) bezogen auf die Gesamtheit der tatsächlich positiven Ergebnisse an. Bezogen auf unseren Spam-Filter bedeutet ein hoher Recall, dass man nicht unbedingt jede SpamMail herausfiltern muss.
recall = tp
(1.4)
tp + fn
Die Metriken haben unterschiedliche Stärken und Schwächen. Die Genauigkeit (acc) ist beispielsweise recht empfindlich gegenüber Klassenungleichgewichten. Der Matthews-Korrelationskoeffizient (mcc) wird als Maß für die Qualität von binären
14
1 Einführung
und mehrklassigen Klassifikationen verwendet. Es gilt allgemein als ausgewogenes Maß, das auch bei sehr unterschiedlichen Klassengrößen eingesetzt werden kann. Der mcc ist im Wesentlichen ein Korrelationskoeffizientwert zwischen 1 und +1. Ein Koeffizient von +1 und 1 steht für eine perfekte Vorhersage, 0 für eine durchschnittliche zufällige Vorhersage.
mcc =
tptn f p fn
(tp + f p)(tp + fn)(tn + f p)(tn + fn)
(1.5)
Bisher wurden die Metriken für Klassifizierungsprobleme diskutiert. Jetzt werden verschiedene Regressionsmetriken betrachtet. Der mittlere absolute Fehler (mae) ist eine der Regressionsmetriken. Zuerst wird die Differenz zwischen dem tatsächlichen Wert y und dem vorhergesagten Wert yˆ berechnet. Dann ergibt der Durchschnitt der Absolutwerte dieser Differenzen den mae. Je näher der Wert an 0 liegt, desto besser ist die Qualität des Modells.
mae = 1 n
n
|yi yˆi |
i =1
(1.6)
Der mittlere quadratische Fehler (mse) ist eine weitere beliebte Metrik. Wie bei mae wird die Differenz zwischen den realen Werten y und vorhergesagten Werten yˆ berechnet. Aber in diesem Fall werden die Differenzen quadriert. Der Wert ist immer nicht negativ, und Werte, die näher an 0 liegen, sind besser.
mse = 1 n
n
(yi yˆi )2
i =1
(1.7)
Beispiel
Gegeben sei eine Konfusionsmatrix mit zwei Klassen. Ein trainiertes Modell kann von 35 Hunden 30 exakt vorhersagen. Auf der anderen Seite wurden von maximal 4 Katzen 2 richtig vorhergesagt.
Berechnen wir zunächst die Genauigkeit für dieses Beispiel. Wir erreichen dabei einen Wert von 0.82 und man könnte nun vermuten, dass das Modell gut zwischen Hund und Katze unterscheiden kann. Allerdings sind die Klassen sehr unausgewogen. In diesem Beispiel sind deutlich mehr Daten bei den Hunden als bei den Katzen vorhanden.
acc =
tp + tn
= 30 + 2 = 0.82
tp + f p + fn + tn
39
1.7 Bewertung und Vergleich von Algorithmen
15
Schauen wir uns nun den Matthews-Korrelationskoeffizienten an. Wir erreichen jetzt nur noch einen Wert von 0.28, welcher deutlich schlechter als die Genauigkeit ist.
mcc =
tptn f p fn
= √ 60 10 = 0.28
(tp + f p)(tp + fn)(tn + f p)(tn + fn) 32 · 35 · 4 · 7
Es stellt sich nun die Frage, welche Metrik man für die Beurteilung eines Modells heranziehen sollte. Das hängt ganz von der Problemstellung ab. In diesem Beispiel sind die Klassen sehr unausgewogen. Daher bieten sich hier Metriken an, welche diese Unausgewogenheit berücksichtigen, wie beispielsweise der MatthewsKorrelationskoeffizient.
1.7.3 Intervallschätzung
Intervallschätzung ist ein statistisches Verfahren, das verwendet wird, um eine Schätzung für einen unbekannten Parameter durchzuführen, wie z. B. den Erwartungswert oder die Standardabweichung einer Zufallsvariable. In der Praxis wird Intervallschätzung oft verwendet, um Vorhersagen für eine Zielvariable zu machen, wie z. B. die Wahrscheinlichkeit, dass ein Kunde ein bestimmtes Produkt kauft. Anstatt nur eine Vorhersage für die Wahrscheinlichkeit zu machen, wird eine Intervallschätzung erstellt, die angibt, wie sicher die Vorhersage ist.
Es gibt verschiedene Methoden zur Berechnung von Intervallschätzungen, die je nach Modell und Daten variieren können. Eine häufig verwendete Methode ist die Konfidenzintervallschätzung, die auf der Normalverteilung basiert. Das Konfidenzintervall gibt einen Bereich an, innerhalb dessen der wahre Wert des Parameters mit einer bestimmten Wahrscheinlichkeit liegt. Die Wahrscheinlichkeit wird durch das Konfidenzniveau angegeben, das üblicherweise als 95 % oder 99 % gewählt wird.
Eine weitere Methode zur Berechnung von Intervallschätzungen ist die BootstrapMethode, die auf der Wiederverwendung der vorhandenen Daten basiert. Die Bootstrap-Methode schätzt die Verteilung des Parameters, indem sie zufällig Stichproben mit Wiederholungen aus den vorhandenen Daten zieht und die Schätzwerte für jede Stichprobe berechnet. Das Konfidenzintervall kann dann aus der Verteilung der Schätzwerte abgeleitet werden.
Es ist wichtig zu beachten, dass Intervallschätzungen keine genauen Vorhersagen liefern, sondern nur eine Schätzung der Unsicherheit der Vorhersage darstellen. Je größer das Konfidenzniveau ist, desto breiter wird das Intervall und desto unsicherer wird die Vorhersage. Eine zu hohe Unsicherheit kann jedoch dazu führen, dass das Modell nicht sinnvoll verwendet werden kann.
1.7.4 Hypothesenprüfung
Die Hypothesenprüfung ist ein grundlegendes statistisches Konzept, das auch beim maschinellen Lernen Anwendung findet. Bei der Hypothesenprüfung geht es darum,
16
1 Einführung
eine statistische Aussage darüber zu treffen, ob ein bestimmtes Merkmal oder eine bestimmte Eigenschaft in einer Population vorhanden ist oder nicht. Im maschinellen Lernen wird die Hypothesenprüfung häufig eingesetzt, um zu bestimmen, ob ein Modell signifikant bessere Ergebnisse liefert als ein anderes Modell oder ob ein bestimmtes Merkmal für die Vorhersagekraft des Modells wichtig ist.
Die Hypothesenprüfung basiert auf der Formulierung von Null- und Alternativhypothesen. Die Nullhypothese besagt, dass es keinen signifikanten Unterschied oder keinen Zusammenhang zwischen den untersuchten Variablen gibt, während die Alternativhypothese besagt, dass es einen signifikanten Unterschied oder Zusammenhang gibt. Das Ziel der Hypothesenprüfung besteht darin festzustellen, ob die Daten ausreichende Beweise für die Ablehnung der Nullhypothese zugunsten der Alternativhypothese liefern.
Es gibt verschiedene statistische Tests, die für die Hypothesenprüfung verwendet werden können, wie z. B. der t-Test oder der Chi-Quadrat-Test. Diese Tests verwenden eine statistische Metrik, um den Grad der Abweichung der beobachteten Daten von den erwarteten Daten unter der Nullhypothese zu messen. Das Ergebnis des Tests wird in der Regel durch einen p-Wert ausgedrückt, der angibt, wie wahrscheinlich es ist, die beobachteten Daten unter der Annahme der Nullhypothese zu erhalten. Ein kleiner p-Wert deutet darauf hin, dass die Daten stark genug sind, um die Nullhypothese abzulehnen.
1.8 Werkzeuge und Ressourcen
In diesem Buch wird es neben den Übungen ebenfalls Programmierbeispiele geben. Es wurde sich hier für die Programmiersprache Python entschieden, da hierfür besonders viele Bibliotheken im Bereich des maschinellen Lernens vorhanden sind. Zunächst muss dafür ein Arbeitsumfeld in Form einer Entwicklungsumgebung für die Programmierung geschaffen werden. In den folgenden Kapiteln werden Sie erfahren, wie Sie Python auf Ihren Rechner installieren und die verschiedenen PythonBibliotheken verwenden können.
1.8.1 Installation von Python mit Anaconda
Eine einfache Installation von Python ist die Verwendung der Anaconda-Distribution. Anaconda ist eine freie und betriebssystemunabhängige Open-Source -Software. Darüber hinaus bietet Anaconda einige hilfreiche Eigenschaften. Viele Data-ScienceModule wie NumPy, scikit-learn, TensorFlow oder Keras können schnell und einfach in unterschiedlichen Entwicklungsumgebungen installiert werden. Ebenso sind viele Pakete in Anaconda integriert, die einem beim Entwickeln von Applikationen unterstützen.
Sie können die Anaconda-Distribution auf der Seite https://www.anaconda.com/ products/distribution herunterladen. In diesem Buch wird durchgängig die PythonVersion 3 verwendet, daher sollten Sie auch die Anaconda-Version für Pyhton 3.x
1.8 Werkzeuge und Ressourcen
17
herunterladen. Nach der Installation starten Sie den Anaconda-Navigator. Dieses Programm erlaubt die Verwaltung der verschiedenen Python-Pakete. Auf der Startseite haben Sie die Möglichkeit, unterschiedliche Applikationen unter der aktuellen Umgebung (Environment) zu starten, wie z. B. jupyter notebook, qtconsole oder spyder.
In dem Reiter Environments können Sie die verschiedenen Umgebungen anschauen. Die Base ist die per Default von Anaconda angelegte Python-Umgebung. Auf Create können weitere Python-Umgebungen hinzugefügt werden. Dadurch können unterschiedliche Entwicklungen mit individuellen Versionen der Python-Pakete durchgeführt werden. Die Python-Pakete werden ebenfalls in diesem Reiter hinzugefügt, dazu gibt man den Modulnamen in das Feld Search Packages ein, aktiviert dieses und klickt anschließend auf Apply.
Eine weitere Installationsmöglichkeit ist die Verwendung von Kommandos in einem Terminal. Das Terminal rufen Sie in Windows beispielsweise mit cmd im Startmenü auf. In Anaconda erzeugen Sie eine neue virtuelle Python-Umgebung, indem folgender Befehl in das Terminal eingegeben wird:
conda create --name machinelearning_env python=3.7
Damit ist nun eine neue Umgebung mit den Namen machinelearning_env und der Python-Version 3.7 vorhanden. Mit dem Befehl
conda activate machinelearning_env
wird die Umgebung aktiviert. Nach dem Beenden der Arbeiten sollte die selektierte Umgebung wieder deaktiviert werden:
conda deactivate
Python-Pakete können Sie wie folgt installieren:
conda install numpy
Dadurch wird das NumPy-Paket installiert. Es können auch mehrere Pakete auf einmal installiert werden, indem man die verschiedenen Paketnamen mit einem Leerzeichen aneinanderreiht.
1.8.2 Entwicklungsumgebungen
Python-Code kann man prinzipiell mit einem Texteditor (z. B. Notepad++) editieren und im Terminal ausführen. Je größer und komplexer die Projekte werden, desto mühsamer wird die Entwicklung mit diesen einfachen Mitteln. Ab einem gewissen Grad an Komplexität wird eine programmierfreundliche Umgebung gebraucht. Eine IDE (Integrated Development Environment) unterstützt einen bei der PythonEntwicklung.
Mit Microsoft Visual Studio Code können sämtliche Programmiersprachen (C#, C++, Java, Python, JSON, PHP) editiert werden. Zusätzlich bietet Visual Studio
18
1 Einführung
Code zahlreiche Erweiterungen und eine Debugging-Funktion an. Die PythonErweiterung wird wie folgt hinzugefügt:
1. Wählen Sie in der Visual Studio Code-Menüleiste Ansicht>Erweiterungen aus, um die Ansicht „Erweiterungen“ zu öffnen. Dort werden einem die empfohlenen und beliebtesten Erweiterungen im Marketplace angezeigt. Zusätzlich werden die bereits installierten und aktivierten Erweiterungen aufgelistet.
2. Geben Sie python in das Suchfeld oben in der Ansicht „Erweiterungen“ ein, um die Liste der verfügbaren Erweiterungen zu filtern.
3. Wählen Sie die von Microsoft veröffentlichte Python-Erweiterung aus. Die Details zu dieser Erweiterung werden in einem Registerkartenbereich auf der rechten Seite angezeigt.
4. Wählen Sie im Bereich „Erweiterungen“ oder im Hauptbereich Installieren aus.
Wenn Sie bereits Anaconda installiert haben, dann können Sie die AnacondaUmgebung mit Visual Studio Code verknüpfen. Drücken Sie CTRL+SHIFT+P, um die Einstellungen zu öffnen. Geben Sie „Select Interpreter“ in die Suchleiste und klicken anschließend auf „Python: Select Interpreter“. Klicken Sie nun auf „Enter Interpreter Path“ und dann auf „Find“. Dadurch wird ein Datei-Explorer-Fenster geöffnet, in dem Sie zum Speicherort des Python-Interpreters navigieren können. Sie können entweder die Basisinstallation von Anaconda „python.exe“ auswählen, oder Sie navigieren zum Ordner „envs“ und öffnen den Ordner für eine Umgebung und wählen die „python.exe“ aus. Die untere rechte Ecke von Visual Studio Code sollte jetzt aktualisiert werden und den Namen und die Python-Version der ausgewählten Umgebung anzeigen. Sollte bei der Ausführung eines Python-Skripts Fehler erscheinen, müssen eventuell noch Umgebungsvariablen angelegt werden. Geben Sie dazu Umgebungsvaiablen im Windows-Startmenü ein und wählen „Umgebungsvariablen bearbeiten“ aus. Nun gibt es die Möglichkeit, die Umgebungsvariablen zu bearbeiten. Wählen Sie „Path“ bei Systemvariablen und klicken auf „Bearbeiten“. Fügen Sie nun folgende zwei Pfade hinzu:
C:\Users\your-user-name\Anaconda3\ C:\Users\your-user-name\Anaconda3\Scripts
Darüber hinaus gibt es noch die Möglichkeit, die in Anaconda bereits integrierte IDE namens Spyder zu nutzen. Spyder steht für Scientific Python Development Envirenment. Die Umgebung ermöglicht das Editieren und Bearbeiten von PythonCode und bietet Funktionen zur Visualisierung und zum Debugging an. Sie können Spyder am schnellsten über den Anaconda-Navigator starten.
1.8.3 Python-Bibliotheken
In Python gibt es eine große Anzahl von Programmbibliotheken, die einem bei der Entwicklung die Arbeit erleichtern. In diesem Abschnitt werden einige dieser Bibliotheken kurz vorgestellt.
1.8 Werkzeuge und Ressourcen
19
Mit NumPy (Numerical Python) können numerische Berechnungen auf Datenstrukturen (Arrays bzw. Matrizen) durchgeführt werden. NumPy bietet dafür seine eigene Datenstruktur mittels der Klasse ndarray an. Eine vollständige Dokumentation aller enthaltenen Funktionen finden Sie unter https://numpy.org.
Matplotlib ermöglicht die Erstellung von wissenschaftlichen Diagrammen und Visualisierungen und kann in den unterschiedlichsten Formaten abgespeichert werden. Verwendet man matplotlib in Jupyter Notebook, dann können die Visualisierungen direkt im Notebook dargestellt werden.
Skikit-learn ist eine Open-Source-Bibliothek, welche auf NumPy, SciPy und Matplotlib aufbaut. Sie umfasst eine große Anzahl von Machine-LearningAlgorithmen für die Regression, Klassifikation und Clustering. Zusätzlich bietet Scikit-learn Funktionalitäten zur Datenvorverarbeitung, Datenreduktion und Ansätze zur Modellselektion. Zahlreiche Tutorials können Sie sich unter https://scikit-learn. org/stable/tutorial/index.html anschauen.
TensorFlow ist eine Open-Source-Plattform für maschinelles Lernen. Es verfügt über ein umfassendes, flexibles Ökosystem aus Tools, Bibliotheken und CommunityRessourcen, mit denen Forscher den Stand der Technik im Bereich ML vorantreiben und Entwickler auf einfache Weise ML-basierte Anwendungen erstellen und bereitstellen können.
Keras ermöglicht die schnelle Implementierung neuronaler Netzwerke für Anwendungen des Deep Learnings. Es handelt sich um eine Open-SourceBibliothek, die in Python geschrieben ist und zusammen mit Frameworks wie TensorFlow oder Theano verwendet werden kann.
1.8.4 Grundlagen in Python
Python ist eine hochmoderne und vielseitige Programmiersprache, die in vielen Bereichen der Softwareentwicklung eingesetzt wird. Sie hat eine klare und übersichtliche Syntax, die es Anfängern leicht macht, sich schnell in die Programmierung einzuarbeiten. Ein weiteres Plus von Python ist die große Anzahl an verfügbaren Bibliotheken und Frameworks, die die Entwicklung von Projekten erleichtern und beschleunigen. Einige Beispiele für solche Bibliotheken sind NumPy und SciPy für wissenschaftliches Rechnen, Pygame für die Entwicklung von Spielen und Django für die Entwicklung von Web-Anwendungen.
Ein Nachteil von Python ist jedoch, dass es im Vergleich zu anderen Sprachen wie C++ und Java nicht so leistungsstark ist. Es kann daher in Bereichen, in denen hohe Rechenleistung erforderlich ist, nicht immer die beste Wahl sein. Darüber hinaus kann die Ausführungsgeschwindigkeit von Python-Code auch durch die Verwendung von interpretiertem Code anstatt von Maschinencode beeinträchtigt werden.
In diesem Kapitel werden wir uns mit den folgenden Themen beschäftigen: Datentypen, Funktionen, Klassen, Kontrollstrukturen, Schleifen, Matrizen und Arrays sowie Visualisierung.
20
1 Einführung
Datentypen In Python gibt es verschiedene Datentypen, die verwendet werden können, um unterschiedliche Arten von Daten zu speichern. Die wichtigsten Datentypen sind:
1. „int“ (ganze Zahl): Beispiel: 1, 5, 0
2. „float“ (Fließkommazahl): Beispiel: 1.0, 5.5, 3.14
3. 4.
„„bstor“ol(“Z(ebiochoelensfcohlgere)W: Bereti)s:pBieeli:spHieell:lTorWueo,rFldals, ePython
5. 6. 7.
„„„ltdiuispct“tl“e(“(LW(iTsötuerpt)e:erlBb):ueBicshep)ii:sepBl:iee[il1s:,p(21ie,,l32: ],,n3[a)m,a(e,a:b,J,bohc,n]c,)age: 30
Listing 1.1 Datentypen # Beispiel Integer x=5 print(x) # Ausgabe: 5
# Beispiel Float y = 5.5 print(y) # Ausgabe: 5.5
# Beispiel String z = "Hallo Welt" print(z) # Ausgabe: Hallo Welt
# Beispiel Boolean a = True print(a) # Ausgabe: True
# Beispiel List b = [1, 2, 3, 4, 5] print(b) # Ausgabe: [1, 2, 3, 4, 5]
Sie können den Datentyp einer Variablen überprüfen, indem Sie die type()Funktion verwenden.
Listing 1.2 Überprüfen des Datentyps einer Variable x=5 print(type(x)) # Ausgabe: <class int>
y = hello print(type(y)) # Ausgabe: <class str>
Funktionen Funktionen sind in Python Teile des Codes, die bestimmte Aufgaben erfüllen und immer wieder verwendet werden können. Eine Funktion besteht aus
1.8 Werkzeuge und Ressourcen
21
einem Namen, Argumenten (optional) und einem Rückgabewert (optional). Sie können eine Funktion erstellen, indem Sie das Schlüsselwort def verwenden, gefolgt von einem Namen und einer Liste von Argumenten in Klammern. Der Rumpf der Funktion wird mit Einrückungen eingerückt.
Listing 1.3 Beispiel einer Umfang- und Flächenberechnung mit entsprechender Ausgabe def add(a, b): return a + b
result = add(3, 4) print(result) # Ausgabe: 7
Es gibt auch spezielle Funktionen, die in Python bereits vordefiniert sind, wie z. B. print(), type(), len().
Klassen Klassen sind in Python ein wichtiger Bestandteil der objektorientierten Programmierung (OOP). Eine Klasse ist eine Vorlage für ein Objekt und definiert seine Eigenschaften und Methoden. Eine Klasse wird mit dem Schlüsselwort class erstellt, gefolgt von einem Namen. Der Rumpf der Klasse wird mit Einrückungen definiert. Innerhalb der Klasse können Eigenschaften (Attribute) und Methoden definiert werden. Eigenschaften sind Variablen, die Daten speichern, während Methoden klassenbezogene Funktionen sind, die bestimmte Aufgaben ausführen.
Listing 1.4 Beispiel einer Klasse Person: def __init__(self, name, age): self.name = name self.age = age
def say_hello(self): print(fHello, my name is {self.name})
p = Person(John, 30) print(p.name) # Ausgabe: John print(p.age) # Ausgabe: 30 p.say_hello() # Ausgabe: Hello, my name is John
Kontrollstrukturen Kontrollstrukturen sind wichtig, um den Ablauf des Programms zu steuern. Die wichtigsten Kontrollstrukturen sind if, else und elif. Sie können dazu verwendet werden, um bestimmte Bedingungen zu überprüfen und entsprechende Aktionen auszuführen.
Listing 1.5 Beispiel einer Kontrollstruktur x=5 if x >= 0: print(x is positive) else: print(x is not positive)
Schleifen Schleifen ermöglichen es, bestimmte Aktionen wiederholt auszuführen. Die wichtigsten Schleifen in Python sind for und while. Der for-Schleife wird
22
1 Einführung
eine Sequenz oder eine Liste von Elementen übergeben, und die Schleife wird für jedes Element in der Sequenz ausgeführt. Der while-Schleife wird eine Bedingung übergeben, und die Schleife wird so lange ausgeführt, bis die Bedingung nicht mehr erfüllt ist.
Listing 1.6 Beispiel einer for- und while-Schleife
# for-Schleife for i in range(5):
print(i) # Ausgabe: 0 1 2 3 4
# while-Schleife i=0 while i < 5:
print(i) i += 1 # Ausgabe: 0 1 2 3 4
Matrizen und Arrays Matrizen und Arrays sind in Python durch die Verwendung von Listen (list) oder Numpy-Arrays (numpy.array) verfügbar. Mit diesen Datenstrukturen können Sie mehrdimensionale Daten speichern und entsprechende Berechnungen durchführen.
Listing 1.7 Matrix- und Array-Operationen import numpy as np
# Erstellen einer 2x3-Matrix mit numpy matrix = np.array([[1, 2,3], [4, 5, 6]]) print(matrix)
# Ausgabe: [[1 2 3]
#
[4 5 6]]
# Zugriff auf ein Element in der Matrix
print(matrix[1, 2]) # Ausgabe: 6
# Aendern eines Elements in der Matrix
matrix[1, 2] = 7 print(matrix)
# Ausgabe: [[1 2 3]
#
[4 5 7]]
# Berechnungen mit Matrizen (z.B. Matrixmultiplikation)
matrix2 = np.array([[1, 1, 1], [2, 2, 2]]) result = np.dot(matrix, matrix2.T) print(result)
1.8 Werkzeuge und Ressourcen
23
# Ausgabe: [[ 6 12]
#
[16 32]]
Visualisierungen Visualisierungen sind ein wichtiger Bestandteil der Datenanalyse und -verarbeitung. In Python gibt es viele Bibliotheken, die es ermöglichen, Daten grafisch darzustellen, wie z. B. matplotlib oder seaborn.
Listing 1.8 Visualisierung mittels Matplotlib-Bibliothek import matplotlib.pyplot as plt
# Erstellen eines einfachen Line-Plots x = [1, 2, 3, 4, 5] y = [2, 4, 6, 8, 10] plt.plot(x, y) plt.show()
Dies erstellt einen einfachen Line-Plot mit x-Werten von 1 bis 5 und y-Werten von 2 bis 10. Es gibt viele weitere Funktionen und Optionen in den verschiedenen Visualisierungsbibliotheken, die verwendet werden können, um komplexere und ansprechendere Visualisierungen zu erstellen. Es ist wichtig, die Dokumentation und Beispiele der jeweiligen Bibliotheken sorgfältig zu lesen, um das beste Ergebnis zu erzielen.
Lineare Algebra
2
Zusammenfassung
Die lineare Algebra ist ein Teilgebiet der Mathematik und beschäftigt sich mit sogenannten Vektorräumen und linearen Abbildungen. In Abschn. 2.1 werden zunächst einige Grundbegriffe erläutert. Anschließend wird in Abschn. 2.2 das Konzept von linearen Gleichungssystemen vorgestellt und wie diese analytisch bzw. numerisch gelöst werden können.
2.1 Skalare, Vektoren und Matrizen
Es werden zunächst einige grundlegende Begriffe der linearen Algebra erläutert. Der Fokus liegt dabei auf Skalaren, Vektoren und Matrizen. Diese Größen bilden die Grundlage von vielen Modellen und Algorithmen im Bereich des maschinellen Lernens. Häufig findet man in der Fachliteratur auch den Begriff des Tensors. Vereinfacht ausgedrückt ist ein Tensor eine Verallgemeinerung von Skalaren, Vektoren und Matrizen. Eine ausführlichere Beschreibung von Tensoren findet man in [1].
Skalare bzw. Tensoren nullter Stufe sind einzelne numerische Zahlenwerte. Das könnten Merkmale wie die Größe, das Gewicht oder das Alter einer Person sein.
x mit x ∈ R
(2.1)
Alle Skalare werden in diesem Buch grundsätzlich mit kleinen Buchstaben dargestellt. x kann hierbei für ein einzelnes Merkmal bzw. Feature stehen.
Ein Vektor (Tensor erster Stufe) ist eine Bezeichnung für ein Array mit einzelnen aneinandergereihten Skalaren. Die Notation ist ähnlich wie beim Skalar, jedoch
Ergänzende Information Die elektronische Version dieses Kapitels enthält Zusatzmaterial, auf das über folgenden Link zugegriffen werden kann https://doi.org/10.1007/978-3-662-67277-8_2.
© Der/die Autor(en), exklusiv lizenziert an Springer-Verlag GmbH, DE, ein Teil von
25
Springer Nature 2023
B. Botsch, Maschinelles Lernen Grundlagen und Anwendungen,
https://doi.org/10.1007/978-3-662-67277-8_2
26
2 Lineare Algebra
wird der Buchstabe zusätzlich fett gedruckt dargestellt. Je nach Ausrichtung kann man zwischen Spaltenvektoren x oder Zeilenvektoren xT unterscheiden. Das hoch-
gestellte T steht dabei für eine Transponierung des Spaltenvektors. Durch einen
Zeilen- bzw. Spaltenvektor der Dimension n kann ein Punkt im n-dimensionalen Raum Rn beschrieben werden.
⎡⎤
x1
x = ⎢⎢⎢⎣x...2⎥⎥⎥⎦ , xT = x1 x2 . . . xn
mit x ∈ Rn
(2.2)
xn
Des Weiteren besitzen Vektoren wichtige Eigenschaften, welche nachfolgend erläutert werden.
Definition 2.1 (Lineare Abhängigkeit). Vektoren sind linear abhängig, wenn man den Nullvektor als eine Linearkombination bilden kann, bei der nicht alle Koeffizienten null ergeben.
Betrachtet man nun folgende Gleichung f mit den Vektoren x1 und x2, dann sind diese genau dann linear unabhängig, wenn sich keine Koeffizienten ri finden lassen, welche die Gleichungsbedingung f = 0 erfüllen.
f = r1 · x1 + r2 · x2
(2.3)
Definition 2.2 (Kollinearität). Zwei Vektoren sind kollinear, wenn sie linear abhängig sind.
Wenn ein Vektor ein Vielfaches eines anderen Vektors ist, dann sind diese parallel und folglich kollinear.
Definition 2.3 (Orthogonalität). Zwei Vektoren sind zueinander orthogonal, wenn sie einen rechten Winkel bilden bzw. ihr Skalarprodukt gleich null ist.
Ein weiteres wichtiges Element in der linearen Algebra bilden die Matrizen (Tensoren zweiter Stufe). Sie können als zweidimensionale Arrays betrachtet werden. Eine Matrix besitzt dabei m Zeilen und n Spalten und wird durchgängig mit einem großen Buchstaben dargestellt. Der Zugriff auf ein Element einer Matrix erfolgt durch seinen Zeilen- und Spaltenindex. So beschreibt xi j das Element einer Matrix X in der i-ten Zeile und der j-ten Spalte.
x11 x12 . . . x1n
X
=
⎢⎢⎢⎣
x21 ...
x22 ...
...
x2n ...
⎥⎥⎥⎦
.
mit
X ∈ Rm×n
xm1 xm2 . . . xmn
(2.4)
2.1 Skalare, Vektoren und Matrizen
27
Mit Hilfe von Matrizen können z. B. lineare Gleichungssysteme beschrieben oder lineare Abbildungen dargestellt werden.
Beispiel
Beim maschinellen Lernen wird es oft vorkommen, dass man eine Datenmatrix konstruieren muss, damit man einen Algorithmus trainieren kann. Möchte man beispielsweise einen digitalen Zwilling eines mechanischen Systems erstellen, dann benötigt man Informationen von verschiedenen Zustandsmöglichkeiten. Man regt nun das System mit verschiedenen Eingangssignalen wt an und schaut, wie das System darauf reagiert. Die Eingangs- und Ausgangssignale yt werden aufgezeichnet und wie folgt aufgeteilt:
wt yt1 yt2 yt3
X
=
⎢⎢⎢⎣
wt 1 ...
yt 2 ...
yt 3
yt 4 ...
⎥⎥⎥⎦ ,
wtN ytN 2 ytN 3 ytN 4
⎡⎤
yt
y
=
⎢⎢⎢⎣
yt 1 ...
⎥⎥⎥⎦
.
yt N
(2.5)
Der Index t bezeichnet den diskreten Abtastzeitpunkt. Eine Zeile der Matrix X entspricht jeweils einem Datenpunkt. Zur Vorhersage des aktuellen Zustandes yt werden die drei vergangenen Zustände und die aktuelle Eingangsgröße wt des Systems verwendet. Sowohl X als auch y können anschließend verwendet werden, um einen Lernalgorithmus zu trainieren.
2.1.1 Operationen mit Skalaren und Vektoren
Für Vektoren gelten Rechenregeln, welche man auch von den Zahlen her kennt. Addiert bzw. subtrahiert man zwei Vektoren der gleichen Länge, dann resultiert auch wieder ein Vektor mit derselben Größe. Die Einträge der Vektoren werden jeweils elementweise addiert bzw. subtrahiert:
uT + vT = u1 . . . un + v1 . . . vn = v1 + u1 . . . vn + un .
(2.6)
Die Vektorsubtraktion wird auf die gleiche Weise definiert:
uT vT = u1 . . . un v1 . . . vn = v1 u1 . . . vn un .
(2.7)
Die Addition ist kommutativ, wegen u + v = v + u, die Subtraktion allerdings nicht. Man kann die Addition auch geometrisch interpretieren, indem man die Vektoren uT = [1, 2] und vT = [3, 1] in ein Koordinatensystem einträgt, siehe Abb. 2.1. Die beiden Vektoren bilden mit der Summe uT + vT = [4, 3] und dem Koordinatenursprung ein Parallelogramm. Hier wird nochmals das Kommutativgesetz deutlich
dargestellt. Es spielt keine Rolle, ob man von u aus v abträgt oder umgekehrt. Man
landet immer im gleichen Endpunkt. Ein Anwendungsbeispiel der Vektoraddition
28
2 Lineare Algebra
Abb. 2.1 Die Punkte u + v, u, v und 0 spannen im zweidimensionalen Raum ein Parallelogramm auf
ist das Superpositionsprinzip. Wirken auf einen Körper mehrere Kräfte, dann kann man diese auch durch eine einzelne resultierende Kraft darstellen, indem man die vektorielle Summe der einzelnen Kräfte bildet.
Ebenso kann ein Vektor x mit einem Skalar a multipliziert werden, wobei jede Komponente des Vektors xi mit diesem Skalar multipliziert wird.
axT = ax1 . . . axn
(2.8)
Durch die Multiplikation mit einem Skalar wird die Länge des Vektors skaliert, allerdings bleibt die Richtung weiterhin erhalten. Die Länge eines Vektor wird durch seine Norm bestimmt. Allgemein lässt sich die Norm eines Vektors durch
x p=
n
|xi |p
i =1
(1/ p)
(2.9)
definieren. Der Ausdruck | · | gibt den absoluten Wert eines Skalars an und p ist ein positiver Integerwert.
Vektoren können ebenso miteinander multipliziert werden. Ein mögliches Pro-
dukt wäre das Skalarprodukt (inneres Produkt). Betrachtet man zwei Vektoren uT = [u1 . . . un] und vT = [v1 . . . vn], dann ist das Skalarprodukt die Summe der elementweisen Multiplikation ihrer Komponenten.
n
u · v = ui vi
i =1
(2.10)
2.1 Skalare, Vektoren und Matrizen
29
Wie in der Definition 2.3 bereits angedeutet wurde, wird das Skalarprodukt zur Berechnung von Winkeln zwischen Vektoren benutzt. In der Physik verwendet man das Skalarprodukt zur Berechnung der Arbeit, also das Produkt von Weg und Kraft.
Ein weiteres Produkt ist das Vektor- bzw. Kreuzprodukt. Das Ergebnis ist ein neuer Vektor mit der gleichen Dimension, der zu den ursprünglichen Vektoren orthogonal ist. Die Länge dieses Vektors entspricht dem Flächeninhalt des Parallelogramms, welches von den Vektoren u und v aufgespannt wird.
⎡⎤ ⎡⎤ ⎡
u1
v1
u2 · v3 u3 · v2
u × v = ⎣u2⎦ × ⎣v2⎦ = ⎣u3 · v1 u1 · v3⎦ .
u3
v3
u1 · v2 u2 · v1
(2.11)
Beispiel
Im folgenden Beispiel wird der Schwerpunkt von einer endlichen Anzahl von
Massenpunkten berechnet. Gegeben seien drei Massen m1 = 1, m2 = 2 und
m3 = 3 mit ihren Ortsvektoren r1 =
0 2
, r2
=
3 2
und r3 =
2 4
im R2. Der
Schwerpunkt eines Körpers ist wie folgt definiert:
s
=
1 m
n
mi ri
i =1
mit
m = m1 + . . . + mn.
Setzen wir nun die einzelnen Massen und Ortsvektoren in die Gleichung ein, dann erhalten wir als Schwerpunkt folgenden Vektor:
s= 1 6
1
0 2
+2
3 2
+3
2 4
=
2 3
.
2.1.2 Operationen mit Vektoren und Matrizen
Matrizen können genau wie Vektoren addiert oder subtrahiert werden. Betrachten wir zwei Matrizen A = (ai j ) und B = (bi j ) mit Rm×n, dann werden jeweils ihre
Komponenten addiert bzw. subtrahiert.
A + B = (ai j + bi j )
(2.12)
Es wird vorausgesetzt, dass beide Matrizen die gleiche Dimension besitzen. Betrachten wir nun das Matrizenprodukt. Hier müssen die Dimensionen nicht
unbedingt gleich sein, allerdings komplett willkürlich dürfen diese auch nicht sein. Das Matrizenprodukt A · B gilt nur, wenn die Anzahl der Spalten von A gleich der
30
2 Lineare Algebra
Anzahl der Zeilen von B ist. Ist dies der Fall, wird das Matrizenprodukt durch die Gleichung
n
A · B = cik mit cik = (ai j · b jk )
j =1
(2.13)
definert. Ein Vektor aT kann ebenso mit einer Matrix B multipliziert werden, wobei als Ergebnis wieder ein Vektor resultiert.
b11 b12 b13
aT · B = a1 a2 a3 · ⎣b21 b22 b23⎦ = c1 c2 c3
b31 b32 b33
(2.14)
⎧ ⎪⎨c1 = a1b11 + a2b21 + a3b31
mit
⎪⎩cc23
= =
a1b12 + a2b22 + a3b32 a1b13 + a2b23 + a3b33
(2.15)
Die Transponierung einer Matrix erhält man durch Spiegeln ihrer Zeilen und
Spalten. Mit anderen Worten, der (i, j)-te Eintrag der Transponierten ist derselbe
wie der ( j, i)-te Eintrag der ursprünglichen Matrix. Daher ist die Transponierte
einer n × d-Matrix eine d × n-Matrix. Die Transponierte einer Matrix A wird mit
AT bezeichnet.
⎡ a11
a12⎤T
⎣a21 a22⎦ =
a31 a32
a11 a21 a31 a12 a22 a32
(2.16)
Die Transponierte der Summe zweier Matrizen ergibt sich aus der Summe der Transponierten.
(A + B)T = AT + BT
(2.17)
Die Transponierte des Produkts zweier Matrizen ist das Produkt ihrer Transponierten, allerdings wird die Reihenfolge der Multiplikation umgekehrt.
(AB)T = BT AT
(2.18)
2.1.3 Die Inverse einer Matrix
Die Invertierung einer quadratischen Matrix A ergibt eine andere quadratische Matrix mit A1. Die Multiplikation der beiden Matrizen (in beliebiger Reihenfolge) ergibt
die Einheitsmatrix I.
AA1 = A1A = I
(2.19)
Wenn A und B invertierbar sind, dann ist ebenso das Produkt AB invertierbar.
(AB)1 = B1A1
(2.20)
2.2 Lineare Gleichungssysteme
31
Eine Matrix A ∈ Rn×n gilt ist invertierbar, wenn der Rang dieser Matrix gleich n ist. Die Inverse bestimmt man nun wie folgt. Zunächst schreibt man (A|I). Dann bringt man (A|I) auf die Form (D|B), wobei D eine obere Dreiecksmatrix ist. Entsteht in
der Matrix D eine Nullzeile, ist A nicht invertierbar. Enthält D keine Nullzeile, dann resultiert (A|I) → (I|A1).
2.2 Lineare Gleichungssysteme
Ein Gleichungssystem besteht grundsätzlich aus mehreren Gleichungen mit zugrunde liegenden Unbekannten. Die Linearität weist darauf hin, dass die Unbekannten nur in erster Potenz auftauchen und in keiner Funktion eingebunden sind. Bei einem Gleichungssystem schreibt man häufig die Summanden mit den Unbekannten auf die linke Seite und das Absolutglied auf die rechte Seite. Betrachten wir die unbekannten Größen x1, x2. Mit diesen beiden Unbekannten lässt sich folgendes Gleichungssystem aufstellen:
x1 x1
+
x2 x2
= =
02.
(2.21)
Möchte man das Gleichungssystem lösen, werden die reellen Zahlen gesucht, die anstelle von x1 und x2 eingesetzt werden können, um die Gleichungen des Systems zu erfüllen.
Lineare Gleichungssysteme müssen nicht immer eine Lösung besitzen. Betrachten wir die Gleichungen
x1 x2 = 1 x1 x2 = 0
(2.22)
mit den Unbekannten x1 und x2. Setzt man die eine Gleichung in die andere Gleichung ein, wird man erkennen, dass sich keine Lösung finden lässt. Darüber hinaus kann der Fall eintreten, dass unendlich viele Lösungen möglich sind. Betrachten wir dazu das folgende lineare Gleichungssystem:
3x1 x1
+
6x2 2x2
= =
00.
(2.23)
Die zweite Gleichung ist das (1/3)-Fache der ersten Gleichung. Sie besitzt also keine zusätzlichen Informationen und wird daher nicht weiter betrachtet. Es bleibt
die erste Gleichung übrig. Man kann nun für x1 beliebige Zahlen einsetzen und damit x2 berechnen. Die Lösungsmenge kann definiert werden mit L = {(2t, t)|t ∈ R} und besitzt somit unendlich viele Lösungen.
2.2.1 Gauß-Algorithmus
Lineare Gleichungssysteme können mit dem Eliminationsverfahren von Gauß gelöst werden. Dabei wird die erweiterte Koeffizientenmatrix (A|b) auf Zeilenstufenform
32
2 Lineare Algebra
gebracht. Anschließend wird das Lösbarkeitskriterium überprüft. Das Kriterium besagt, dass der Rang der Koeffizientenmatrix rgA und der Rang der erweiterten Koeffizientenmatrix rg(A|b) gleich sein müssen. Ist dies der Fall, dann ist das Gleichungssystem lösbar. Zuletzt wird durch das Rückwärtseinsetzen die Lösung des Systems bestimmt.
Beispiel
Wir betrachten das lineare Gleichungssystem
x1 + 4x2 = 2 3x1 + 5x2 = 7
mit der erweiterten Koeffizientenmatrix
14 35
2 7
.
Die erweiterte Koeffizientenmatrix wird nun mittels Umformungen auf Zeilenstufenform gebracht. Die zweite Zeile wird mit dem (3)-Fachen der ersten Zeile subtrahiert:
14 35
2 7
.→
14 0 7
2 1
Damit ergibt sich folgendes Gleichungssystem:
x1
+
4x2 7x2
= =
21.
Durch das Rückwärtseinsetzen folgt für x2 der Wert (1/7). Setzt man x2 nun in die erste Gleichung ein und formt die Gleichung nach x1 um, folgt x1 = 18/7.
2.2.2 Numerische Lösungsmethoden linearer Gleichungssysteme
Im vorherigen Kapitel haben wir gesehen, wie man lineare Gleichungssysteme per Hand berechnen kann. Steigt die Größe des Gleichungssystems weiter an, so steigt auch der Aufwand, dieses zu lösen. Es bietet sich also an, die Berechnungen von einem Computer durchführen zu lassen. Eine näherungsweise Lösung von linearen Gleichungssystemen kann mit dem Verfahren von Gauß-Seidel berechnet werden. Dabei wird die k-te Gleichung nach der k-ten Variablen xk aufgelöst.
xk(m+1)
=
1 ak,k
k1
n
bk
ak,i xi(m+1)
ak,i xi(m)
i =1
i =k +1
(2.24)
Für dieses Verfahren wird vorausgesetzt, dass alle Diagonalelemente ak,k von null verschieden sein müssen. Im Programmierbeispiel 2.1 ist die Implementierung des
2.2 Lineare Gleichungssysteme
33
Gauß-Seidel-Verfahrens dargestellt. Ausgehend vom Startvektor x0 werden iterativ weitere Näherungen berechnet. Die Schleife wird unterbrochen, sobald eine Iterierte gefunden wurde, die nahe an der exakten Lösung Ax = b liegt.
Listing 2.1 Gauß-Seidel-Verfahren
def gaussSeidel(A,b,x,e): """ Solves the equation Ax=b via the Gauss-Seidel-method. Parameters: ----------A : array coefficient matrix b : array the right-hand side of the system of equations x : array initial vector e : int error condition Returns: -------x : array solution """ error = norm(dot(A,x)-b) n=b.shape[0] xnew = zeros(n) while error>e: x = xnew.copy() for i in range(0,n): xnew[i] = (b[i] sum([A[i, j]*x[j] for j in range(i+1, n )]) sum([A[i, j]*xnew[j] for j in range(i) ]))/A[i, i] error = norm(dot(A,x)-b) return x
Wahrscheinlichkeit und Statistik
3
Zusammenfassung
Die Wahrscheinlichkeitsrechnung und die mathematische Statistik gehören zur Mathematik der Daten und des Zufalls. Oft werden diese unter der gemeinsamen Bezeichnung Stochastik geführt. Es werden zunächst einige Grundbegriffe der Wahrscheinlichkeit erläutert. Anschließend wird das Konzept von Zufallsgrößen und Verteilungsfunktionen beschrieben und welche Eigenschaften diese besitzen. Es wird ebenfalls die deskriptive Statistik behandelt, welche sich mit der Beschreibung von Datensätzen und deren Eigenschaften befasst. Zum Schluss werden einige statistische Tests vorgestellt.
3.1 Grundbegriffe der Wahrscheinlichkeit
Durch die Verwendung der Wahrscheinlichkeit lassen sich zufällige Ereignisse erfolgreich beschreiben. Was sind nun aber Ereignisse? Betrachten wir dazu einen Würfel, den wir werfen. Es können die Ereignisse {1} bis {6} eintreten. Die einzelnen Ereignisse können zu einer Obermenge (auch Grundgesamtheit genannt)
= {1, 2, 3, 4, 5, 6} zusammengefasst werden. Die Obermenge nennt man auch das sichere Ereignis. Das Komplement von , also die leere Menge ∅, nennt man das unmögliche Ereignis. Ereignisse können darüber hinaus durch logische Operationszeichen verknüpft werden. Betrachten wir dazu die Ereignisse A = {1, 2, 3} und B = {3, 4, 5}. Das Ereignis von A ∩ B (Durchschnitt) ist {3} und das Ereignis A B (Vereinigung) ist {1, 2, 3, 4, 5}. Neben den Operationszeichen ∩ und gibt
Ergänzende Information Die elektronische Version dieses Kapitels enthält Zusatzmaterial, auf das über folgenden Link zugegriffen werden kann https://doi.org/10.1007/978-3-662-67277-8_3.
© Der/die Autor(en), exklusiv lizenziert an Springer-Verlag GmbH, DE, ein Teil von
35
Springer Nature 2023
B. Botsch, Maschinelles Lernen Grundlagen und Anwendungen,
https://doi.org/10.1007/978-3-662-67277-8_3
36
3 Wahrscheinlichkeit und Statistik
es in der Mengenlehre noch die De Morgansche Regel.
A∩B= AB
(3.1)
Mit den Mengenoperationen ∩ und kann ebenso gerechnet werden. Das nachfolgende Beispiel beschreibt die Anwendung des Distributivgesetzes. Die Klammern verdeutlichen die Reihenfolge der Operationen.
(A ∩ (A B)) (B ∩ (A B)) = (A ∩ A) (A ∩ B) (B ∩ A) (B ∩ B) (3.2)
Betrachten wir nun eine endliche Folge aus dem Ereignisfeld S, wobei S eine Menge von Teilmengen einer Obermenge ist.
n
Ai ∈ S
i =0
(3.3)
Jedem Element Ai von S kann eine sogenannte Wahrscheinlichkeit P(Ai ) zugeordnet werden. P ist die Mengenfunktion und wird auch als Wahrscheinlichkeitsmaß oder Wahrscheinlichkeitsverteilung bezeichnet und besitzt die folgenden 3 Axiome:
I. 0 ≤ P(A) ≤ 1 mit A ∈ S
II. P( ) = 1
III. P
Ai
i =0
= P(Ai )
i =1
(3.4) (3.5)
(3.6)
Das Tripel [ , S, P] heißt Wahrscheinlichkeitsraum. Im weiteren Verlauf werden wir uns aber vorrangig mit der Wahrscheinlichkeit P beschäftigen.
Beispiel
Betrachten wir einen Würfel mit den 6 möglichen Ereignissen 1, 2, 3, 4, 5 und 6. Das Ereignisfeld dieser 6 Ereignisse ist die Potenzmenge von . Damit besteht S aus den folgenden 26 Ereignissen:
S = {∅, {1}, {2}, {3}, {4}, {5}, {6}, {1, 2}, {1, 3}, ..., {1, 2, 3, 4, 5, 6}}.
3.2 Zufallsgrößen und Verteilungsfunktionen
37
Abb. 3.1 Die Zufallsgröße X bildet in R ab
3.2 Zufallsgrößen und Verteilungsfunktionen
Eine Zufallsgröße (Zufallsvariable) X , wie beispielsweise die Augenzahl eines Würfels, ist eine Abbildung des Wahrscheinlichkeitsraumes [ , S, P] → [R, B, PX ]. Jedem Element w aus wird eine reelle Zahl X (w) ∈ R zugeordnet. PX ordnet jedem Ereignis B ∈ B eine Wahrscheinlichkeit PX (B) zu. B bezeichnet eine Borel-Menge und ist eine in der Borelschen σ -Algebra enthaltene Menge. Anders
formuliert, die Zufallsgröße hat die Aufgabe, die grob beschriebenen Ereignisse im Raum [ , S, P] auf die reelle Achse zu transformieren (siehe Abb. 3.1).
Eine Zufallgröße kann nun in verschiedenen Formen zugrunde liegen. Ist sie diskret, sind endlich bzw. abzählbar viele Werte x1, x2, . . . vorhanden. Diese Werte treten mit einer bestimmten Wahrscheinlichkeit p1, p2, . . . auf, wobei p1+ p2+. . . = 1 gilt. Ebenso kann eine Zufallsgröße stetig sein, falls es eine nichtnegative Funktion y = fX (x) mit dem Flächeninhalt
+∞
f X (x)d x = 1
−∞
(3.7)
über der x-Achse gibt. Zusätzlich gilt für jedes Ereignis B ∈ B:
PX (B) = P(X ∈ B) = f X (x)d x.
(3.8)
B
PX (B) beschreibt die Wahrscheinlichkeit für ein Ereignis in R und ist im Falle einer stetigen Zufallsgröße X der Flächeninhalt unter dem Graphen von fX (x) oder im Falle einer diskreten Zufallsgröße entsprechend die Summe. Eine Intervallwahrscheinlichkeit P(X ∈ [a, b]) kann nun mit einem Integral über eine Wahrscheinlichkeitsdichtefunktion bzw. einer Summe über diskreter Einzelwahrscheinlichkeiten berechnet werden.
Kommen wir zu einem weiteren wichtigen Begriff in der Stochastik, nämlich der Verteilungsfunktion. Eine Verteilungsfunktion F : R → [0, 1] ist eine von rechts stetige und monoton wachsende Funktion von x. Eine Verteilungsfunktion besitzt verschiedene Eigenschaften. Die Wahrscheinlichkeit, dass X den Wert x überschreitet, ist durch 1 F(x) = P(X > x) definiert. Ebenso beschreibt P(a < X ≤ b) = F(b) F(a) eine Wahrscheinlichkeit, das X im Intervall (a, b] liegt.
38
3 Wahrscheinlichkeit und Statistik
Abb. 3.2 Verteilungsfunktion einer diskreten Gleichverteilung
Betrachten wir als Beispiel die Verteilungsfunktion einer diskreten Gleichverteilung (siehe Abb. 3.2). Bei einem Würfel gilt für die Zufallsgröße X ∈ {1, 2, 3, 4, 5, 6} und den dazugehörigen Wahrscheinlichkeiten pk = P(X = k) = 1/6.
Die Verteilungsfunktion wird wie folgt beschrieben:
⎪⎪⎪⎪⎪⎪⎪⎪⎨
0, 1/6, 2/6,
−∞ < x < 1, 1 ≤ x < 2, 2 ≤ x < 3,
F(x)
=
⎪⎪⎪⎪⎪⎪⎪⎪⎩
3/6, 4/6, 5/6, 1,
3 ≤ x < 4, 4 ≤ x < 5, 5 ≤ x < 6, 6 ≤ x < ∞.
(3.9)
Die Wahrscheinlichkeit, dass eine Zahl größer gleich 1 und kleiner 4 ist, lässt sich mit der Verteilungsfunktion sehr schnell ermitteln. Die Wahrscheinlichkeit beträgt demnach 50 %.
P(1 ≤ X < 4) = F(4) F(1) = 4/6 1/6 = 1/2
(3.10)
Es existieren noch deutlich mehr Verteilungsfunktionen, wie beispielsweise bei der Normalverteilung, Rechteckverteilung oder Exponentialverteilung. Diese werden allerdings nicht näher betrachtet und es wird daher auf die einschlägige Literatur von Wolfgang Preuß und Günter Wenisch [2] verwiesen.
3.3 Momente einer Verteilung
Momente einer Verteilung sind ein wichtiges Konzept in der Wahrscheinlichkeitstheorie und Statistik. Sie sind mathematische Kennzahlen, die es ermöglichen, eine Verteilung zu charakterisieren und zu vergleichen. Momente können sowohl für diskrete als auch stetige Verteilungen definiert werden und dienen als Grundlage für viele weitere statistische Methoden und Modelle.
3.3 Momente einer Verteilung
39
3.3.1 Erwartungswert und Streuung
Betrachten wir nun die Wahrscheinlichkeitsverteilung einer Zufallsgröße X . Oft
möchte man Lage- und Streuungsparameter bei Wahrscheinlichkeitsverteilungen
berechnen. Der Lageparameter bzw. Erwartungswert E(X ) einer Zufallsgröße X
wird durch
⎧ ⎨
∞ i =0
xi
pi
,
E(X ) := ⎩
∞ −∞
x
f
(x
)d
x
,
falls X diskret falls X stetig
(3.11)
berechnet. Für einen Erwartungswert gelten zudem folgende Eigenschaften:
E(a X + b) = a E(X ) + b,
(3.12)
wobei a und b Konstanten sind. Sind X und Y beliebige Zufallsgrößen, dann gilt
E(X + Y ) = E(X ) + E(Y ).
(3.13)
Sind X und Y unabhängig voneinander, dann gilt zusätzlich E(X · Y ) = E(X ) · E(Y ).
(3.14)
Der Erwartungswert lässt sich zum Begriff des Momentes verallgemeinern. Sofern die Erwartungswerte existieren, heißt E(X k) das k-te Moment der Zufallsgröße X
bzw. der Verteilung F.
Beispiel
Betrachten wir wieder als Beispiel das Werfen eines Würfels. Es wird vorausgesetzt, dass die Wahrscheinlichkeiten der zufälligen Augenzahl gleich sind. Der Erwartungswert der Augenzahl beträgt demnach
E(X ) = 6 i 1 = 3, 5. i=1 6
Existiert bei einer Häufigkeits- bzw. Wahrscheinlichkeitsverteilung der Erwartungswert, kann man zusätzlich eine Varianz (Streuung) berechnen. Die Varianz ist definiert als Mittelwert der quadrierten Abweichungen der Werte der Zufallsgröße X von ihrem Erwartungswert E(X ):
⎧ ⎨
i∞=0(xi E (X ))2 pi
falls X diskret,
Var(X ) := ⎩ −∞∞(x E(X ))2 f (x)d x falls X stetig.
(3.15)
40
3 Wahrscheinlichkeit und Statistik
Zieht man zusätzlich die Wurzel der Varianz, erhält man die Standardabweichung. Der Erwartungswert und die Standardabweichung können nun dazu verwendet werden, eine Zufallsgröße X zu zentrieren und zu normieren.
Z = X√ E(X ) Var(X )
(3.16)
Z beschreibt eine standardisierte Zufallsgröße, die zentriert und normiert ist.
3.3.2 Schiefe und Exzess
Eine Zufallsgröße X besitzt noch weitere Kennzahlen, beispielsweise die Schiefe γ1 und den Exzess γ2. Berechnet werden sie durch das dritte bzw. vierte Anfangsmoment einer standardisierten Zufallsgröße Z .
γ1 = E(Z 3) = E
X E(X) 3 √
Var(X )
(3.17)
Die Schiefe charakterisiert die Asymmetrie einer Verteilung. Falls γ1 > 0 ist, nennt man die Verteilung rechtsschief, für γ1 < 0 entsprechend linksschief. Ein negativer Versatz zeigt an, dass es sich um eine nach links geneigte Verteilung handelt. Ein positiver Versatz zeigt an, dass es sich um eine nach rechts geneigte Verteilung handelt. Die Berechnung der Schiefe ist in Listing 3.1 dargestellt. Die Funktion skew(x) berechnet den Wert für die Schiefe. mean(x) und std(x) sind Hilfsfunktionen und berechnen jeweils den Mittelwert und die Standardabweichung.
Listing 3.1 Berechnung der Schiefe einer Zufallsgröße X
def mean(x): mean=0 for xi in x: mean+=xi return mean/len(x)
def std(x): std=0 x_mean = mean(x) for xi in x: std +=( xi - x_mean ) **2 return np.sqrt(std/(len(x)))
def skew(x): x_mean = mean(x) x_std = std(x) skew = ((x-x_mean)/x_std)**3 return mean(skew)
3.4 Bedingte Wahrscheinlichkeiten
41
Der Exzess γ2 ist ein Maß für die Abweichung einer Verteilung im Vergleich zu einer Normalverteilung.
γ2 = E(Z 4) 3 = E
X√ E(X ) 4 3 Var(X )
(3.18)
Der Exzess einer Normalverteilung beträgt 3. In einigen Gleichungen in der Literatur wird von dem Exzess eine 3 subtrahiert, um den Vergleich mit der Normalverteilung zu erleichtern.
3.4 Bedingte Wahrscheinlichkeiten
Die bedingte Wahrscheinlichkeit verknüpft zwei zufällige Ereignisse miteinander. Ist ein Ereignis B eingetreten, bewirkt dies eine Änderung der Wahrscheinlichkeit von A. Die bedingte Wahrscheinlichkeit ist definiert als
P(A|B) =
P
(A ∩ B) P(B)
,
(3.19)
wobei A|B das bedingte Ereignis darstellt. Sind A und B unabhängige Ereignisse, gilt
P(A ∩ B) = P(A|B)P(B) = P(B|A)P(A).
(3.20)
Aus dieser Formulierung resultiert nun die Bayes-Formel.
P(A|B) =
P ( B | A) P(B)
P(
A)
(3.21)
P(A) ist die A-priori-Wahrscheinlichkeit und P(A|B) die A-posterioriWahrscheinlichkeit von A. Der Satz von Bayes ist die einfachste Formulierung.
Durch den Satz der totalen Wahrscheinlichkeit kann die Bayes-Formel verallgemeinert werden.
n
n
P(B) = P(B ∩ Ai ) = P(B|Ai )P(Ai )
i =1
i =1
(3.22)
Man nennt P(B) die unbedingte bzw. totale Wahrscheinlichkeit. Jedes Ai beschreibt mit B ∩ Ai einen möglichen Fall innerhalb von B. Setzt man nun die Formel der totalen Wahrscheinlichkeit in die Bayes-Formel ein, resultiert die Bayessche Formel.
P(Ai |B)
=
P(B ∩ Ai ) P(B)
=
P(B|Ai )P(Ai )
n i =1
P(B|Ai )P(Ai )
(3.23)
42
3 Wahrscheinlichkeit und Statistik
Beispiel
Betrachten wir als Beispiel eine Produktion mit drei Maschinen M1, M2 und M3. Jede der Maschinen erzeugt pro Tag einen gewissen Ausschuss mit M1: 500 Stück, 4 % Ausschuss, M2: 300 Stück, 5 % Ausschuss, M3: 200 Stück, 2 % Ausschuss. Wir berechnen zunächst die Wahrscheinlichkeit, dass ein zufällig ausgewähltes Erzeugnis ein Ausschuss ist. Dass ein zufällig ausgewähltes Ereignis von der Maschine Mi stammt, definieren wir als Ai . Mit B bezeichnen wir ein zufällig ausgewähltes Erzeugnis, welches Ausschuss ist. Mit der Formel der totalen Wahrscheinlichkeit können wir zunächst den Ausschuss berechnen.
P(B) =
3
P(B|Ai )P(Ai )
=
0.04
·
5 10
+
0.05
·
3 10
+
0.02
·
2 10
=
0.039
i =1
Die Wahrscheinlichkeit beträgt somit 3.9 %, dass ein zufällig ausgewähltes Erzeugnis ein Ausschuss ist. Zusätzlich wollen wir wissen, ob ein zufällig ausgewähltes Erzeugnis von der Maschine M1 stammt. Wir benutzen dazu die Bayessche Formel:
P(A1|B) =
P ( B | A1) P ( A1) P(B)
=
0.04 · (5/10) 0.039
= 0.51.
3.5 Deskriptive Statistik
Die deskriptive Statistik befasst sich mit der Gewinnung, Aufbereitung und Dar-
stellung von Daten. Eine Stichprobe (X1, X2, ..., Xn)T (mathematische Stichprobe) liefert die Realisierungen (x1, x2, ..., xn)T (konkrete Stichprobe) aus einer Grund-
gesamtheit X . Der empirische Mittelwert x¯ resultiert aus der konkreten Stichprobe.
1n
x¯ = n
xi
i =1
(3.24)
Der empirische Mittelwert ist ein Lageparameter und beschreibt das Zentrum der
konkreten Stichprobe. Ein weiterer Lageparameter ist der Median xmed . Zur Bestim-
mung des Medians müssen die Daten zunächst sortiert werden. Bei einer ungera-
den
Anzahl
von
Daten
ist
der
Median
x n+1 , 2
ansonsten
1 2
(x
n 2
+
x
n 2
+1
).
Der
Modus
xmod beschreibt die am häufigsten vorkommende Realisierung einer Stichprobe. Der
Modus ist also das Maximum einer Verteilung.
Streuungsparameter fassen in der deskriptiven Statistik verschiedene Parameter
zusammen, um die Streubreite von Werten einer Häufigkeitsverteilung um einen
3.5 Deskriptive Statistik
43
Abb. 3.3 Darstellung einer Verteilungsfunktion und dem daraus konstruierten Boxplot mit den fünf Werten Minimum, unteres Quartil x25, Median x0.5, oberes Quartil x0.75 und dem Maximum
geeigneten Lageparameter herum zu beschreiben. Die empirische Streuung s2 ergibt sich mittels eines empirischen Mittelwerts durch die Gleichung:
s2
=
n
1
1
n
(xi x¯)2.
i =1
(3.25)
Ist der Mittelwert μ von vornherein bekannt, kann die Summe der quadratischen Abweichungen mit n anstatt n 1 normiert werden. Die Gleichung
r = max(x1, x2, ..., xn) min(x1, x2, ..., xn)
(3.26)
berechnet die Spannweite. Die Spannweite ist der Abstand zwischen dem kleinsten und dem größten Wert einer Stichprobe. Die Spannweite ist recht empfindlich gegenüber Ausreißern und hängt stark vom Stichprobenumfang ab. Ein robusteres Streuungsmaß ist der sogenannte Quartilsabstand. Der Quartilsabstand beschreibt die Streuung einer Verteilung, indem die Differenz zwischen dem x0.75- und dem x0.25-Quartil berechnet wird.
Mit den beschriebenen Lage- und Streuungsparametern können nun Verteilungsfunktionen und Histogramme eindeutig charakterisiert und verglichen werden. Einige dieser Parameter sind in Abb. 3.3 dargestellt. Anhand einer Verteilungsfunktion werden die Parameter Minimum, unteres Quartil x25, Median x0.5, oberes Quartil x0.75 und Maximum ermittelt. Zur Darstellung dieser Parameter wird ein sogenannter Boxplot verwendet. Man erkennt eine leichte Unsymmetrie bei der Verteilung der Daten, da der Median etwas näher am oberen Quartil liegt.
Wir haben nun gesehen, wie man charakteristische Parameter von einer Verteilung bzw. einer Zufallsgröße berechnen kann. Man kann darüber hinaus mehrere
44
3 Wahrscheinlichkeit und Statistik
Zufallsgrößen zu einem Vektor zusammenfassen. X kann beispielsweise der Verlauf
einer Versuchsserie sein.
¯
X ¯
=
(X1,
X2,
...,
X n )T
Die Einzelwahrscheinlichkeiten von X sind durch ¯
(3.27)
P
X ¯
=
(x1,
x2,
...,
xn )T
(3.28)
definiert. Zur Beschreibung des Zusammenhanges mehrerer Zufallsgrößen verwendet man häufig die Kovarianz oder die Korrelation. Die Kovarianz ist definiert als
cov(x,y) = 1 n
n
(xi x¯)(yi y¯).
i =1
(3.29)
Die Kovarianz ist abhängig von den Dimensionen, in denen die Zufallsgrößen gemes-
sen werden. Sie ist daher an sich schwer interpretierbar. Ein besseres Maß für den
Zusammenhang mehrerer Zufallsgrößen ist die Korrelation bzw. der Korrelations-
koeffizient.
r (x,y) = √
cov(x,y) √
var(x) var(y)
(3.30)
Der Korrelationskoeffizient ist auf das Intervall [1, +1] beschränkt. Ist r (x, y) = 1 oder r (x, y) = 1, dann besteht zwischen x und y ein linearer Zusammenhang. Ist r (x, y) = 0, sind die beiden Zufallsgrößen entsprechend unkorreliert.
3.6 Einfache statistische Tests
Statistische Tests sind Verfahren, die verwendet werden, um zu bestimmen, ob es einen signifikanten Unterschied zwischen zwei oder mehreren Gruppen oder Beobachtungen gibt. Sie ermöglichen es, Schlussfolgerungen über eine Population aufgrund von Beobachtungen in einer Stichprobe zu treffen.
Ein wichtiger Aspekt von statistischen Tests ist die Annahme von Nullhypothesen und Alternativhypothesen. Die Nullhypothese besagt, dass es keinen Unterschied zwischen den Gruppen oder Beobachtungen gibt, während die Alternativhypothese besagt, dass es einen Unterschied gibt. Der statistische Test wird dann verwendet, um die Stärke der Beweise für die Alternativhypothese zu bestimmen. Wenn die Beweise für die Alternativhypothese stark genug sind, wird die Nullhypothese verworfen und es wird angenommen, dass es einen Unterschied zwischen den Gruppen oder Beobachtungen gibt.
Es gibt viele verschiedene Arten von statistischen Tests, die je nach Art der Daten und Fragestellung verwendet werden können. Einige Beispiele sind: t-Tests, diese werden verwendet, um zu bestimmen, ob es einen Unterschied zwischen zwei Mittelwerten in unabhängigen oder abhängigen Gruppen gibt. ANOVA (Analysis of Variance) wird verwendet, um zu bestimmen, ob es einen Unterschied zwischen
3.6 Einfache statistische Tests
45
den Mittelwerten von mehr als zwei Gruppen gibt. Schlussendlich gibt es noch den Chi-Quadrat-Test, dieser überprüft, ob es einen Unterschied in der Verteilung von Merkmalen innerhalb einer Gruppe oder zwischen Gruppen gibt.
Es ist wichtig zu beachten, dass statistische Tests nur als Hilfsmittel zur Unterstützung von Schlussfolgerungen verwendet werden sollten und dass sie oft in Verbindung mit anderen Analysen und Interpretationen verwendet werden. Ein weiterer wichtiger Aspekt ist das Konzept des Fehlers, insbesondere des Typ-I- und -IIFehlers. Ein Typ-I-Fehler tritt auf, wenn man die Nullhypothese verwirft, obwohl sie in Wirklichkeit wahr ist, während ein Type-II-Fehler darin besteht, dass man die Nullhypothese nicht verwirft, obwohl sie in Wirklichkeit falsch ist.
3.6.1 Ablauf eines statistischen Tests
Der Ablauf eines statistischen Tests umfasst in der Regel folgende Schritte:
1. Formulierung der Fragestellung: Bevor ein statistischer Test durchgeführt wird, muss die Fragestellung klar formuliert werden, für die der Test durchgeführt werden soll. Dies kann beispielsweise darin bestehen, herauszufinden, ob es einen Unterschied zwischen den Mittelwerten von zwei Gruppen gibt oder ob es einen Zusammenhang zwischen zwei Variablen gibt.
2. Formulierung der Nullhypothese und Alternativhypothese: Basierend auf der formulierten Fragestellung werden die Nullhypothese und die Alternativhypothese formuliert. Die Nullhypothese besagt, dass es keinen Unterschied oder Zusammenhang gibt, während die Alternativhypothese das Gegenteil behauptet.
3. Wahl des statistischen Tests: Basierend auf der Form der Daten und der Art der Fragestellung wird der geeignete statistische Test ausgewählt. Beispielsweise würde für die Überprüfung eines Unterschieds zwischen zwei Gruppen ein t-Test verwendet werden, während für die Überprüfung eines Zusammenhangs zwischen zwei Variablen ein Korrelationskoeffizient verwendet werden könnte.
4. Durchführung des statistischen Tests: Der statistische Test wird anhand der vorliegenden Daten durchgeführt. Dies kann beispielsweise das Berechnen von Mittelwerten, Standardabweichungen und Teststatistiken beinhalten.
5. Bestimmung des Signifikanzlevels: Nach Durchführung des statistischen Tests wird das Signifikanzlevel bestimmt. Dies ist der Wert, der angibt, wie wahrscheinlich es ist, dass die beobachteten Ergebnisse zufällig auftreten, wenn die Nullhypothese tatsächlich wahr ist. In der Regel wird ein Signifikanzlevel von 0.05 verwendet, was bedeutet, dass die Nullhypothese verworfen wird, wenn die Wahrscheinlichkeit, dass die beobachteten Ergebnisse zufällig auftreten, kleiner als 5 % ist.
6. Schlussfolgerungen ziehen: Basierend auf dem erhaltenen Signifikanzlevel wird entschieden, ob die Nullhypothese verworfen oder akzeptiert wird.
46
3 Wahrscheinlichkeit und Statistik
3.6.2 Parametertests bei normalverteilter Grundgesamtheit
Ein Parametertest ist ein statistischer Test, der verwendet wird, um die Unsicherheit in der Schätzung eines unbekannten Parameters einer normalverteilten Grundgesamtheit zu quantifizieren. Normalverteilung bedeutet, dass die Verteilung der Daten in der Grundgesamtheit eine glockenförmige Form hat und die Wahrscheinlichkeit, dass ein bestimmter Wert auftritt, durch die Gaußsche Verteilungsfunktion beschrieben werden kann.
Es gibt zwei Arten von Parametertests, einseitige Tests und zweiseitige Tests. Ein einseitiger Test hat eine Nullhypothese, die besagt, dass der Parameter einen bestimmten Wert hat, und eine Alternativhypothese, die besagt, dass der Parameter einen anderen Wert hat. Ein Beispiel für einen einseitigen Test wäre zu testen, ob der Mittelwert einer Grundgesamtheit größer als ein bestimmter Wert ist.
Ein zweiseitiger Test hat eine Nullhypothese, die besagt, dass der Parameter einen bestimmten Wert hat, und eine Alternativhypothese, die besagt, dass der Parameter ungleich diesem Wert ist. Ein Beispiel für einen zweiseitigen Test wäre zu testen, ob der Mittelwert einer Grundgesamtheit gleich einem bestimmten Wert ist.
Ein häufig verwendeter Parametertest bei normalverteilter Grundgesamtheit ist der t-Test, der verwendet wird, um zu bestimmen, ob der Mittelwert einer Grundgesamtheit von einem angegebenen Wert abweicht. Ein weiterer wichtiger Parametertest ist der Chi-Quadrat-Test, der verwendet wird, um die Homogenität von Frequenzen in mehreren Kategorien zu überprüfen.
Es ist wichtig zu beachten, dass die Annahmen der Normalverteilung und die Unabhängigkeit der Beobachtungen vor Durchführung eines Parametertests überprüft werden sollten, da andernfalls die Ergebnisse des Tests ungültig sein können. Es ist auch wichtig, die Art der verfügbaren Daten und die Fragestellung zu berücksichtigen, um zu entscheiden, welcher Parametertest am besten geeignet ist.
3.6.3 Mittelwerttest
Der t-Test ist ein statistischer Test, der verwendet wird, um die Unsicherheit in der Schätzung des Mittelwerts einer normalverteilten Grundgesamtheit zu quantifizieren. Der Test basiert auf der Annahme, dass die Daten in der Grundgesamtheit normalverteilt sind und dass der Mittelwert des zugrunde liegenden Prozesses unbekannt ist. Es gibt zwei Arten von t-Tests, ein t-Test für unabhängige Stichproben und einer für abhängige Stichproben.
Ein t-Test für unabhängige Stichproben wird verwendet, um zu bestimmen, ob der Mittelwert von zwei unabhängigen Grundgesamtheiten gleich ist oder nicht. Er hat eine Nullhypothese, die besagt, dass die Mittelwerte der beiden Grundgesamtheiten gleich sind, und eine alternativ e Hypothese, die besagt, dass die Mittelwerte der beiden Grundgesamtheiten ungleich sind.
Ein t-Test für abhängige Stichproben (auch bekannt als Paired t-Test) wird verwendet, um zu bestimmen, ob der Mittelwert von zwei abhängigen Grundgesamtheiten gleich ist oder nicht. Es hat eine Nullhypothese, die besagt, dass die Mittelwerte
3.6 Einfache statistische Tests
47
der beiden Grundgesamtheiten gleich sind und eine alternative Hypothese, die besagt, dass die Mittelwerte der beiden Grundgesamtheiten ungleich sind.
In beiden Fällen, wenn die Annahmen der Normalverteilung und die Unabhängigkeit der Beobachtungen erfüllt sind, berechnet der t-Test einen p-Wert, der die Wahrscheinlichkeit angibt, dass der Unterschied zwischen den Mittelwerten rein zufällig ist. Wenn dieser p-Wert klein genug ist, wird die Nullhypothese verworfen und es wird die Schlussfolgerung gezogen, dass der Mittelwert signifikant von dem angegebenen Wert abweicht.
3.6.4 χ 2-Streuungstest
Ein Streuungstest ist ein statistischer Test, der verwendet wird, um die Unsicherheit in der Schätzung der Streuung einer normalverteilten Grundgesamtheit zu quantifizieren. Der Streuungstest basiert auf der Annahme, dass die Daten in der Grundgesamtheit normalverteilt sind und die Streuung des zugrunde liegenden Prozesses unbekannt ist.
Ein häufig verwendeter Streuungstest bei normalverteilter Grundgesamtheit ist der Chi-Quadrat-Test für die Varianz. Dieser Test hat eine Nullhypothese, die besagt, dass die Varianz der Grundgesamtheit gleich einem bestimmten Wert ist, und eine alternative Hypothese, die besagt, dass die Varianz ungleich diesem Wert ist. Der Test berechnet einen p-Wert, der die Wahrscheinlichkeit angibt, dass die Abweichung des beobachteten Wertes von dem angegebenen Wert in der Nullhypothese rein zufällig ist. Wenn dieser p-Wert klein genug ist, wird die Nullhypothese verworfen und es wird die Schlussfolgerung gezogen, dass die Varianz signifikant von dem angegebenen Wert abweicht.
Es ist wichtig zu beachten, dass die Annahme der Normalverteilung vor Durchführung eines Streuungstests überprüft werden sollte, da andernfalls die Ergebnisse des Tests ungültig sein können. Es gibt auch andere Tests zur Überprüfung von Streuungen, wie z. B. den F-Test für die Varianz. Dieser vergleicht die Varianz von zwei oder mehreren Grundgesamtheiten. Es ist jedoch wichtig, dass die Annahmen dieser Tests erfüllt sind und dass die Verwendung des richtigen Tests entsprechend der Fragestellung und den verfügbaren Daten ausgewählt wird.
Optimierung
4
Zusammenfassung
Ein Optimierungsproblem hat eine Zielfunktion, die durch einen Satz von Variablen definiert ist, die als Optimierungsvariablen bezeichnet werden. Das Ziel des Optimierungsproblems besteht darin, die Werte der Variablen zu berechnen, bei denen die Zielfunktion entweder maximiert oder minimiert wird. Es ist üblich, beim maschinellen Lernen eine Minimierungsform der Zielfunktion zu verwenden, wobei die entsprechende Zielfunktion oft als Verlustfunktion („loss function“) bzw. Kostenfunktion („cost function“) bezeichnet wird. Die meisten objektiven Funktionen beim maschinellen Lernen sind multivariate Verlustfunktionen über viele Variablen. Zuerst betrachten wir den einfachen Fall von Optimierungsfunktionen, die für eine einzelne Variable definiert sind. Anschließend folgen Optimierungsfunktionen mit mehr als einer Variable.
4.1 Grundlagen der Optimierung
Optimierungsprobleme beschäftigen sich damit, in meist komplexen Systemen optimale Parameter zu finden. Insbesondere, wenn eine analytische Lösung nicht oder nur sehr schwer möglich ist, werden entsprechende Optimierungsverfahren eingesetzt. Zunächst werden einige grundlegende Begriffe und Bestandteile einer Optimierung formal beschrieben. Eine allgemeine Optimierungsaufgabe ist wie folgt spezifiziert:
n ∈ N ∧ F ⊂ G ⊂ Rn ∧ f : G → R ∧ opt ∈ {min, max}. (4.1)
Ergänzende Information Die elektronische Version dieses Kapitels enthält Zusatzmaterial, auf das über folgenden Link zugegriffen werden kann https://doi.org/10.1007/978-3-662-67277-8_4.
© Der/die Autor(en), exklusiv lizenziert an Springer-Verlag GmbH, DE, ein Teil von
49
Springer Nature 2023
B. Botsch, Maschinelles Lernen Grundlagen und Anwendungen,
https://doi.org/10.1007/978-3-662-67277-8_4
50
4 Optimierung
Die Aufgabe besteht nun darin, die Zielfunktion f über einen zulässigen Bereich F zu optimieren. Es liegt eine Minimierungsaufgabe vor, wenn opt=min gewählt wird, ansonsten eine Maximierungsaufgabe. Die Menge aller Optimierungsaufgaben wird als Optimierungsproblem bezeichnet [3]. Beim maschinellen Lernen wird üblicherweise die Zielfunktion minimiert, wobei die Zielfunktion oft als Verlustfunktion („loss function“) bezeichnet wird.
4.1.1 Univariate Optimierung
Betrachten wir zunächst den einfachsten Fall von Optimierungsfunktionen. Eine eindimensionale Zielfunktion f (x) besitzt lediglich eine einzelne Variable.
f (x) = x2 2x + 3
(4.2)
Man findet das Minimum dieser Zielfunktion, indem man die erste Ableitung f (x) der Funktion f (x) nach x berechnet und anschließend zu 0 setzt.
f (x) = d f (x) = 2x 2 = 0
(4.3)
dx
Wir erhalten mit x = 1 zunächst einen kritischen Punkt. Ein kritischer Punkt kann ein Maximum, Minimum oder Sattelpunkt sein. Die Überprüfung des Punktes erfolgt mit der zweiten Ableitung. Ist die zweite Ableitung f (x) an diesem Punkt größer 0, handelt es sich um ein Minimum. Ist f (x) kleiner 0, handelt es sich um ein Maximum [6].
Eine analytische Lösung für ein Minimierungsproblem zu finden, stellt in vielen Fällen kein Problem dar. Steigt allerdings die Komplexität der Gleichung f (x) weiter an bzw. ist eine Lösung in geschlossener Form nicht möglich, werden für gewöhnlich iterative Verfahren zur Lösung verwendet. Ein beliebter Ansatz zur Optimierung einer Zielfunktion ist die Verwendung des Gradientenabstiegsverfahrens.
x (t+1) = x (t) α f (x (t))
(4.4)
Bei dem Gradientenabstieg beginnt man an einem meist zufälligen Anfangspunkt x = x0 und aktualisiert x iterativ unter Verwendung der steilsten Abstiegsrichtung.
4.1.2 Bivariate Optimierung
Bei der bivariaten Optimierung sind nun 2 Variablen in der Zielfunktion vorhanden. Eine bivariate Funktion kann beispielsweise durch 2 univariate Funktionen konstruiert werden.
g(x, y) = f (x) + f (y) = x2 + y2 2x 2y + 6
(4.5)
4.1 Grundlagen der Optimierung
51
10
()
4
5 2
2
0
0
2
4 2
Abb. 4.1 Darstellung der Funktion g(x, y)
Die Funktion g(x, y) besitzt ein Minimum an der Position [x, y] = [1, 1] (siehe Abb. 4.1). Die partielle Ableitung der Zielfunktion g(x, y) wird durch
∇g(x, y) =
g(x, ∂x
y)
,
g(x, ∂y
y)
T
= [(2x 2), (2y 2)]T
(4.6)
berechnet. Eine partielle Ableitung berechnet die Ableitung in Bezug auf eine bestimmte Variable, während andere Variablen als Konstanten behandelt werden. Die Notation ∇ kennzeichnet den Gradienten. Der Gradient ∇xy g(x y) ist in diesem Fall ein Spaltenvektor mit 2 Komponenten, da 2 Optimierungsvariablen vorhanden sind. Zur Lösung der bivariaten Funktion kann wieder das Gradientenabstiegsverfahren genutzt werden.
x (t+1) y (t +1)
=
x (t) y (t )
α∇g(x, y)
(4.7)
Die Funktion g(x, y) besitzt, wie man in Abb. 4.1 sehen kann, ein einziges globales Optimum und keine lokalen Optima. Viele Optimierungsprobleme, die beim maschinellen Lernen auftreten, besitzen eine ähnliche Struktur, wie die in der Abbildung dargestellt. Das globale Optimum zu erreichen, unabhängig davon, wo man das Gradientenverfahren beginnt, stellt somit kein Problem dar. Treten nun zusätzlich lokale Optima auf, kann es vorkommen, dass das Gradientenverfahren in einem dieser Punkte landet.
4.1.3 Multivariate Optimierung
Sie haben in den 2 vorherigen Kapiteln nun die univariate und bivariate Optimierung kennengelernt. Diese Verfahren nutzen lediglich 1 bzw. 2 Variablen zur Optimierung.
52
4 Optimierung
Die Anzahl der Variablen kann beliebig vergrößert werden. Beispielsweise werden
bei der linearen Regression n Optimierungsvariablen θ1, . . . , θn verwendet, um die abhängige Variable y aus unabhängigen Variablen x1, . . . , xn vorherzusagen.
n
yˆ = θi xi
i =1
(4.8)
Wenn man viele Samples der Form [θ1, θ2, . . . , θn, y] zur Verfügung hat, können diese durch (yi yˆi )2 über alle Samples aufsummiert werden. Eine solche Funktion wird im Sprachgebrauch des maschinellen Lernens oft als Verlustfunktion („loss
function“) bzw. Kostenfunktion („cost function“) bezeichnet. In den folgenden Kapi-
teln werden wir daher den Begriff „Zielfunktion“ durch einen dieser beiden genannten Bezeichnungen ersetzen. Die Kostenfunktion wird durch f (θ ) dargestellt und ist eine Funktion eines Vektors mit mehreren Optimierungsvariablen θ. Die Berechnung des Gradienten einer Kostenfunktion mit n Variablen ähnelt dem im vorherigen
Abschnitt diskutierten bivariaten Fall. Anstelle eines zweidimensionalen Vektors ent-
steht nun ein n-dimensionaler Vektor mit den jeweiligen partiellen Ableitungen. Die
i-te Komponente des n-dimensionalen Gradientenvektors ist die partielle Ableitung von f bezüglich des i-ten Parameters θi . Es kann auch hier wieder das Gradientenabstiegsverfahren genutzt werden, um die Optimierungsvariablen anzupassen.
θ (t+1) = θ (t) α∇ f (θ )
(4.9)
4.2 Gradient Descent
Das Gradientenabstiegsverfahren (Gradient Descent) ist ein iterativer Optimierungsalgorithmus zur Findung eines lokalen Optimums einer differenzierbaren Funktion f (θ ) (Kostenfunktion). Es handelt sich dabei um eine Optimierung ohne Nebenbedingungen. Wie in den vorherigen Kapiteln bereits erwähnt, startet der Algorithmus an einem zufälligen Startpunkt θ (0). Von diesem Punkt schreitet man in Richtung des negativen Gradienten −∇ f (θ ) fort, bis eine bestimmte Abbruchbedingung erfüllt ist. Es kann nun der Fall eintreten, dass man bei einem Iterationsschritt über das lokale Minimum hinwegspringt. Das kann passieren, wenn die Schrittweite α zu groß gewählt wurde. Man würde diesen entsprechend verkleinern und die Optimierung neu beginnen. Die Implementierung in Python ist in Listing 4.1 dargestellt. Die Klasse GradientDescent besitzt eine Methode fit(), in der die eigentliche Optimierung stattfindet.
Listing 4.1 Gradientenabstiegsverfahren class GradientDescent: """ A class that implements the gradient descent algorithm.
Attributes:
4.2 Gradient Descent
53
----------param_hist : list
A list containing the parameter values at each step of the algorithm. """ def __init__(self): self . param_hist =[] def fit( self,
X, y, gradient , start , alpha=0.1, n_iter=100): """ Fits the model to the data using gradient descent.
Parameters: ----------X : array-like
The input data y : array-like
The target values gradient : function
The gradient of the loss function to be minimized start : array-like The initial parameter values alpha : float The learning rate n_iter : int The maximum number of iterations """ self.param_hist.append(start) self.param = start for _ in range(n_iter): for i in range(len(y)):
param = self.param - alpha * np.array(gradient (X[i],y[i],self.param))
self.param_hist.append(param) self.param = param
Die Methode benötigt Eingangsdaten X , Ausgangsdaten y, Startpunkt, Lernrate α und den Gradienten in Form einer Funktion. In der Methode sind 2 Schleifen implementiert. Die äußere Schleife ist für die Anzahl der Datensatzdurchläufe zuständig. Die innere Schleife iteriert über den Datensatz und aktualisiert die Parameter θ in jeder Iteration. Die dargestellte Implementierung nennt sich stochastischer Gradientenabstieg („stochastic gradient descent“), da pro Parameteranpassung nur ein Sample des Datensatzes verwendet wird. Es gibt darüber hinaus noch den Batch- und Mini-Batch-Gradientenabstieg, bei denen mehr als nur ein Sample des Datensatzes verwendet wird.
54
4 Optimierung
4.2.1 Momentum-Based Learning
Momentum-basierte Methoden behandeln die Probleme lokaler Optima, flacher Regionen und krümmungszentrischer Zickzackbewegungen, indem sie erkennen, dass die Betonung mittelfristiger bis langfristiger Richtungen konsistenter Bewegung vorteilhafter ist. Es werden exponentiell gewichtete Durchschnitte von Gradienten über vergangene Iterationen verwendet, um die Konvergenz zu stabilisieren, was zu einer schnelleren Optimierung führt.
v(t+1) = βv(t) + α ∂ f ∂θ
(4.10)
Der Vektor v wird in jeder Iteration aktualisiert, indem der Algorithmus den vorherigen v(t) und den aktuellen Gradientenvektor nutzt. β ∈ (0, 1) ist ein Geschwindigkeitsparameter und bestimmt, wie stark der Einfluss der vorherigen Iteration v(t) ist.
Wird Beta zu 0 gesetzt, entsteht der bekannte Gradientenabstieg („gradient descent“).
Die Anpassung der Parameter θ erfolgt durch
θ (t+1) = θ (t) + v(t+1).
(4.11)
Die Verwendung des Momentum-basierten Lernens kann dazu führen, dass das lokale Optima etwas überschritten wird. Das wird allerdings in Kauf genommen, da im Allgemeinen durch eine geeignete Wahl von β die Lösung schneller erreicht wird. Wählt man β größer 1, dann kann das zu einer Instabilität und zu einer Divergenz führen.
Listing 4.2 Momentum-Based
class Momentum: """ A class implementing stochastic gradient descent with momentum. """ def __init__(self): self . param_hist =[]
def fit( self, X, y, gradient , start , alpha=0.1, beta=0.7, n_iter=20):
""" Train the model using stochastic gradient descent with momentum.
Parameters: -----------
4.2 Gradient Descent
55
X : array-like of shape (n_samples , n_features) The input data for the model.
y : array-like of shape (n_samples ,) The target labels for the input data.
gradient : function A function that computes the gradient of the loss function with respect to the model parameters.
start : array-like of shape (n_features ,) The initial parameter values for the model.
alpha : float, optional The learning rate for the model.
beta : float, optional The momentum coefficient for the model.
n_iter : int, optional The number of iterations to run the algorithm for.
Returns: -------None
""" self.param_hist.append(start) self.param = start v=0 for _ in range(n_iter):
for i in range(len(y)): v = beta * v - learn_rate * np.array(gradient( X[i],y[i],self.param)) self.param = self.param + v self.param_hist.append(self.param)
4.2.2 AdaGrad
Der Name AdaGrad kommt von Adaptive Gradient [5]. Der Algorithmus passt die Lernrate α für jedes Merkmal in Abhängigkeit des geschätzten Problems an. Bei selten vorkommenden Merkmalen wird meist eine höhere Lernrate zugewiesen, das führt dazu, dass die Parameteranpassungen mehr nach Relevanz und nicht nach Häufigkeit durchgeführt werden. Die allgemeine Anpassung des i-ten Parameters θi erfolgt durch
θi(t +1)
=
θi(t )
√α Gi
∂f ∂ θi
.
(4.12)
Mit G =
t τ
gτ gτT
wird
in
jeder
Iteration
die
Lernrate
für
jedes
Merkmal
individu-
ell angepasst. Dieser Algorithmus funktioniert besonders gut bei Daten mit vielen
Nullen, da er die Lernrate für häufige Parameter schneller und für seltene Parameter
langsamer verringert. Leider gibt es einige Fälle, in denen die Lernrate sehr schnell
56
4 Optimierung
abnimmt, da die Gradienten vom Beginn des Trainings an akkumulieren werden. Dies kann zu dem Problem führen, dass das Modell irgendwann nicht mehr lernt, weil die Lernrate mit steigender Anzahl an Iterationen immer weiter verringert wird.
Listing 4.3 AdaGrad class AdaGrad: """ A class implementing AdaGrad algorithm for stochastic gradient descent. """ def __init__(self): self . param_hist =[]
def fit( self, X, y, gradient , start , alpha=0.1, n_iter=20):
""" Train the model using AdaGrad algorithm for stochastic
gradient descent.
Parameters: ----------X : array-like of shape (n_samples , n_features)
The input data for the model. y : array-like of shape (n_samples ,)
The target labels for the input data. gradient : function
A function that computes the gradient of the loss function with respect to the model parameters. start : array-like of shape (n_features ,) The initial parameter values for the model. alpha : float, optional The learning rate for the model. n_iter : int, optional The number of iterations to run the algorithm for.
Returns: -------None
""" self.param_hist.append(start) self.param = start G=0 for _ in range(n_iter):
for i in range(len(y)):
4.2 Gradient Descent
57
g = np.array(gradient(X[i],y[i],self.param)). reshape(-1,1)
G += g**2 param = self.param - alpha / (np.sqrt(G+eps))
*g self.param_hist.append(param) self.param = param
4.2.3 Adam
Der Adam-Algorithmus verwendet eine ähnliche Normalisierung wie bei AdaGrad. Es bringt ebenso das Momentum bei der Parameteranpassung hinzu.
m i(t +1)
=
β1 m i(t )
+
(1
β1
)
∂ ∂
f θi
(4.13)
β1 ist die exponentielle Zerfallsrate für die Schätzungen im ersten Moment mi .
vi(t+1) = β2vi(t) + (1 β2)
∂f ∂ θi
2
(4.14)
vi ist der exponentiell gemittelte Wert des i-ten Parameters θi . Dieser Wert wird mit dem β2 ∈ (0, 1)-Parameter aktualisiert. Am Anfang werden sowohl mi als auch vi zu null gesetzt. Beide Werte tendieren dazu, stärker in Richtung null verzerrt zu sein. Dieses Problem wird vom Adam-Optimierer behoben. Dazu wird der
verzerrungskorrigierte mˆ i durch
mˆ
(t i
+1)
=
m i(t +1) (1 β1t )
(4.15)
und der verzerrungskorrigierte vˆi berechnet.
vˆi(t +1)
=
vi(t +1) (1 β2t )
Die Parameter θi werden nun wie folgt aktualisiert:
(4.16)
θi(t+1) = θi(t)
αmˆ
(t i
+1)
.
vˆi(t +1)
(4.17)
Die Implementierung in Python ist in Listing 4.4 dargestellt.
58
4 Optimierung
Listing 4.4 Adam
class AdamOptim: """ A class for the Adam optimization algorithm. """ def __init__(self, beta1=0.9, beta2=0.999): """ Initializes the AdamOptim object.
Parameters: ---------beta1 : float, optional
The exponential decay rate for the first moment estimate (default is 0.9). beta2 : float, optional The exponential decay rate for the second moment estimate (default is 0.999).
""" self . param_hist =[] self.m_dg, self.v_dg = 0, 0 self.beta1 = beta1 self.beta2 = beta2 def fit( self,
X, y, gradient , start , t=1, alpha=0.1, n_iter=20): """ Fits the model to the data using the Adam optimization algorithm.
Parameters: ---------X : array-like of shape (n_samples , n_features)
The input data y : array-like of shape (n_samples ,)
The target values gradient : callable
A function that computes the gradient of the loss function with respect to the parameters start : array-like of shape (n_features ,) The initial parameter values t : int, optional The current iteration number alpha : float, optional The learning rate n_iter : int, optional
4.3 Newton-Methode
59
The number of iterations
""" self.param = start for _ in range(n_iter):
for i in range(len(y)): t+=1 g = np.array( gradient( X[i], y[i], self.param)).reshape(-1,1) self.m_dg = self.beta1*self.m_dg + (1-self. beta1)*g self.v_dg = self.beta2*self.v_dg + (1-self. beta2)*(g**2) m_dg_corr = self.m_dg/(1-self.beta1**t) v_dg_corr = self.v_dg/(1-self.beta2**t) param = self.param - alpha*(m_dg_corr/(np.sqrt (v_dg_corr)+eps)) self.param_hist.append(param) self.param = param
Beispiel
Die verschiedenen Optimierungsmethoden werden nun benutzt, um die folgende
Kostenfunktion
f (a, b) =
1 N
n
(a + bxi
i =1
yi )2
zu minimieren. xi und yi können durch Beobachtungen erfasst werden. Die Parameter a und b sollen dahingehend optimiert werden, dass f (a, b) ein Minimum annimmt. In Abb. 4.2 sind die Ergebnisse der Optimierungsmethoden dargestellt,
wie zu erwarten, erreichen alle Methoden das Minimum.
4.3 Newton-Methode
Die Newton-Methode ist ein Verfahren zur numerischen Optimierung, das auf TaylorReihen basiert und sich besonders gut für Probleme eignet, die eine gute Schätzung der Lösung und eine gute Konvergenzgeschwindigkeit erfordern. Im Machine Learning wird die Newton-Methode häufig verwendet, um optimale Parameterwerte für bestimmte Modelle zu finden. Eine wichtige Voraussetzung für die Anwendung der Newton-Methode ist die Kenntnis der Gradienten- und Hessian-Matrix des zu optimierenden Problems. Der Gradientenvektor enthält die partiellen Ableitungen der Kostenfunktion nach jedem der Parameter, während die Hessian-Matrix die zweiten
60
4 Optimierung
Abb. 4.2 Optimierung der Kostenfunktion f (a, b) durch Gradient Descent, Momentum, AdaGrad und Adam
partiellen Ableitungen enthält. Diese Matrizen können verwendet werden, um den aktuellen Schritt der Newton-Methode zu berechnen. Die Newton-Methode wird so lange iteriert, bis ein Abbruchkriterium erreicht wird. Der Algorithmus startet zunächst mit einer initialen Schätzung der Lösung θ0. Anschließend werden die Gradienten und die Hessian-Matrix an der aktuellen Schätzung θ berechnet. Die Aktualisierung der Parameter erfolgt durch θ = θ + θ.
Ein Vorteil der Newton-Methode ist die schnelle Konvergenz gegenüber anderen Verfahren wie zum Beispiel dem Gradientenabstieg. Eine weitere Stärke ist, dass die Methode auch in hochdimensionalen Räumen robust und stabil bleibt. Ein Nachteil ist jedoch, dass die Berechnung der Hessian-Matrix sehr rechenintensiv sein kann, insbesondere bei großen Datensätzen oder komplexen Modellen. Eine Möglichkeit, dieses Problem zu umgehen, ist die Verwendung von Approximationen der Hessian-Matrix, wie zum Beispiel die L-BFGS-Methode. Diese Methode nutzt die Informationen aus den letzten Schritten, um eine numerisch stabile Approximation der Hessian-Matrix zu berechnen, anstatt die Matrix direkt zu berechnen. Ein weiterer Aspekt, der bei der Anwendung der Newton-Methode im Machine Learning beachtet werden sollte, ist die Möglichkeit von lokalen Minima. Um dieses Problem zu umgehen, kann man mehrere Initialisierungen der Lösung durchführen.
Algorithm 1 Newton-Methode
Require: : Initial parameter θ 0
Require: : Training set of m examples
1: while stopping criterion not met do
2:
Compute
gradient:
g
1 m
∇θ
m i
L(
f
(xi ,
θ ),
yi )
3:
Compute
Hessian:
H
1 m
∇θ2
m i
L(
f
(xi ,
θ ),
yi )
4: Compute Hessian inverse: H1
5: Compute update: θ = H1g
6: Apply update: θ = θ + θ
7: end while
Parametrische Methoden
5
Zusammenfassung
Maschinelle Lernverfahren können auf unterschiedliche Art und Weise unterteilt werden. In den Abschn. 1.2 bis 1.5 haben wir uns bereits mit einer Unterteilung von Lernverfahren beschäftigt. Diese Verfahren beschreiben, wie und vor allem welche Daten beim Lernvorgang zur Verfügung stehen. Eine weitere Unterteilung erfolgt in sogenannte parametrische und nichtparametrische Verfahren. Bei parametrischen Lernverfahren stehen vor dem Training die Anzahl der Parameter und die grundsätzliche Struktur fest. Bei nichtparametrischen Lernverfahren wird die Anzahl an Parametern erst zur Laufzeit des Trainings bestimmt. Wir beginnen zunächst mit den parametrischen Lernverfahren.
5.1 Regressionsanalyse
Die Regressionsanalyse ist ein wichtiges statistisches Verfahren, das in der Datenanalyse eingesetzt wird, um die Beziehung zwischen einer abhängigen Variablen und einer oder mehreren unabhängigen Variablen zu untersuchen. Regressionsanalyse wird in vielen Bereichen angewendet, wie z. B. in der Wirtschaft, den Sozialwissenschaften und der Medizin, um nur einige zu nennen. Das Ziel der Regressionsanalyse besteht darin, ein Modell zu erstellen, das die Beziehung zwischen den Variablen beschreibt und Vorhersagen für die abhängige Variable auf der Grundlage der unabhängigen Variablen treffen kann. Es gibt verschiedene Arten von Regressionsanalysen, einschließlich linearer Regression, logistischer Regression und Polynomregression, die je nach Art der Daten und dem Untersuchungsziel ausgewählt werden können. Eine sorgfältige Durchführung der Regressionsanalyse und eine angemessene
Ergänzende Information Die elektronische Version dieses Kapitels enthält Zusatzmaterial, auf das über folgenden Link zugegriffen werden kann https://doi.org/10.1007/978-3-662-67277-8_5.
© Der/die Autor(en), exklusiv lizenziert an Springer-Verlag GmbH, DE, ein Teil von
61
Springer Nature 2023
B. Botsch, Maschinelles Lernen Grundlagen und Anwendungen,
https://doi.org/10.1007/978-3-662-67277-8_5
62
5 Parametrische Methoden
Interpretation der Ergebnisse sind entscheidend, um sinnvolle Schlussfolgerungen zu ziehen und fundierte Entscheidungen zu treffen.
5.1.1 Lineare Regression
Ziel der einfachen linearen Regression ist es, den Wert einer abhängigen Variable (Regressand) aufgrund einer unabhängigen Variable (Regressor) vorherzusagen. Sind mehrere Regressoren vorhanden, spricht man von einer multiplen Regression. Ein lineares Modell wird durch
y = Xβ + ε
(5.1)
beschrieben. y ist ein Vektor mit den Zielvariablen, X nennt sich Designmatrix und beinhaltet die unabhängigen Variablen bzw. Einflussgrößen. In β sind die unbekannten Parameter (Regressionskoeffizienten) vorhanden und ε ist ein unbekannter
Vektor mit zufälligen Störvariablen. Die Summe der quadrierten Störvariablen ist das Skalarprodukt εT ε.
f (β) = εT ε = (y Xβ)T (y Xβ)
(5.2)
f ist die Kostenfunktion und wird durch die Optimierung von β minimiert. Der OLS-Schätzer („ordinary least squares estimator“) ergibt sich aus
f (β) ∂β
=
2XT y
+
2XT Xβ
=!
0
(5.3)
mit den optimalen Regressionskoeffizienten
βˆ = (XT X)1XT y.
(5.4)
Die algorithmische Implementierung der linearen Regression ist in Listing 5.1 dargestellt. Die Klasse LinearRegression besitzt drei Methoden. Die Methode __init__ wird aufgerufen, sobald ein Objekt der Klasse instanziiert wird. Beim Initialisieren wird eine Metrik mit übergeben, dies kann beispielsweise der mittlere quadratische Fehler sein. Die fit()-Methode führt die Berechnung der Regressionskoeffizienten durch. Mit der predict()-Methode wird eine Regression mittels der optimalen Regressionskoeffizienten und einem Datensatz durchgeführt.
Listing 5.1 Lineare Regression als OLS-Schätzer
class LinearRegression: """ A class for linear regression. """ def __init__(self, metric): """ Initializes the LinearRegression object.
5.1 Regressionsanalyse
63
Parameters: ----------metric : callable
The error metric to be used for evaluation. """ self.metric = metric
def fit(self,X,y): """ Fits the model to the data.
Parameters: ----------X : array-like of shape (n_samples , n_features)
The input data. y : array-like of shape (n_samples ,)
The target values. """ self.beta = solve(X.T.dot(X),X.T.dot(y)) yp = X.dot(self.beta) error = self.metric(y,yp) print(error)
def predict(self,X): """ Predicts the output values for new input data.
Parameters: ----------X : array-like of shape (n_samples , n_features)
The input data.
Returns: -------array-like of shape (n_samples ,)
The predicted output values. """ return X.dot(self.beta)
Wir verwenden nun die lineare Regression, um den Arcustangens zwischen 0 ≤ x ≤ 5 zu approximieren. Dieser wird zusätzlich noch mit einem zufälligen Rauschen ε überlagert.
y = arctan(x) + ε
(5.5)
Das Ergebnis ist in Abb. 5.1 dargestellt. Die Regressionsgrade besitzt einen OffsetParameter und versucht, die Daten bestmöglich zu approximieren. Der Arcustangens ist nun aber eine nichtlineare Funktion, um hier eine bessere Approximation zu erhalten, muss der linearen Regression zusätzlich eine Nichtlinearität hinzugefügt werden. Eine Möglichkeit, die lineare Regression zu erweitern, ist die Verwendung von polynomischen Funktionen. Hierbei werden zusätzliche Potenzen der Eingangs-
64
Abb. 5.1 Modellvorhersage durch eine lineare Regression
5 Parametrische Methoden
variablen hinzugefügt, um eine nichtlineare Beziehung zwischen der Eingangs- und Ausgangsvariablen zu modellieren. Eine andere Möglichkeit ist die Verwendung von Kernmethoden, die auf einer ähnlichen Idee basieren, indem sie eine nichtlineare Transformation des Eingangsraums durchführen.
In jedem Fall ist es wichtig, die Modellkomplexität sorgfältig zu steuern, um eine Überanpassung an die Trainingsdaten zu vermeiden. Eine Überanpassung würde dazu führen, dass das Modell die Trainingsdaten sehr genau abbildet, aber schlecht auf neuen Daten generalisiert. Daher sollte die Modellkomplexität so gewählt werden, dass sie die Daten gut approximiert, aber nicht zu viele Freiheitsgrade hat.
Die Inversion von XT X kann bei einer großen Designmatrix X sehr rechenintensiv sein. Sind also zu viele Merkmale (Feature) bzw. zu viele Trainingsinstanzen vorhanden, um diese im Arbeitsspeicher ordnungsgemäß zu verarbeiten, bieten sich iterative Optimierungsverfahren (wie in Abschn. 4.2 beschrieben) an. Wir verwenden also das Gradientenverfahren. Dazu wird die Kostenfunktion f (β) nach den Regressionskoeffizienten abgeleitet.
∇β
f
(β )
=
f (β) ∂β
=
2XT (Xβ
y)
(5.6)
Der aktuelle Koeffizientenvektor β wird durch den Gradientenvektor ∇β f (β) iterative angepasst. Damit die numerische Optimierung stabil bleibt, multipliziert man den Gradientenvektor noch mit einer Lernrate η.
β(i+1) = β(i) η∇β f (β)
(5.7)
In Listing 5.2 ist die Implementierung dargestellt. Die Klasse IterativeLinearRegression erbt von der Klasse LinearRegression. Es wird lediglich die fit()-Methode entsprechend angepasst. Es können neben X und y ebenfalls 2 Hyperparameter mit übergeben werden. Durch iterations wird die Anzahl der Durchläufe festgelegt. Mit eta können wir die Stärke der Koeffizientenanpassung beeinflussen. eta ist ein sensibler Parameter, dieser darf nicht zu groß oder zu klein sein, da die numerische Optimierung entweder instabil oder zu lange dauern würde.
5.1 Regressionsanalyse
65
Listing 5.2 Lineare Regression mit dem Gradientenabstiegsverfahren class IterativeLinearRegression(LinearRegression): """ Implements linear regression using iterative gradient descent.
Inherits from LinearRegression class.
Parameters: ----------metric : callable
The loss function to use for evaluating model performance.
Attributes: ----------beta : numpy.ndarray
The learned regression coefficients.
Methods: -------fit(X, y, iterations=500, eta=0.0001):
Fits the linear regression model to the given training data using iterative gradient descent.
predict(X): Predicts the output for the given input data using the learned regression coefficients.
"""
def fit(self,X,y,iterations=500,eta=0.0001): self.beta = randn(X.shape[1],1) for i in range(iterations): gradients = 2*X.T.dot(X.dot(self.beta)-y) self.beta = self.beta-eta*gradients yp = X.dot(self.beta) error = self.metric(y,yp) print(error)
Kommen wir noch mal zu dem Beispiel mit der Arcustangens-Funktion zurück. Die lineare Regression ist grundsätzlich nur für lineare Problemstellungen geeignet. Es gibt nun aber einfache Verfahren, um nichtlineare Probleme mit einem linearen Modell zu lösen. Dieses Verfahren nennt sich polynominale Regression. Dabei werden die Merkmale in der Designmatrix miteinander multipliziert. In Abb. 5.2 ist die Vorhersage der iterativen linearen Regression mit polynominalen Merkmalen 4. Grades dargestellt. Wie man sehen kann, kann das lineare Modell die verrauschte, nichtlineare Arcustangens-Funktion sehr gut approximieren.
Es kann nun der Fall eintreten, dass das zu lösende Problem ein recht einfaches ist und man möchte es mit einem komplexen Modell realisieren. Das Modell wird die Daten einfach bestmöglich nachbilden, ebenfalls das Rauschen. Es entsteht zwar
66
Abb. 5.2 Modellvorhersage durch eine lineare Regression mit polynominalen Merkmalen 4. Grades
5 Parametrische Methoden
ein geringer Trainingsfehler, doch der Fehler bei Validierungs- oder Testdaten ist deutlich größer. Es findet in der Regel eine sogenannte Überanpassung („overfitting“) statt. Man kann die Überanpassung verringern, indem man der Kostenfunktion einen Regularisierungsparameter α hinzufügt.
f (β) = εT ε + αβT β
(5.8)
Diese Kostenfunktion ist der Ridge-Regression zuzuordnen, wobei die Lösung dieser Kostenfunktion durch
βˆ = (XT X + αI)1XT y
(5.9)
in geschlossener Form möglich ist. Der Regularisierungsparameter α ist ein zusätzlicher Hyperparameter, der entsprechend angepasst werden muss.
5.1.2 Logistische Regression
Die Regression kann ebenfalls für Klassifikationsprobleme verwendet werden. Die logistische Regression wird häufig verwendet, um die Wahrscheinlichkeit abzuschätzen, dass eine Instanz zu einer bestimmten Klasse gehört. Ist die geschätzte Wahrscheinlichkeit größer als 50 %, wird die Instanz der Klasse 1 zugeordnet, ansonsten der Klasse 0 [9]. Daraus resultiert ein binärer Klassifikator. Die Berechnung der logistischen Regression ist ähnlich der linearen Regression. Es wird zunächst die gewichtete Summe der Einflussgrößen berechnet. Das Ergebnis wird dann der logistischen Funktion σ übergeben (die logistische Funktion ist in Abb. 5.3 dargestellt).
pˆ = σ (Xβ)
(5.10)
Die logistische Funktion liefert Werte zwischen 0 und 1. Wenn σ (t) < 0.5 ist bzw.
t < 0, dann ist die Modellvorhersage eine 0. Falls σ (t) ≥ 0.5 ist bzw. t ≥ 0, ist das
Ergebnis eine 1. Die Vorhersage yˆ ist somit wie folgt definiert:
⎧ ⎨ 0 , wenn pˆ < 0.5
yˆ = ⎩ 1 , wenn pˆ ≥ 0.5.
(5.11)
5.1 Regressionsanalyse
67
Die Kostenfunktion der logistischen Regression ist für einen Datensatz durch
f (β) = 1 m y(i)log( pˆ(i)) + (1 y(i))log(1 pˆ(i)) m
i =1
(5.12)
möglich, wobei dadurch der Durchschnitt der Kosten über alle Trainingsinstanzen berechnet wird. Diese Kostenfunktion liefert große Werte, falls die Modellvorhersage pˆ(i) nahe 0 und y(i) = 1 oder pˆ(i) ist nahe 1 und y(i) = 0 ist. Um diese Kostenfunktion zu minimieren, kann wieder das Gradientenabstiegsverfahren verwendet werden. Dazu werden wie auch bei der linearen Regression die partiellen Ableitungen nach den Modellparametern benötigt.
∇β
f (β)
=
f (β) ∂β
=
1 m
m i =1
σ (βT x(i)) y(i)
x
(i j
)
(5.13)
Die Implementierung in Python ist in Listing 5.3 dargestellt. Die Klasse LogisticRegression ist ähnlich aufgebaut wie die anderen Klassen. Zusätzlich muss die predict()-Methode angepasst werden, da jetzt eine Klassifikation mittels der logistischen Funktion stattfindet.
Listing 5.3 Logistische Regression mit dem Gradientenabstiegsverfahren class LogisticRegression(LinearRegression): """ Logistic regression class for binary classification problems. """
def fit(self,X,y,iterations=500,eta=0.0001): """ Fits the logistic regression model to the training data.
Parameters: ----------X : array-like, shape (n_samples , n_features)
Training data. y : array-like, shape (n_samples , 1)
Target values. iterations : int, optional
Number of iterations to perform gradient descent. eta : float, optional Learning rate for gradient descent. """ self.beta = randn(X.shape[1],1) for i in range(iterations): sigmoid = 1 / (1 + np.exp(-(X.dot(self.beta)))) gradients = X.T.dot(sigmoid-y)
68
5 Parametrische Methoden
self.beta = self.beta-eta*gradients yp = self.predict(X) error = self.metric(y,yp) print(error)
def predict(self,X): """ Predicts the binary class labels for new data using the fitted model.
Parameters: ----------X : array-like, shape (n_samples , n_features)
New data to predict.
Returns: -------y : array-like, shape (n_samples , 1)
Predicted binary class labels. """ yp = 1 / (1 + np.exp(-(X.dot(self.beta)))) yp[yp<0.5] = 0 yp[yp>0] = 1 return yp
Wir benutzen nun die logistische Regression zur Klassifikation eines Datensatzes mit 2 Klassen. Die Daten sind in der Abb. 5.4 im linken Diagramm zu sehen. Der Datensatz besitzt 2 Einflussgrößen (x1, x2). Darüber hinaus werden polynominale Merkmale hinzugefügt, um entsprechende Nichtlinearitäten berücksichtigen zu können. Die logistische Regression wird zunächst durch den Datensatz trainiert. Anschließend wird das Modell dazu verwendet, einen definierten Bereich der Einflussgrößen zu klassifizieren. Das Ergebnis ist in Abb. 5.4 im rechten Diagramm dargestellt. Das Modell trennt die beiden Klassen recht gut voneinander.
Die logistische Regression kann nun verallgemeinert werden, um Problemstellungen mit mehr als nur 2 Klassen lösen zu können. Dieses Verfahren nennt sich Softmax-Regression bzw. multinomiale logistische Regression. Die Softmax-
Abb. 5.3 Logistische Funktion
5.1 Regressionsanalyse
69
Abb. 5.4 Datensatz zum Trainieren der logistischen Regression (linke Abb.). Modellvorhersage über einen definierten Bereich der Einflussgrößen (rechte Abb.)
Regression berechnet zunächst einen Score sk(x) für jede Klasse k. sk (x) = (β(k))T x
(5.14)
Mit x wird eine Datensatzinstanz bezeichnet. Jede Klasse besitzt einen eigenen Parametervektor β(k). Alle Parametervektoren werden normalerweise in eine Parameter-
matrix B gespeichert. Nachdem der Score für jede Klasse berechnet wurde, kann die
Wahrscheinlichkeit für jede Klasse durch die Softmax-Funktion ermittelt werden.
pˆk = σ (s(x))k =
e(sk (x))
K j =1
e(s
j
(x))
(5.15)
s(x) beinhaltet die Scores jeder Klasse für eine Instanz x. Die Softmax-Regression ermittelt die Klasse mit der größten vorhergesagten Wahrscheinlichkeit.
yˆ = argmax σ (s(x))k
k
(5.16)
Der argmax-Operator gibt den Wert von k zurück, der die vorhergesagte Wahrscheinlichkeit σ (s(x))k maximiert. Als Kostenfunktion wird die Kreuzentropie („cross entropy“) verwendet. Diese Funktion misst, wie gut ein Satz geschätzter Klassenwahrscheinlichkeiten mit den Zielklassen übereinstimmt.
f (B) = 1 m m
K
yk(i)log pˆk(i)
i=1 k=1
(5.17)
yk(i) ist gleich 1, falls die Zielklasse für die i-te Instanz k entspricht, ansonsten eine 0. Leitet man die Kostenfunktion nach β(k) ab, resultiert der Gradientvektor für die
Klasse k.
∇β
f
(β)
=
1 m
m
( pˆk(i)
i =1
yk(i ) )x(i )
(5.18)
Mit Hilfe des Gradientenverfahrens können wieder die optimalen Parameter ermittelt
werden, die schließlich die Kostenfunktion minimieren.
70
5 Parametrische Methoden
Listing 5.4 Softmax-Regression mit dem Gradientenabstiegsverfahren class SoftmaxRegression(LinearRegression): """ A class for performing Softmax Regression. """
def fit(self,X,y,iterations=500,eta=0.0001): """ Fits the Softmax Regression model to the given data.
Parameters: ----------X : numpy array
The feature matrix.
y : numpy array The target vector.
iterations : int, optional The number of iterations for which to run the training.
eta : float, optional The learning rate for the model.
Returns: -------None """ self.classes = np.max(y)+1 self.beta = randn(X.shape[1],int(self.classes)) self.ohe = OneHotEncoder().fit(y) y = self.ohe.transform(y).toarray() for i in range(iterations):
score = np.exp(X.dot(self.beta)) softmax = score / (np.sum(score,axis=1)).reshape
(-1,1) gradients = X.T.dot(softmax-y) self.beta = self.beta-eta*gradients yp = self.predict(X).reshape(-1,1) error = self.metric(self.ohe.inverse_transform(y),yp) print(error)
def predict(self,X): """ Predicts the target values for the given feature matrix.
Parameters: -----------
5.2 Lineare Support Vector Machines
71
X : numpy array The feature matrix.
Returns: -------numpy array
The predicted target values. """ score = np.exp(X.dot(self.beta)) softmax = score / (np.sum(score,axis=1)).reshape(-1,1) yp = np.argmax(softmax ,axis=1) return yp
Betrachten wir wieder ein kleines Beispiel. In Abb. 5.5 sind in dem linken Diagramm nun 3 Klassen dargestellt. Die Softmax-Regression wird nun auf diese Daten angewendet. Das Ergebnis der Klassifikation ist im rechten Diagramm zu sehen. Das Beispiel kann mit beliebig vielen Klassen erweitert werden.
5.2 Lineare Support Vector Machines
Support Vector Machines (SVMs) sind eine Klasse von maschinellen Lernalgorithmen, die in den 1990er Jahren entwickelt wurden und häufig für die Klassifikation und Regression verwendet werden [13]. SVMs arbeiten, indem sie eine Linie oder Hyperfläche zwischen den Klassen in einem hochdimensionalen Raum finden, die möglichst weit von den nahesten Datenpunkten entfernt ist (auch bekannt als Vektoren mit maximalem Abstand oder sogenannte „Support Vectors“). Jeder neue Datenpunkt kann dann anhand seiner Position zu dieser Linie oder Hyperfläche klassifiziert werden. Einer der Vorteile von SVMs ist ihre Fähigkeit, komplexe Beziehungen zwischen Datenpunkten durch die Verwendung von Kernfunktionen abzubilden. Diese Funktionen ermöglichen es, Datenpunkte in hochdimensionalen Räumen zu transformieren, in denen sie leichter zu trennen sind. Ein weiterer Vorteil von SVMs ist ihre Robustheit gegenüber Überanpassung, insbesondere im Vergleich zu anderen Algorithmen wie neuronalen Netzen. Dies ist auf die Einführung von
Abb. 5.5 Datensatz zum Trainieren der Softmax-Regression (linke Abb.). Modellvorhersage über einen definierten Bereich der Einflussgrößen (rechte Abb.)
72
5 Parametrische Methoden
Regularisierungstermen zurückzuführen, die das Modell vor Überanpassung schützen. SVMs haben jedoch auch einige Nachteile, wie z. B. lange Trainingszeiten bei großen Datensätzen und eine eingeschränkte Fähigkeit, nicht lineare Beziehungen abzubilden.
5.2.1 Die optimale Trennebene
Die optimale Trennebene bezieht sich auf die Linie oder die Hyperfläche, das die Klassen in einem Feature-basierten Raum trennt. Diese Linie sollte so ausgewählt werden, dass eine maximale Distanz zwischen den Klassen besteht, was die generalisierte Überlegenheit des Modells garantiert. Wir betrachten dafür zwei Klassen, welche voneinander getrennt werden sollen und für diese gilt:
w0 + wT xi ≥ +1 Klasse 1,
(5.19)
w0 + wT xi ≤ 1 Klasse 2.
(5.20)
Eine kompakte Schreibweise erfolgt durch
ri (w0 + wT xi ) ≥ +1.
(5.21)
Durch ri wird die Kodierung der Klassen festgelegt. Der Abstand der Trennebene zu den jeweiligen Datenpunkten, die der Ebene am nächsten liegen, wird als Margin bezeichnet. Durch das Maximieren des Margin wird eine optimale Trennebene gefunden. Der Abstand von xi zur Trennebene ist durch
ri (w0 + wT xi ) ||w||
(5.22)
definiert. Der Abstand sollte für eine gute Generalisierung maximiert werden. Das wird erreicht, indem man ||w||2 minimiert. Darüber hinaus sollen die Klassen voneinander getrennt werden. Es ergibt sich somit eine quadratische Optimierung mit
Nebenbedingung.
min 1 ||w||2 2
mit
ri (w0 + wT xi ) ≥ +1
(5.23)
Zur Lösung dieses Problems werden die Lagrange-Multiplikatoren benötigt. Dadurch ergibt sich unter der Nutzung der Lagrange-Multiplikatoren αi :
L(w0, w,α)
=
1 ||w||2 2
N i =1
αi (ri (w0
+
wT xi )
1).
(5.24)
5.2 Lineare Support Vector Machines
73
Es werden nun Gradienten von L(w0, w, α) bezüglich w0 und w berechnet und zu 0 gesetzt. Diese Ergebnisse werden wiederum in L(w0, w, α) eingesetzt. Daraus resultiert die folgende Gleichung:
L (w0 ,
w,α)
=
1 (wT w) 2
+
αi .
i
(5.25)
Das Ziel besteht nun darin, αi zu maximieren. Anschließend erfolgt die Berechnung von w durch i αi ri xi . Die Menge an xi , deren ri > 0 ist, sind die sogenannten Support-Vektoren. Für die Berechnung von w0 werden beliebige Support-Vektoren genutzt. Um die numerische Stabilität zu gewährleisten, werden im Allgemeinen alle Support-Vektoren berücksichtigt. Möchte man nun eine Klassifikation durchführen, berechnet man zunächst durch g(x) = w0+wT x eine Vorhersage. Je nach Vorzeichen wird die jeweilige Klasse bestimmt. Wenn mehr als 2 Klassen vorliegen, werden k Zweiklassenprobleme definiert, wobei dann k Support-Vektor-Maschinen gi (x) gelernt werden müssen.
Wir betrachten dazu ein kleines Beispiel. In Abb. 5.6 sind 2 Klassen mit jeweils 3 Datenpunkten dargestellt. Die Linie zwischen den Datenpunkten ist die gefundene optimale Trennlinie. Die Implementierung der SVM-Klasse ist in Listing 5.5 umgesetzt. Der vorliegende Code implementiert eine Support Vector Machine (SVM) für binäre Klassifikationsprobleme. Die Klasse SVM enthält eine Reihe von Methoden, um den Algorithmus zu initialisieren, zu trainieren und Vorhersagen zu treffen. Die init()-Methode initialisiert die Hyperparameter des Modells, nämlich die Lernrate learning_rate, den Regularisierungsterm (alpha) und die Anzahl der Iterationen n_iters, die für das Training durchgeführt werden sollen. Zudem werden die Gewichte w und der Bias-Term w0 mit None initialisiert. Die fit()-Methode trainiert das Modell, indem sie die Gewichte und den Bias-Term anpasst, um eine Entscheidungsgrenze zwischen den beiden Klassen zu finden. Dazu wird zunächst die Anzahl der Proben n_samples und die Anzahl der Merkmale n_features aus den Eingabedaten X ermittelt. Dann wird eine transformierte Zielvariable y_ erstellt, die entweder den Wert -1 oder 1 für jede Klasse annimmt. Anschließend werden die Gewichte und der Bias-Term initialisiert, indem sie auf null gesetzt werden. In einer Schleife werden nun die Gewichte und der Bias-Term für eine festgelegte Anzahl von Iterationen n_iters aktualisiert. Dabei wird jeder Datenpunkt x_i im Datensatz betrachtet und überprüft, ob er auf der richtigen Seite der Entscheidungsgrenze liegt (d. h., ob er richtig oder falsch klassifiziert wurde). Wenn der Datenpunkt richtig klassifiziert wurde (condition=True), wird das Modell nicht angepasst und die Schleife geht zum nächsten Datenpunkt über. Wenn der Datenpunkt jedoch falsch klassifiziert wurde (condition=False), werden die Gewichte und der Bias-Term aktualisiert, um die Entscheidungsgrenze zu verbessern. Die predict()-Methode ermöglicht es, Vorhersagen für neue Eingabedaten X zu treffen, indem sie das Modell mit den gelernten Gewichten und dem Bias-Term verwendet. Dabei wird die Approximation approx berechnet, indem die Eingabedaten mit den Gewichten multipliziert und der Bias-Term abgezogen wird. Anschließend wird die Vorhersage als das Vorzei-
74
5 Parametrische Methoden
chen der Approximation np.sign(approx) ausgegeben, d. h., es wird bestimmt, auf welcher Seite der Entscheidungsgrenze die Eingabedaten liegen.
Listing 5.5 Support-Vektor-Maschine class SVM: """ A class for performing Support Vector Machine (SVM) classification. """
def __init__( self, learning_rate=0.01, alpha=0.01, n_iters=5000):
""" Initializes the SVM object.
Parameters: ----------learning_rate : float, optional
The learning rate for the model.
alpha : float, optional The regularization parameter for the model.
n_iters : int, optional The number of iterations for which to run the training.
Returns: -------None """ self.lr = learning_rate self.alpha = alpha self.n_iters = n_iters self.w = None self.w0 = None
def fit(self, X, y): """ Fits the SVM model to the given data.
Parameters: ----------X : numpy array
The feature matrix.
y : numpy array The target vector.
5.2 Lineare Support Vector Machines
75
Returns: -------None """ n_samples, n_features = X.shape
y_ = np.where(y <= 0, -1, 1)
self.w = np.zeros(n_features) self.w0 = 0
for _ in range(self.n_iters): for idx, x_i in enumerate(X): condition = y_[idx] * (np.dot(x_i, self.w) self.b) >= 1 if condition: self.w -= self.lr * (2 * self.alpha * self .w) else: self.w -= self.lr * (2 * self.alpha * self .w - np.dot(x_i, y_[idx])) self.w0 -= self.lr * y_[idx]
def predict(self, X): """ Predicts the target values for the given feature matrix.
Parameters: ----------X : numpy array
The feature matrix.
Returns: -------numpy array
The predicted target values. """ approx = np.dot(X, self.w) - self.w0 return np.sign(approx)
5.2.2 Soft-Margin
Das Soft-Margin-Verfahren ist eine wichtige Technik im Rahmen der Support Vector Machine. Es wurde entwickelt, um Probleme bei der Klassifikation von Daten mit einer hohen Fehlerrate oder bei ungleichmäßiger Verteilung der Klassen in den Daten zu lösen. Eine SVM verwendet eine Trennebene, um Datenpunkte in zwei Klassen zu trennen. Das Ziel ist es, eine Entscheidungsfläche zu finden, die mög-
76
Abb. 5.6 Klassifikation eines 2-Klassen-Problems mit der Support-Vektor-Maschine
5 Parametrische Methoden
lichst weit von beiden Klassen entfernt ist, um eine gute Trennung zu garantieren. Ein Problem bei diesem Ansatz ist, dass es in vielen praktischen Anwendungen schwierig ist, eine perfekte Trennung zu finden, da einige Datenpunkte möglicherweise auf der falschen Seite der Trennebene liegen oder nicht sauber in eine der Klassen eingeordnet werden können. Das Soft-Margin-Verfahren löst dieses Problem, indem es eine gewisse Fehlerrate erlaubt, d. h., es ermöglicht ein paar falsch klassifizierte Datenpunkte. Dies wird erreicht, indem ein Gewichtungsfaktor eingeführt wird, der die Bedeutung jedes Datenpunkts für die Klassifikation definiert. Datenpunkte, die schwer zu klassifizieren sind, erhalten ein höheres Gewicht und haben einen größeren Einfluss auf die Bestimmung der Trennebene. Das Soft-MarginVerfahren wird durch die Lösung eines konvexen Optimierungsproblems erreicht, bei dem eine Mischung aus maximalem Abstand der Trennebene von den Datenpunkten und der Anzahl der falsch klassifizierten Datenpunkte minimiert wird. Diese Mischung wird durch den Gewichtungsfaktor kontrolliert, der als Regularisierungsparameter bezeichnet wird. Ein hoher Parameter führt zu einer geringeren Fehlerrate und einem größeren Abstand der Trennebene von den Datenpunkten, während ein niedriger Parameter eine höhere Fehlerrate und einen geringeren Abstand zulässt. Das Soft-Margin-Verfahren hat einige wichtige Vorteile im Vergleich zu anderen Klassifikationsalgorithmen. Es ist sehr robust gegenüber Überanpassung und kann effektiv mit hohen Dimensionen umgehen.
5.2.3 Kernfunktionen
Kernfunktionen sind mathematische Funktionen, die eine Transformation der Eingabedaten in einen höherdimensionalen Zusammenhang ermöglichen. Diese Transformation ist notwendig, da SVM nur lineare Entscheidungsgrenzen lernen kann. Wenn die Daten jedoch nicht linear getrennt werden können, kann die Verwendung einer Kernfunktion eine effektive Lösung sein. Die Diskriminante wird nun wie folgt definiert:
g(x) = αi ri K (xi , x).
i
(5.26)
5.3 Der Bayessche Schätzer
77
Es gibt verschiedene Kernfunktionen, die verwendet werden können. Eine beliebte Kernfunktion ist die radiale Basisfunktion.
K (xi , x) = exp
||xi
x||2 σ2
(5.27)
Dadurch wird ein sphärischer Kern definiert, mit xi als Zentrum und σ als Radius. Eine weitere Kernfunktion ist die Sigmoidfunktion.
K (xi , x) = tanh(2xT xi + 1)
(5.28)
Andere Kernfunktionen sind unter bestimmten Bedingungen ebenfalls möglich [16]. Es ist jedoch zu beachten, dass die Wahl einer geeigneten Kernfunktion von
vielen Faktoren abhängt, wie der Art der Daten, der Größe der Datensätze und der Anzahl der Funktionsparameter. Eine ungünstige Wahl einer Kernfunktion kann zu Overfitting oder Unterfitting führen, was die Vorhersagegenauigkeit beeinträchtigen kann. Zusammenfassend lässt sich sagen, dass die Verwendung von Kernfunktionen bei SVM eine wertvolle Technik ist, um nichtlineare Beziehungen zwischen den Daten zu erkennen und Vorhersagen mit hoher Genauigkeit zu treffen. Während die Wahl einer geeigneten Funktion eine wichtige Überlegung darstellt, kann die Verwendung einer geeigneten Funktion dazu beitragen, dass SVM ein mächtiger Klassifikator und Regressor wird.
5.3 Der Bayessche Schätzer
Der Bayes-Schätzer ist ein wichtiges Konzept in der statistischen Schätztheorie, das es ermöglicht, Schätzungen für die Wahrscheinlichkeiten von Ereignissen auf der Grundlage von beobachteten Daten zu berechnen. Der Bayes-Schätzer ist benannt nach dem englischen Mathematiker und Philosophen Thomas Bayes, der die Theorie des Schätzers in seinem berühmten Werk An Essay towards solving a Problem in the Doctrine of Chances (1763) vorgestellt hat. Das Konzept des Bayes-Schätzers basiert auf Bayes Theorem, das die Beziehung zwischen A-priori-Wahrscheinlichkeiten und A-posteriori-Wahrscheinlichkeiten beschreibt. A-priori-Wahrscheinlichkeiten sind die Wahrscheinlichkeiten, die vor einer Beobachtung berechnet werden, während A-posteriori-Wahrscheinlichkeiten die Wahrscheinlichkeiten sind, die nach einer Beobachtung berechnet werden.
Der Satz von Bayes ist durch
P(A|B) =
P ( B | A) P ( A) P(B)
(5.29)
definiert. Hier wird P(A) als A-priori-Wahrscheinlichkeit bezeichnet, da das Wissen von A bereits bekannt ist, bevor man die beobachtbaren Variablen B betrachtet.
78
5 Parametrische Methoden
P(B|A) bezeichnet man als Klassen-Likelihood und ist die bedingte Wahrscheinlichkeit dafür, dass ein zu A zugehöriges Ereignis den zugehörigen Beobachtungswert B hat. Die A-posteriori-Wahrscheinlichkeit der Klasse Ai wird durch
P(Ai |B) =
P(B|Ai )P(Ai )
K k=1
P ( B | Ak ) P ( Ak )
(5.30)
berechnet. Der Bayessche Klassifikator ermittelt anschließend die Klasse mit der höchsten A-posteriori-Wahrscheinlichkeit.
Eine mögliche Implementierung ist in Listing 5.6 dargestellt. Der gegebene Code implementiert einen naiven Bayes-Klassifikator, der in der Lage ist, zwischen verschiedenen Klassen von Datenpunkten zu unterscheiden. Der Klassifikator besitzt eine fit()-Methode, um das Modell anhand der Trainingsdaten zu trainieren, und eine predict()-Methode, um Vorhersagen auf neuen, unbekannten Daten zu treffen. Die fit()-Methode berechnet die Mittelwerte, Varianzen und Priorwahrscheinlichkeiten für jede Klasse auf Basis der Trainingsdaten. Zunächst werden die einzigartigen Klassen in den Zielvariablen y identifiziert. Anschließend werden die Mittelwerte und Varianzen der Merkmale (Features) für jede Klasse berechnet. Die Priorwahrscheinlichkeit jeder Klasse wird als das Verhältnis der Anzahl von Datenpunkten in der Klasse zur Gesamtzahl der Datenpunkte berechnet. Die predict()-Methode berechnet die Vorhersage für jeden Datenpunkt in der Testdatenmatrix X. Für jeden Datenpunkt wird die Wahrscheinlichkeit einer Klassenzugehörigkeit berechnet. Da der Klassifikator eine naive Bayes-Annahme macht, d. h., er nimmt an, dass alle Merkmale unabhängig voneinander sind, können die Wahrscheinlichkeiten für jedes Merkmal separat berechnet werden. Schließlich wird die Vorhersage der Klasse mit der höchsten Posterior-Wahrscheinlichkeit zurückgegeben. Die accuracy()Methode berechnet die Genauigkeit des Modells durch Vergleich der wahren Klasse der Testdaten mit den vorhergesagten Klassen. Die Vorhersagen und tatsächlichen Klassen werden als Arrays übergeben, und die Genauigkeit wird als Prozentsatz der korrekt vorhergesagten Klassen berechnet. Die _pdf()-Methode berechnet die Wahrscheinlichkeitsdichtefunktion für die Normalverteilung jedes Merkmals, gegeben sind dabei die Mittelwerte und Varianzen der entsprechenden Klasse. Die Dichtefunktion wird dann verwendet, um die Wahrscheinlichkeit zu berechnen, dass ein bestimmter Merkmalswert in einer bestimmten Klasse beobachtet wird.
Listing 5.6 Klasse des Bayesschen Schätzers
class NaiveBayes: """ The NaiveBayes class implements a Naive Bayes algorithm for classification. """ def fit(self, X, y): """ Fit the Naive Bayes classifier to a training set.
Parameters: -----------
5.3 Der Bayessche Schätzer
79
X (numpy.ndarray): The training data, where each row represents a sample and each column represents a feature.
y (numpy.ndarray): The target values for the training data.
Returns: -------None """ n_samples, n_features = X.shape self._classes = np.unique(y) n_classes = len(self._classes)
# calculate mean, var, and prior for each class self._mean = np.zeros((n_classes , n_features), dtype=
np.float64) self._var = np.zeros((n_classes , n_features), dtype=np
.float64) self._priors = np.zeros(n_classes , dtype=np.float64)
for idx, c in enumerate(self._classes): X_c = X[y == c] self._mean[idx, :] = X_c.mean(axis=0) self._var[idx, :] = X_c.var(axis=0) self._priors[idx] = X_c.shape[0] / float(n_samples )
def predict(self, X): """ Predict the target values for a test set.
Parameters: ----------X (numpy.ndarray):
The test data, where each row represents a sample and each
column represents a feature.
Returns: -------numpy.ndarray: The predicted target values for
the test data. """ y_pred = [self._predict(x) for x in X] return np.array(y_pred)
def accuracy(self, y_true, y_pred): """ Calculate the accuracy of the Naive Bayes classifier.
80
5 Parametrische Methoden
Parameters: ----------y_true (numpy.ndarray): The true target values. y_pred (numpy.ndarray): The predicted target values.
Returns: -------float: The accuracy of the Naive Bayes classifier. """ accuracy = np.sum(y_true == y_pred) / len(y_true) return accuracy
def _predict(self, x): """ Predict the target value for a single sample.
Parameters: ----------x (numpy.ndarray): A single sample.
Returns: -------float: The predicted target value for the sample. """ posteriors = []
# calculate posterior probability for each class for idx, c in enumerate(self._classes):
prior = np.log(self._priors[idx]) posterior = np.sum(np.log(self._pdf(idx, x))) posterior = prior + posterior posteriors.append(posterior)
# return class with highest posterior probability return self._classes[np.argmax(posteriors)]
def _pdf(self, class_idx , x): """ Calculate the probability density function for a single feature of a single sample.
Parameters: ----------class_idx (int): The index of the class to
calculate the PDF for. x (numpy.ndarray): A single sample.
Returns: -------numpy.ndarray:
The calculated PDF for the specified feature and class.
5.3 Der Bayessche Schätzer
81
""" mean = self._mean[class_idx] var = self._var[class_idx] numerator = np.exp(-((x - mean) ** 2) / (2 * var)) denominator = np.sqrt(2 * np.pi * var) return numerator / denominator
5.3.1 Stochastische Unabhängigkeit
Die stochastische Unabhängigkeit ist ein wichtiger Begriff in der Wahrscheinlichkeitstheorie und spielt auch eine entscheidende Rolle beim Bayes-Klassifikator. Um die stochastische Unabhängigkeit beim Bayes-Klassifikator zu verstehen, müssen wir zunächst das Konzept der Unabhängigkeit in der Wahrscheinlichkeitstheorie genauer betrachten. Zwei Ereignisse A und B sind stochastisch unabhängig voneinander, wenn das Eintreten des einen Ereignisses keinen Einfluss auf die Wahrscheinlichkeit des anderen Ereignisses hat.
P(A ∩ B) = P(A)P(B)
(5.31)
Wenn A und B stochastisch unabhängig sind, dann ist die Wahrscheinlichkeit, dass sie gleichzeitig eintreten, das Produkt der Wahrscheinlichkeiten, dass sie einzeln eintreten. Nun kommen wir zur Anwendung der stochastischen Unabhängigkeit beim Bayes-Klassifikator. Der Bayes-Klassifikator verwendet eine Tabelle von Wahrscheinlichkeiten, um die Wahrscheinlichkeit zu bestimmen, dass ein Pixel einer bestimmten Farbe einer bestimmten Klasse (z. B. Vordergrund oder Hintergrund) angehört. Die Tabelle wird aus einer Trainingsmenge von Bildern abgeleitet, in der jedes Pixel einer Klasse zugeordnet ist. Für jedes Pixel wird eine bestimmte Farbe ermittelt und die entsprechende Zelle in der Tabelle wird aktualisiert. Da der Bayes-Klassifikator annimmt, dass die Farbwerte eines Pixels stochastisch unabhängig voneinander sind, wird die Wahrscheinlichkeit für jedes Pixel unabhängig von den Wahrscheinlichkeiten der anderen Pixel berechnet. Das bedeutet, dass die Wahrscheinlichkeit, dass ein bestimmtes Pixel einer bestimmten Klasse angehört, nur von der Farbe des Pixels abhängt und nicht von den Farben der umliegenden Pixel. Diese Annahme der stochastischen Unabhängigkeit ist zwar vereinfachend, aber oft ausreichend für viele Anwendungen in der Bildverarbeitung. Es gibt jedoch auch Situationen, in denen die Annahme nicht erfüllt ist, wie z. B. bei der Erkennung von Text in Bildern. In solchen Fällen müssen andere Klassifikatoren verwendet werden, die die Abhängigkeit zwischen den Pixeln berücksichtigen. Nach der Merkmal-Auswahl werden die ausgewählten Merkmale skaliert. Dies dient dazu sicherzustellen, dass jedes Merkmal den gleichen Einfluss auf die Klassifikation hat. Ohne Skalierung könnte ein Merkmal, das beispielsweise Werte im Bereich von 0 bis 1 annimmt, einen viel größeren Einfluss auf die Klassifikation haben als ein Merkmal, das Werte im Bereich von 0 bis 1000 annimmt. Der nächste Schritt ist die eigentliche Klassifikation. Der Klassifikator verwendet die skalierten Merkmale, um Vorhersagen über
82
5 Parametrische Methoden
die Klasse des Eingabevektors zu treffen. Dabei wird angenommen, dass die stochastische Unabhängigkeit der Merkmale weiterhin gilt. Das Ergebnis der Klassifikation ist die Klasse y des Eingabevektors x. Mathematisch lässt sich die stochastische Unabhängigkeit der Merkmale wie folgt ausdrücken:
m
P(x1, x2, . . . , xm) = P(xk ).
k=1
(5.32)
Dabei ist P(x1, x2, . . . , xn) die Wahrscheinlichkeit, dass alle Merkmale x1, x2, . . . , xn gleichzeitig auftreten, und P(xk) ist die Wahrscheinlichkeit, dass das Merkmal xk alleine auftritt.
Es gibt jedoch Fälle, in denen die stochastische Unabhängigkeit nicht erfüllt ist. Wenn es eine Abhängigkeit zwischen den Merkmalen gibt, ist die Annahme der stochastischen Unabhängigkeit nicht mehr korrekt. In diesem Fall können wir das gemeinsame Auftreten von Merkmalen berücksichtigen, indem wir eine Kovarianzmatrix verwenden. Die Kovarianzmatrix ist eine symmetrische Matrix, die das Ausmaß der linearen Abhängigkeit zwischen den Merkmalen darstellt. Sie enthält die Varianzen der einzelnen Merkmale auf der Hauptdiagonalen und die Kovarianzen zwischen den Merkmalen auf den Nebendiagonalen. Eine positive Kovarianz zwischen zwei Merkmalen bedeutet, dass sie tendenziell gemeinsam auftreten, während eine negative Kovarianz bedeutet, dass sie tendenziell entgegengesetzt auftreten. Um die Kovarianzmatrix zu berechnen, kann die folgende Formel verwendet werden
=
n
1
1
n
(xi x¯)(xi x¯)T ,
i =1
(5.33)
wobei n die Anzahl der Beobachtungen, xi der Vektor der Merkmalswerte der i-ten Beobachtung und x¯ der Durchschnittsvektor der Merkmalswerte über alle Beobachtungen ist. Wenn wir die Kovarianzmatrix in unsere Klassifikationsmethode einbeziehen, wird der Bayes-Klassifikator zu einem sogenannten linearen BayesKlassifikator. Hierbei wird die Kovarianzmatrix zur Bestimmung der Grenzen zwischen den Klassen verwendet. Es ist wichtig zu beachten, dass die Schätzung der Kovarianzmatrix schwierig sein kann, insbesondere wenn die Anzahl der Merkmale groß ist. In diesem Fall können Regularisierungsmethoden wie die Schrumpfung der Kovarianzmatrix verwendet werden, um die Genauigkeit der Schätzung zu verbessern. Insgesamt ist die Berücksichtigung der stochastischen Unabhängigkeit und der Kovarianzmatrix ein wichtiger Aspekt bei der Anwendung des Bayes-Klassifikators. Es hilft uns, die Beziehung zwischen den Merkmalen und der Zielgröße besser zu verstehen und unsere Klassifikationsmodelle zu verbessern.
5.3.2 Bayessche Netze
Bayessche Netze sind ein mächtiges Werkzeug in der künstlichen Intelligenz und haben in den letzten Jahren immer mehr an Bedeutung gewonnen. Sie sind ein proba-
5.3 Der Bayessche Schätzer
83
bilistisches Modell, das es ermöglicht, kausale Zusammenhänge zwischen verschiedenen Variablen zu modellieren. Dies macht sie zu einem wertvollen Instrument für eine Vielzahl von Anwendungen, darunter Diagnostik, Prognostik, Risikobewertung und Entscheidungsunterstützung.
Bayessche Netze basieren auf Bayesscher Statistik, einer Methode zur Berechnung von Wahrscheinlichkeiten, die auf das Bayessche Theorem zurückgeht. Das Modell besteht aus einem Netzwerk von Knoten, die jeweils eine Variable repräsentieren, und Kanten, die den kausalen Zusammenhang zwischen den Variablen repräsentieren. Jeder Knoten hat eine Wahrscheinlichkeitsverteilung, die seinen Zustand beschreibt, und die Kanten definieren die Abhängigkeiten zwischen den Knoten. Eines der wichtigsten Konzepte bei Bayesschen Netzen ist die Konstruktion von Directed Acyclic Graphs (DAGs), die die Struktur des Netzwerks definieren. Diese Struktur bestimmt die Art und Weise, wie die Informationen in dem Netzwerk fließen und wie die Wahrscheinlichkeiten berechnet werden. Die Konstruktion eines DAGs erfordert ein Verständnis der kausalen Beziehungen zwischen den Variablen und eine sorgfältige Überlegung, wie diese Beziehungen modelliert werden sollen. Ein weiteres wichtiges Konzept bei Bayesschen Netzen ist die Schätzung von Wahrscheinlichkeitsverteilungen. Dies kann auf verschiedene Arten erfolgen, darunter die Verwendung von Trainingsdaten, die Verwendung von vorhandenen statistischen Daten oder die Verwendung eines statistischen Modells. Einmal geschätzt, können die Wahrscheinlichkeitsverteilungen verwendet werden, um Vorhersagen zu treffen und Entscheidungen zu treffen.
Bayessche Netze haben eine Vielzahl von Anwendungen in verschiedenen Bereichen. Eines der bekanntesten Beispiele ist die Diagnostik, bei der das Netz verwendet wird, um Krankheiten oder andere Gesundheitsprobleme zu identifizieren, indem es Symptome und andere klinische Informationen analysiert. Ein Beispiel für die Anwendung von Bayesschen Netzen in der Diagnostik ist das MYCIN-System, das in den 1970er Jahren entwickelt wurde, um Diagnosen für bakterielle Infektionen zu treffen. Ein weiteres Beispiel ist die Prognostik, bei der das Netz verwendet wird, um die Wahrscheinlichkeit eines bestimmten Ereignisses in der Zukunft vorherzusagen. Hier kann es beispielsweise eingesetzt werden, um das Risiko einer Kreditkarte oder eines Darlehens zu bewerten oder die Wahrscheinlichkeit eines Maschinenausfalls vorherzusagen. Bayessche Netze haben auch Anwendungen in Bereichen wie dem Marketing, bei der Bewertung von Risiken in Finanzinstituten und bei der Überwachung von Produktionsprozessen in der Industrie.
In Bezug auf ihre Stärken und Schwächen ist zu beachten, dass Bayessche Netze sehr gut in der Lage sind, Komplexität und Unsicherheit zu modellieren, was sie zu einem wertvollen Werkzeug für eine Vielzahl von Anwendungen macht. Einer ihrer Nachteile ist jedoch, dass die Konstruktion eines Bayesschen Netzes Zeit und Fachwissen erfordert und dass es schwierig sein kann, die richtigen Wahrscheinlichkeitsverteilungen zu schätzen.
84
Abb. 5.7 Mathematisches Modell eines Neurons
5 Parametrische Methoden
5.4 Neuronale Netze
Das Konzept von künstlichen neuronalen Netzen wurde bereits in den 1940er Jahren von Warren McCulloch und Waltern Pitts erarbeitet [7]. Das Ziel dieser Arbeit war die Beschreibung des Verhaltens von Neuronen im Gehirn durch ein einfaches mathematisches Modell. Neuronen erhalten dabei Signale, die wiederum verarbeitet und an andere Neuronen weitergeleitet werden. Künstliche neuronale Netze können sowohl für die Klassifikation als auch für die Regression verwendet werden. Vor allem werden neuronale Netze bei Problemen eingesetzt, wo die Beziehung zwischen Eingang und Ausgang recht komplex ist, wie beispielsweise bei der Bilderkennung. 5.4.1 Das künstliche Neuron
Wir beginnen zunächst mit der Beschreibung des künstlichen Neurons. Die Grundstruktur ist in Abb. 5.7 dargestellt. Auf der linken Seite stehen die Werte des Merkmalsvektors x. Jeder Eintrag dieses Vektors wird mit einem Gewicht wi ∈ R multipliziert und anschließend aufsummiert.
n
h(x) = wi xi = wT x
i =0
(5.34)
Anschließend wird das Ergebnis von h an eine Aktivierungsfunktion („activation function“) g weitergeleitet. Dieses Konzept kommt einer Nervenzelle schon recht nahe, da auch hier eine Art Summation von Signalen stattfindet [14]. Liegt die Summe von Anregungen über einem Schwellwert, fängt die Nervenzelle an zu feuern. Dieses sogenannte Feuern versuchen wir, durch die Aktivierungsfunktion darzustellen.
Eine der wichtigsten Eigenschaften von Aktivierungsfunktionen ist ihre Nichtlinearität. Durch die Verwendung von nichtlinearen Funktionen können neuronale Netzwerke auch komplexe Beziehungen zwischen den Eingabe- und Ausgabesignalen approximieren. Wenn das Netzwerk ausschließlich lineare Funktionen verwenden würde, könnte es nur lineare Beziehungen approximieren. Die meisten Aktivierungsfunktionen sind nichtlineare Funktionen, die eine Sättigungsgrenze haben. Diese Sättigungsgrenze kann dazu führen, dass das Neuron nicht mehr auf Änderungen der Eingabesignale reagiert, wenn diese außerhalb des linearen Bereichs liegen.
5.4 Neuronale Netze
y 1
y 1
85
y 1
0
0
0
x
x
x
Abb. 5.8 Darstellung verschiedener Aktivierungsfunktionen. Heaviside (linke Abb.), ReLU (mittlere Abb.), Sigmoid (rechte Abb.)
Ein weiterer wichtiger Aspekt von Aktivierungsfunktionen ist ihre Differenzierbarkeit. Die Differenzierbarkeit ist für das Lernen des neuronalen Netzwerks unerlässlich. Wenn die Aktivierungsfunktion nicht differenzierbar wäre, könnte das Netzwerk nicht durch Backpropagation trainiert werden, das auf der Berechnung von Gradienten basiert. Wenn die Funktion nicht stetig differenzierbar ist, können die Gradienten an bestimmten Stellen nicht berechnet werden, was zu numerischen Problemen führt.
Es gibt eine ganze Reihe verschiedener Aktivierungsfunktionen, wobei drei von ihnen in Abb. 5.8 dargestellt sind. Weit verbreitet ist die sogenannte ReLU-Funktion. Diese Funktion gibt das Ergebnis von h weiter, falls dieses größer null ist, ansonsten ist der Ausgang null.
5.4.2 Mehrschichtige neuronale Netze
Mehrschichtige neuronale Netze sind ein mächtiges Instrument in der künstlichen Intelligenz und finden Anwendung in vielen Anwendungsgebieten wie Bild- und Spracherkennung, Robotik und Finanzprognosen. Diese Art von Netzwerken besteht aus mehreren Schichten von Neuronen, die miteinander verbunden sind und durch ein Trainingsverfahren angepasst werden, um eine bestimmte Aufgabe zu erfüllen. Im Vergleich zu einfachen neuronalen Netzen haben mehrschichtige Netze den Vorteil, dass sie in der Lage sind, komplexe Zusammenhänge zwischen Eingabe- und Ausgabedaten zu erkennen und somit eine höhere Genauigkeit in der Vorhersage zu erzielen. In diesem Kapitel werden wir uns eingehend mit der Funktionsweise von mehrschichtigen neuronalen Netzen befassen und deren Anwendungsgebiete untersuchen. Wir werden uns ebenso mit den Gewichten und dem Bias auseinandersetzen.
Im vorherigen Kapitel haben wir die Funktionsweise der Neuronen kennengelernt. Es können nun mehrere Neuronen zu komplexen Netzwerken verbunden werden. Man nennt diese Art von Netzwerk auch Multi-Layer-Perceptron (MLP) bzw. ein mehrschichtiges Netz. In einem neuronalen Netz gibt es verschiedene Bezeichnungen von Layern (Schichten). Beim Input-Layer werden alle Merkmale dem Netzwerk zugefügt. Der Input-Layer gibt die Daten an die nächste Schicht weiter, bis die Daten am Output-Layer anliegen und die fertige Berechnung bereitstellt. Die
86
InputLayer
Hidden-Layers
5 Parametrische Methoden
OutputLayer
Abb. 5.9 Neuronales Netz mit drei Hidden-Layern
Schichten zwischen Input- und Output-Layer werden Hidden-Layer genannt (siehe Abb. 5.9).
Grundsätzlich können bei neuronalen Netzen beliebig viele Hidden-Layer hinzugefügt werden. Verfügt das Netz über mehr als zwei Hidden-Layer, dann spricht man bereits von tiefen Netzen (Deep Networks).
Bevor wir uns mit dem Training des neuronalen Netzes beschäftigen, schauen wir uns zunächst an, wie das Netz eine Vorhersage berechnet, wenn es bereits trainiert wurde. Wir nehmen für die weiteren Betrachtungen an, dass alle Neuronen in den Hidden-Layern eine Sigmoid-Funktion und im Output-Layer lineare Aktivierungsfunktionen verwenden. Wir beginnen als Erstes mit dem Input-Layer. Dieser Layer beinhaltet die Merkmale (Feature) xi .
o(1) = sig(W(1)x)
(5.35)
Die Gewichte der ersten Schicht können zu einer Matrix W(1) zusammengefasst
werden.
w1,1 w1,2 . . . w1,n
W(1)
=
⎜⎜⎜⎝
w2,1 ...
w2,2 ...
... ...
w2,n ...
⎟⎟⎟⎠
(5.36)
wm,1 wm,2 . . . wm,n
Der Ausgang o(1) der ersten Schicht dient nun als Input der nächsten Schicht. Dieser Vorgang wird so lange durchgeführt, bis man zum Output-Layer gelangt. Die
5.4 Neuronale Netze
87
Abb. 5.10 Ausführliche Darstellung der Gewichte eines neuronalen Netzes zwischen zwei Layern
Vorhersage yˆi ist also nichts anderes als eine Nacheinander-Ausführung von Aktivierungsfunktionen im Zusammenspiel mit Matrix-Vektor-Multiplikationen. Eine ausführliche Darstellung ist in Abb. 5.10 zu sehen.
5.4.3 Lernvorgang
Wie bei allen anderen ML-Verfahren wird auch bei neuronalen Netzen eine Kostenfunktion benötigt f (W).
f (W)
=
n i =1
1 2
(
yˆi
yi )2
(5.37)
Die Gewichte wmk ,n werden durch die Gleichung
Wneu = Walt sig(∇ f (Walt ))
(5.38)
iterativ aktualisiert. Dazu werden allerdings die partiellen Ableitungen für das Gradientenverfahren benötigt.
∂ f (W) ∂wmk ,n
=
n
(yˆi
i =1
yi
)
∂y wmk
,n
(5.39)
88
5 Parametrische Methoden
Für das Trainieren eines neuronalen Netzes wird die sogenannte Backpropagation verwendet. Der Backpropagation-Algorithmus besteht aus zwei Schritten, dem Vorwärtsgang und dem Rückwärtsgang. Im Vorwärtsgang werden die Eingabevektoren durch das Netz geschickt und die Ausgabevektoren berechnet. Im Rückwärtsgang werden die Fehler, die zwischen den berechneten Ausgabevektoren und den tatsächlichen Ausgabevektoren bestehen, zurück durch das Netz propagiert, um die Gewichte anzupassen. Die Gleichungen, die verwendet werden, um die Gewichte anzupassen, basieren auf der Kostenfunktion, die verwendet wird, um die Genauigkeit des Netzes zu messen. Eine häufig verwendete Kostenfunktion ist die Summe des Quadrats der Fehler (SSE). Die Gewichte werden so angepasst, dass die Ableitung der Fehlerfunktion nach den Gewichten minimiert wird. Ein Beispiel für die Anpassung der Gewichte kann mit dem Gradientenabstiegsverfahren erfolgen. In jedem Lernzyklus werden die Gewichte angepasst, indem sie um einen Bruchteil der negativen Ableitung der Kostenfunktion nach den Gewichten verringert werden. Die numerische Implementierung des Backpropagation-Algorithmus erfordert die Verwendung von numerischen Methoden zur Berechnung der Ableitungen der Kostenfunktion. Eine häufig verwendete Methode ist die Berechnung der Ableitungen mittels der Finite-Differenzen-Methode. Es gibt auch andere Varianten des BackpropagationAlgorithmus, wie z. B. die Rückpropagation mit Momentum und die Rückpropagation mit Adaptive Learning Rate. Diese Varianten können verwendet werden, um das Lernen des Netzes zu beschleunigen und die Stabilität des Lernprozesses zu verbessern. In der Praxis werden Backpropagation und Gradient Descent oft zusammen genutzt. Backpropagation ist der Algorithmus, der die Fehler berechnet und Gradient Descent nutzt diese Fehler, um die Gewichte des Netzes zu verändern.
Beispiel
Gegeben sei ein simples neuronales Netz mit einem Eingangswert x1, zwei
Hidden-Layern mir jeweils einem Neuron und einem Neuron im Output-Layer. Es
wird vorausgesetzt, dass nur Sigmoid-Aktivierungsfunktionen bei den Hidden-
Layern zum Einsatz kommen. Wir möchten nun die partiellen Ableitungen der ein-
zelnen Gewichte berechnen. Ausgehend von einer Kostenfunktion f (W) begin-
nen
wir
zunächst
mit
der
Berechnung
von
∂f ∂ w1(3,1)
.
∂f
n
∂y
∂ w1(3,1)
= (yˆi
i =1
yi ) ∂w1(3,1)
Die
Berechnung
von
∂y ∂ w1(3,1)
erfolgt
durch
∂y ∂ w1(3,1)
=
w1(3,1) o1(2) ∂ w1(3,1)
= o1(2).
5.4 Neuronale Netze
89
Das Ergebnis ist lediglich der Ausgang des zweiten Hidden-Layers. Für die
Berechnung
von
∂y ∂ w1(2,1)
wird
die
Kettenregel
benötigt.
∂y ∂ w1(3,1)
=
∂y ∂ o1(2)
∂ o1(2) ∂ w1(2,1)
=
w1(3,1) (o1(2)(1 o1(2))o1(1))
Der Term o1(1) entsteht durch die innere Ableitung von o1(2) nach w1(2,1). Durch die
äußere Ableitung der Sigmoid-Funktion entsteht o1(2)(1 o1(2)). Schlussendlich
folgt
analog
für
∂y ∂ w1(1,1)
∂y ∂ w1(3,1)
=
∂ y ∂o1(2) ∂o1(2) ∂o1(1)
∂ o1(1) ∂ w1(1,1)
= w1(3,1)(o1(2)(1 o1(2))o1(1))w1(2,1)(o1(1)(1 o1(1))x1).
Wie Sie anhand des Beispiels gesehen haben, haben wir zunächst die am weitesten rechts stehende Schicht betrachtet und sind dann sukzessive nach links gegangen. Auf diese Weise arbeitet auch das Verfahren der Backpropagation.
Die Schritte für den Backpropagation-Algorithmus sind wie folgt:
1. Zunächst werden die Gewichte und Bias festgelegt. Normalerweise werden diese
zufällig initialisiert. 2. Eingangsdaten xi werden dem Netz hinzugefügt. Berechne alle om(n) und die Aus-
gabe yˆ j .
3. Berechne den aktuellen Wert der Kostenfunktion.
4.
Beginne auf
der
rechten Seite und berechne alle
Ableitungen
∂ ∂
f (W) wmk ,n
.
5. Aktualisiere alle Gewichte und Bias durch das Gradientenabstiegsverfahren.
Eine recht simple Implementierung eines neuronalen Netzes ist in Listing 5.7 dargestellt. Der folgende Python-Code implementiert ein mehrschichtiges neuronales Netzwerk (Multi-Layer Perceptron, MLP), das für die Klassifizierung von Daten verwendet werden kann. Das Netzwerk besteht aus einer Eingabeschicht, einer oder mehreren versteckten Schichten und einer Ausgabeschicht. Jede Schicht enthält mehrere Neuronen, die miteinander verbunden sind. Das Netzwerk wird trainiert, indem es mit Trainingsdaten gefüttert wird. Das MLP-Netzwerk wird durch eine Klasse in Python repräsentiert, die drei Parameter erfordert: die Anzahl der Eingabevariablen, die Anzahl der Neuronen in der versteckten Schicht und die Anzahl der Klassen. Die init-Methode initialisiert die Gewichte der beiden Schichten zufällig mit Hilfe von NumPy-Bibliothek. Die Größe der Gewichtsmatrizen hängt von der Anzahl der Eingabevariablen, der versteckten Neuronen und der Ausgabeklassen ab. Die Größe der Gewichte zwischen der Eingabe- und der versteckten Schicht wird durch die Anzahl der Eingabevariablen und die Anzahl der Neuronen in der versteckten Schicht bestimmt. Die Gewichte zwischen der versteckten Schicht und der
90
5 Parametrische Methoden
Ausgabeschicht hängen von der Anzahl der versteckten Neuronen und der Anzahl der Klassen ab. Um das Training des Netzes zu ermöglichen, wird eine train()Methode definiert. Diese Methode erhält die Trainings- und Testdaten sowie die Anzahl der Iterationen und die Lernrate als Parameter. In einer Schleife werden dann iterativ die Vorhersagen für die Trainingsdaten berechnet und anhand der wahren Werte die Gradienten für die Gewichte der beiden Schichten zurückpropagiert. Anschließend werden die Gewichte anhand der Gradienten und der Lernrate aktualisiert. Die Methode report() wird aufgerufen, um den Fortschritt des Trainings zu überwachen. Die train()-Methode wird mit den Trainings- und Testdaten aufgerufen und passt das Modell iterativ an, bis die gewünschte Anzahl von Iterationen erreicht ist.
Listing 5.7 Neuronales Netz
class MLP: """ Multi-Layer Perceptron (MLP) class for classification tasks. """ def __init__( self, n_input_variables , n_hidden_nodes , n_classes): """ Initializes the MLP with random weights.
Parameters: ----------n_input_variables : int
number of input variables n_hidden_nodes : int
number of nodes in the hidden layer n_classes : int number of output classes """ w1_rows = n_input_variables + 1 self.w1 = np.random.randn(w1_rows , n_hidden_nodes) * np.sqrt(1 / w1_rows) w2_rows = n_hidden_nodes + 1 self.w2 = np.random.randn(w2_rows , n_classes) * np. sqrt(1 / w2_rows)
def sigmoid(self,z): """ Computes the sigmoid function for the given input z. Parameters: ----------z : numpy.ndarray The input values to the
5.4 Neuronale Netze
91
sigmoid function Returns: -------numpy.ndarray :
The output values of the sigmoid function """ return 1 / (1 + np.exp(-z))
def softmax(self,logits): """ Computes the softmax function for the given logits. Parameters: ----------logits : numpy.ndarray The input logits. Returns: -------numpy.ndarray : The output probabilities of the softmax function. """ exponentials = np.exp(logits) return exponentials / np.sum(exponentials , axis=1). reshape(-1, 1)
def sigmoid_gradient(self,sigmoid): """ Computes the gradient of the sigmoid function for the given sigmoid value. Parameters: ----------sigmoid : numpy.ndarray The output values of the sigmoid function. Returns: -------numpy.ndarray : The gradient values of the sigmoid function. """ return np.multiply(sigmoid , (1 - sigmoid))
def loss(self,Y, y_hat): """ Calculates the cross-entropy loss between the predicted and actual output values. Parameters: ----------Y : numpy.ndarray
92
5 Parametrische Methoden
A numpy array of shape (num_samples, num_classes) containing the actual output values for the given input samples. y_hat : numpy.ndarray A numpy array of shape (num_samples, num_classes) containing the predicted output values for the given input samples. Returns: -------float : The calculated cross-entropy loss between the predicted and actual output values. """ return -np.sum(Y * np.log(y_hat)) / Y.shape[0]
def prepend_bias(self, X): """ Adds a column of 1s at the beginning of the input array X. Parameters: ----------X : numpy.ndarray The input array to which the bias term is to be prepended. Returns: -------numpy.ndarray : The input array with a column of 1s prepended. """ return np.insert(X, 0, 1, axis=1)
def forward(self, X): """ The method takes a numpy array X as input and returns the predicted output and hidden layer values for the input. Parameters: ----------X : numpy.ndarray The input array of shape (num_samples, num_features). Returns: -------tuple : (numpy.ndarray, numpy.ndarray) A tuple containing
5.4 Neuronale Netze
93
two numpy arrays """ h = self.sigmoid(np.matmul(
self.prepend_bias(X), self.w1)) y_hat = self.softmax(np.matmul( self.prepend_bias(h), self.w2)) return (y_hat, h)
def back(self,X, Y, y_hat, h): """ Calculates the gradients of the weights w1 and w2 with respect to the loss function using backpropagation algorithm. Parameters: ----------X : numpy.ndarray The input data of shape (num_samples, num_features). Y : numpy.ndarray The one-hot encoded target labels of shape (num_samples , num_classes). y_hat : numpy.ndarray The predicted probabilities of shape (num_samples , num_classes). h : numpy.ndarray The output of the hidden layer after applying the sigmoid function. Returns: -------Tuple : (numpy.ndarray, numpy.ndarray) The gradients of the weights w1 and w2, respectively. """ w2_gradient = np.matmul( self.prepend_bias(h).T, (y_hat - Y)) / X.shape[0] w1_gradient = np.matmul( self.prepend_bias(X).T, np.matmul( y_hat - Y, self.w2[1:].T) * self.sigmoid_gradient(h)) / X.shape[0] return (w1_gradient, w2_gradient)
def classify(self,X):
94
5 Parametrische Methoden
""" The classify method takes a set of input features and returns the predicted class labels based on the learned weights of the neural network. Parameters: ----------X : numpy.ndarray
A matrix of shape (n_samples , n_features) containing the input features for which class labels are to be predicted. Returns: -------numpy.ndarray : A matrix of shape (n_samples , 1) containing the predicted class labels for the input features. """ y_hat, _ = self.forward(X) labels = np.argmax(y_hat, axis=1) return labels.reshape(-1, 1)
def report( self, iteration , X_train , Y_train , X_test , Y_test):
""" Computes and prints the training loss and test accuracy for the current iteration. Parameters: ----------iteration (int):
The current iteration number. X_train : numpy.ndarray
The training data matrix. Y_train : numpy.ndarray
The training data labels. X_test : numpy.ndarray
The test data matrix. Y_test : numpy.ndarray
The test data labels. Returns: --------
None """ y_hat, _ = self.forward(X_train) training_loss = self.loss(Y_train, y_hat) classifications = self.classify(X_test)
5.4 Neuronale Netze
95
accuracy = np.average(classifications == Y_test) * 100.0
print( "Iteration: %5d, Loss: %.8f, Accuracy: %.2f%%" %
(iteration, training_loss , accuracy))
def train( self, X_train , Y_train , X_test , Y_test , iterations=1000, lr=0.01):
""" Train the neural network model using the given input data and hyperparameters. Parameters: ----------X_train : numpy.ndarray
Input features for training the model. Y_train : numpy.ndarray Target output values for the training data. X_test : numpy.ndarray Input features for testing the model. Y_test : numpy.ndarray Target output values for the testing data. iterations : int Number of training iterations to perform. lr : float Learning rate to use for training. Returns: -------None """ for iteration in range(iterations): y_hat, h = self.forward(X_train) w1_gradient , w2_gradient = self.back(
X_train , Y_train , y_hat , h) self.w1 = self.w1 - (w1_gradient * lr) self.w2 = self.w2 - (w2_gradient * lr) self.report( iteration, X_train , Y_train ,