{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Maschinelles Lernen (ML), Praktikum 2\n", "Dieser Kurs vermittelt den Umgang mit den Pythonbibliotheken `matplotlib`, `NumPy`, `Pandas` und `Scikit-Learn`. Dabei werden Sie anhand eines Beispielprojekts vom Anfang bis zum Ende geführt. Im Rahmen dieser Übung werden Sie die folgenden Schritte durchlaufen: \n", "- Einführung in Numpy, Pandas und Matplotlib\n", "- Daten auswerten und visualisieren, um Erkenntnisse zu gewinnen\n", "- Vorbereitung der Daten\n", "- Modell Auswahl und Training \n", "- Präsentieren Sie Ihre Lösung\n", "\n", "In dieser Übung experimentieren Sie mit realen Datensätzen. Hierfür stehen einige frei verfügbare Datensätze aus unterschiedlichen Fachgebieten zur Verfügung: \n", "- [UC Irvine Machine Learning Repository](http://archive.ics.uci.edu/ml/)\n", "- [Kaggle](https://www.kaggle.com/datasets)\n", "- [Amazon AWS](http://aws.amazon.com/fr/datasets/)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Einführung in Numpy, Matplotlib und Pandas\n", "\n", "Numpy ist eine Python-Bibliothek, die für numerische Berechnungen verwendet wird. Numpy stellt hauptsächlich ein mehrdimensionales Array-Objekt zusammen mit effizient implementierten Funktionen zur Verfügung. Um Numpy zu nutzen müssen wir es zunächst importieren. Üblicherweise bindet man es unter dem Namen `np` ein." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Praktische mathematische Funktionen:\n", "\n", "| Operator | Beschreibung |\n", "|--------------|----------------------------------------------------------|\n", "| ``np.linalg.inv`` | Inverse der Matrix |\n", "| ``np.linalg.eig`` | Eigenwerte der Matrix |\n", "| ``np.matmul`` | Matrix-Multiplikation |\n", "| ``np.zeros`` | Matrix mit Nullen erstellen (`.ones` für Einsen) |\n", "| ``np.arange`` | Start, Stopp und Schrittweite |\n", "| ``np.identity`` | Create an identity matrix |\n", "| ``np.vstack`` | Vertically stack 2 arrays |\n", "\n", "\n", "\n", "Hilfreiche Funktionen für die Fehlersuche:\n", "\n", "| Operator | Beschreibung |\n", "|--------------------------------|--------------------------------------------------|\n", "| ``array.shape`` | Form des Numpy-Arrays abfragen |\n", "| ``array.dtype`` | Datentyp des Arrays prüfen |\n", "| ``type(stuff)`` | Typ einer Variablen abfragen |\n", "| ``print(f\"Data type of integer is {name}\")`` | Einfacher Weg eine Nachricht zu erzeugen |\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Allgemeine Numpy Verwendung\n", "Initialisierung mit Listen:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "array_1d = np.array([1, 2, 3, 4])\n", "print(array_1d.shape)\n", "array_1by4 = np.array([[1, 2, 3, 4]])\n", "print(array_1by4.shape)\n", "\n", "large_array = np.array([i for i in range(400)])\n", "print(large_array.shape)\n", "\n", "large_array = large_array.reshape((20, 20))\n", "print(large_array.shape)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Listen mit verschiedenen Typen. Numpy verwendet einen Autocasts, der dem Array `from_list_2d` automatisch eine höherere Präzision zuweist." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from_list = np.array([1, 2, 3])\n", "from_list_2d = np.array([[1, 2, 3.0], [4, 5, 6]])\n", "from_list_bad_type = np.array([1, 2, 3, \"a\"])\n", "\n", "print(f'Data type of integer is {from_list.dtype}')\n", "print(f'Data type of float is {from_list_2d.dtype}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy unterstützt viele Arten von algebraischen Operationen auf einem ganzen Array" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "array_1d + 5\n", "array_1d * 5\n", "np.sqrt(array_1d)\n", "np.power(array_1d, 2)\n", "np.exp(array_1d)\n", "np.log(array_1d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Punktprodukt und Matrix-Multiplikation\n", "Einige Möglichkeiten das Punktprodukt zu schreiben" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "array_1d @ array_1d\n", "array_1d.dot(array_1d)\n", "np.dot(array_1d, array_1d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrix-Multiplikation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "weight_matrix = np.array([1, 2, 3, 4]).reshape(2, 2)\n", "sample = np.array([[50, 60]]).T\n", "np.matmul(weight_matrix, sample)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2D Matrix-Multiplikation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mat1 = np.array([[1, 2], [3, 4]])\n", "mat2 = np.array([[5, 6], [7, 8]])\n", "np.matmul(mat1, mat2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Elementweise Multiplikation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "a = np.array([i for i in range(10)]).reshape(2, 5)\n", "a * a\n", "np.multiply(a, a)\n", "np.multiply(a, 10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting\n", "Matplotlib kann zum Erstellen von Plots und Diagrammen verwendet werden. Üblicherweise bindet man es unter dem Namen `plt` ein. Die Bibliothek wird wie folgt verwendet:\n", "1. Aufruf einer Plotting-Funktion mit einigen Daten mit `.plot()`.\n", "2. Funktionen aufrufen, um die Eigenschaften des Plots einzustellen (z.B. Beschriftungen und Farben).\n", "3. Den Plot sichtbar machen mit `.show()`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Import\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", "\n", "# Create data\n", "t = np.arange(0.0, 2.0, 0.01)\n", "s = 1 + np.sin(2 * np.pi * t)\n", "\n", "# Plotting\n", "fig, ax = plt.subplots()\n", "ax.plot(t, s)\n", "ax.set(xlabel = \"time (s)\", ylabel = \"voltage (mV)\", title = \"About as simple as it gets, folks\")\n", "ax.grid()\n", "fig.savefig(\"test.png\") # Saves the current plot into a .png file located in the same folder\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plot mit gestrichelten Linien und einer Legende" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "x = np.linspace(0, 10, 500)\n", "y = np.sin(x)\n", "\n", "fig, ax = plt.subplots()\n", "\n", "line1, = ax.plot(x, y, label = \"Using set_dashes()\")\n", "# 2pt line, 2pt break, 10pt line, 2pt break\n", "line1.set_dashes([2, 2, 10, 2])\n", "\n", "line2, = ax.plot(x, y - 0.2, dashes=[6, 2], label = \"Using the dashes parameter\")\n", "\n", "ax.legend()\n", "plt.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pandas \n", "Pandas bietet Datenstrukturen und Funktionen zur schnellen Manipulation und Analyse von Daten. Es setzt dabei auf die effizienten Datenmodelle von Numpy auf und analysiert Tabellen in verschiedenen Größen in Sekundenbruchteilen. Für das Maschinelle Lernen ist Pandes eine hilfreiche Bibliothek, da die Pandas-Dataframes und die Tabellenobjekte\n", "des Frameworks grafisch als Tabellen aufbereitet werden. Üblicherweise bindet man Pandas unter dem Namen `pd` ein." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Nun laden wir die Daten mit Pandas. Ums Einlesen kümmert sich ``pd.read_csv()``. Die Spaltennamen können mit einer Liste ``names`` per Hand festgelegt werden, falls die Datei keine zufriedenstellenden Spaltennamen liefert. Pandas bestimmt die Datentypen der Spalten automatisch, arbeitet aber schneller, wenn man die Typen als Dictionary im Parameter ``dtype`` definiert." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "names = [\"sepal-length\", \"sepal-width\", \"petal-length\", \"petal-width\", \"class\"]\n", "\n", "# Optional\n", "# dtype={\"sepal-length\": float,\n", "# \"sepal-width\": float,\n", "# \"petal-length\": float,\n", "# \"petal-width\": float, \n", "# \"class\": str})\n", "\n", "iris_data = pd.read_csv(\"iris.csv\", names = names)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Ein Blick auf den Datensatz\n", "Wir verwenden den Iris-Datensatz, um die Klassifikation zu veranschaulichen. Es handelt sich hierbei um einen Datensatz, der die Länge und Breite der Kelchblätter (engl. sepal) und Kronblätter (engl. petal) von 150 Iris-Blüten aus drei Unterarten unterscheidet: *Iris-Setosa*, *Iris-Virginica* und *Iris-Versicolor*. \n", "\n", "