Erforschung überwachter Algorithmen für maschinelles Lernen

Veröffentlicht: 2022-03-11

Das Hauptziel dieser Lektüre besteht darin, genügend statistische Methoden zu verstehen, um die maschinellen Lernalgorithmen in der scikit-learn-Bibliothek von Python nutzen zu können und dieses Wissen dann anzuwenden, um ein klassisches maschinelles Lernproblem zu lösen.

Die erste Station unserer Reise führt uns durch eine kurze Geschichte des maschinellen Lernens. Dann werden wir in verschiedene Algorithmen eintauchen. Bei unserem letzten Halt werden wir das, was wir gelernt haben, anwenden, um das Problem der Vorhersage der Titanic-Überlebensrate zu lösen.

Einige Haftungsausschlüsse:

  • Ich bin ein Full-Stack-Softwareentwickler, kein Experte für maschinelle Lernalgorithmen.
  • Ich nehme an, Sie kennen einige grundlegende Pythons.
  • Dies ist explorativ, daher wird nicht jedes Detail erklärt, wie es in einem Tutorial der Fall wäre.

Lassen Sie uns in diesem Sinne eintauchen!

Eine schnelle Einführung in maschinelle Lernalgorithmen

Sobald Sie sich in dieses Feld wagen, stellen Sie fest, dass maschinelles Lernen weniger romantisch ist, als Sie vielleicht denken. Anfangs war ich voller Hoffnung, dass ich, nachdem ich mehr gelernt hatte, in der Lage sein würde, meine eigene Jarvis-KI zu bauen, die den ganzen Tag damit verbringen würde, Software zu programmieren und Geld für mich zu verdienen, sodass ich ganze Tage im Freien verbringen könnte, Bücher lesen, Motorrad fahren, und genieße einen rücksichtslosen Lebensstil, während mein persönlicher Jarvis meine Taschen tiefer macht. Allerdings wurde mir schnell klar, dass die Grundlage von Machine-Learning-Algorithmen Statistiken sind, die ich persönlich langweilig und uninteressant finde. Glücklicherweise stellte sich heraus, dass „stumpfe“ Statistiken einige sehr faszinierende Anwendungen haben.

Sie werden schnell feststellen, dass Sie Statistiken sehr gut verstehen müssen, um diese faszinierenden Anwendungen zu erreichen. Eines der Ziele von maschinellen Lernalgorithmen ist es, statistische Abhängigkeiten in gelieferten Daten zu finden.

Die bereitgestellten Daten können alles sein, von der Überprüfung des Blutdrucks gegen das Alter bis hin zum Auffinden von handschriftlichem Text anhand der Farbe verschiedener Pixel.

Allerdings war ich neugierig zu sehen, ob ich maschinelle Lernalgorithmen verwenden könnte, um Abhängigkeiten in kryptografischen Hash-Funktionen (SHA, MD5 usw.) zu finden – aber das ist nicht wirklich möglich, da richtige Krypto-Primitive auf diese Weise konstruiert sind dass sie Abhängigkeiten eliminieren und eine äußerst schwer vorhersagbare Ausgabe erzeugen. Ich glaube, dass maschinelle Lernalgorithmen mit unendlich viel Zeit jedes Kryptomodell knacken könnten.

Leider haben wir nicht so viel Zeit, also müssen wir einen anderen Weg finden, um Kryptowährung effizient abzubauen. Wie weit sind wir bisher gekommen?

Eine kurze Geschichte der Algorithmen für maschinelles Lernen

Die Wurzeln der Algorithmen für maschinelles Lernen stammen von Thomas Bayes, einem englischen Statistiker, der im 18. Jahrhundert lebte. Sein Aufsatz An Essay Towards Solving a Problem in the Doctrine of Chances untermauert den Satz von Bayes, der in der Statistik weit verbreitet ist.

Im 19. Jahrhundert veröffentlichte Pierre-Simon Laplace die Theorie analytique des probabilites , erweiterte die Arbeit von Bayes und definierte das, was wir heute kennen, als den Satz von Bayes. Adrien-Marie Legendre hatte kurz zuvor die Methode der „kleinsten Quadrate“ beschrieben, die heute auch beim überwachten Lernen weit verbreitet ist.

Das 20. Jahrhundert ist die Zeit, in der die meisten öffentlich bekannten Entdeckungen auf diesem Gebiet gemacht wurden. Andrey Markov erfand Markov-Ketten, mit denen er Gedichte analysierte. Alan Turing schlug eine Lernmaschine vor, die künstlich intelligent werden könnte und im Wesentlichen genetische Algorithmen vorwegnimmt. Frank Rosenblatt erfand das Perzeptron und löste damit große Aufregung und große Berichterstattung in den Medien aus.

Aber dann gab es in den 1970er-Jahren viel Pessimismus in Bezug auf die Idee der KI – und damit weniger Mittel –, weshalb diese Zeit als KI-Winter bezeichnet wird. Die Wiederentdeckung der Backpropagation in den 1980er Jahren führte zu einem Wiederaufleben der Forschung zum maschinellen Lernen. Und heute ist es wieder ein heißes Thema.

Der verstorbene Leo Breiman unterschied zwischen zwei statistischen Modellierungsparadigmen: Datenmodellierung und algorithmische Modellierung. „Algorithmische Modellierung“ bedeutet mehr oder weniger die maschinellen Lernalgorithmen wie den Random Forest .

Maschinelles Lernen und Statistik sind eng verwandte Bereiche. Laut Michael I. Jordan haben die Ideen des maschinellen Lernens, von methodischen Grundlagen bis hin zu theoretischen Werkzeugen, eine lange Vorgeschichte in der Statistik. Er schlug auch Data Science als Platzhalterbegriff für das Gesamtproblem vor, an dem sowohl Spezialisten für maschinelles Lernen als auch Statistiker implizit arbeiten.

Kategorien von Algorithmen für maschinelles Lernen

Das Gebiet des maschinellen Lernens steht auf zwei Hauptsäulen, dem überwachten Lernen und dem nicht überwachten Lernen . Einige Leute betrachten auch ein neues Studiengebiet – Deep Learning – als getrennt von der Frage des überwachten vs. nicht überwachten Lernens.

Beim überwachten Lernen werden einem Computer Beispiele für Eingaben und die gewünschten Ausgaben präsentiert. Das Ziel des Computers ist es, eine allgemeine Formel zu lernen, die Eingaben auf Ausgaben abbildet. Dies kann weiter unterteilt werden in:

  • Halbüberwachtes Lernen , bei dem der Computer einen unvollständigen Trainingssatz erhält, bei dem einige Ausgaben fehlen
  • Aktives Lernen , wenn der Computer nur für eine sehr begrenzte Anzahl von Instanzen Trainingsbezeichnungen erhalten kann. Bei interaktiver Verwendung können ihre Trainingssets dem Benutzer zur Kennzeichnung präsentiert werden.
  • Reinforcement Learning , d. h. wenn die Trainingsdaten nur als Feedback zu den Aktionen des Programms in der dynamischen Umgebung gegeben werden, z. B. zum Fahren eines Fahrzeugs oder zum Spielen eines Spiels gegen einen Gegner

Im Gegensatz dazu werden beim unüberwachten Lernen überhaupt keine Labels angegeben und es liegt am Algorithmus, die Struktur in seiner Eingabe zu finden. Unüberwachtes Lernen kann ein Ziel für sich sein, wenn wir nur versteckte Muster entdecken müssen.

Deep Learning ist ein neues Studiengebiet, das von der Struktur und Funktion des menschlichen Gehirns inspiriert ist und nicht nur auf statistischen Konzepten, sondern auf künstlichen neuronalen Netzen basiert. Deep Learning kann sowohl in überwachten als auch in unüberwachten Ansätzen verwendet werden.

In diesem Artikel werden wir nur einige der einfacheren überwachten maschinellen Lernalgorithmen durchgehen und sie verwenden, um die Überlebenschancen einer Person beim tragischen Untergang der Titanic zu berechnen. Aber im Allgemeinen, wenn Sie sich nicht sicher sind, welchen Algorithmus Sie verwenden sollen, ist der Spickzettel für maschinelle Lernalgorithmen von scikit-learn ein guter Ausgangspunkt.

Grundlegende Modelle für überwachtes maschinelles Lernen

Der vielleicht einfachste mögliche Algorithmus ist die lineare Regression. Manchmal kann dies grafisch als gerade Linie dargestellt werden, aber trotz ihres Namens könnte diese Linie, wenn es eine Polynomhypothese gibt, stattdessen eine Kurve sein. In jedem Fall modelliert es die Beziehungen zwischen der skalaren abhängigen Variablen $y$ und einem oder mehreren erklärenden Werten, die mit $x$ bezeichnet werden.

Für Laien bedeutet dies, dass die lineare Regression der Algorithmus ist, der die Abhängigkeit zwischen jedem bekannten $x$ und $y$ lernt, sodass wir ihn später verwenden können, um $y$ für eine unbekannte Stichprobe von $x$ vorherzusagen.

In unserem ersten Beispiel für überwachtes Lernen verwenden wir ein einfaches lineares Regressionsmodell, um den Blutdruck einer Person in Anbetracht ihres Alters vorherzusagen. Dies ist ein sehr einfacher Datensatz mit zwei aussagekräftigen Merkmalen: Alter und Blutdruck.

Wie oben bereits erwähnt, funktionieren die meisten Machine-Learning-Algorithmen, indem sie eine statistische Abhängigkeit in den ihnen zur Verfügung gestellten Daten finden. Diese Abhängigkeit wird als Hypothese bezeichnet und üblicherweise mit $h(\theta)$ bezeichnet.

Um die Hypothese herauszufinden, beginnen wir mit dem Laden und Untersuchen der Daten.

 import matplotlib.pyplot as plt from pandas import read_csv import os # Load data data_path = os.path.join(os.getcwd(), "data/blood-pressure.txt") dataset = read_csv(data_path, delim_whitespace=True) # We have 30 entries in our dataset and four features. The first feature is the ID of the entry. # The second feature is always 1. The third feature is the age and the last feature is the blood pressure. # We will now drop the ID and One feature for now, as this is not important. dataset = dataset.drop(['ID', 'One'], axis=1) # And we will display this graph %matplotlib inline dataset.plot.scatter(x='Age', y='Pressure') # Now, we will assume that we already know the hypothesis and it looks like a straight line h = lambda x: 84 + 1.24 * x # Let's add this line on the chart now ages = range(18, 85) estimated = [] for i in ages: estimated.append(h(i)) plt.plot(ages, estimated, 'b')

[<matplotlib.lines.Line2D at 0x11424b828>]

Eine lineare Hypothese, die in einem Diagramm zwischen Alter und Blutdruck dargestellt wird.

Auf dem obigen Diagramm stellt jeder blaue Punkt unsere Datenprobe dar und die blaue Linie ist die Hypothese, die unser Algorithmus lernen muss. Was genau ist diese Hypothese überhaupt?

Um dieses Problem zu lösen, müssen wir die Abhängigkeit zwischen $x$ und $y$ lernen, die mit $y = f(x)$ bezeichnet wird. Daher ist $f(x)$ die ideale Zielfunktion. Der maschinelle Lernalgorithmus versucht, die Hypothesenfunktion $h(x)$ zu erraten, die die engste Annäherung an die Unbekannte $f(x)$ ist.

Die denkbar einfachste Hypothesenform für das lineare Regressionsproblem sieht so aus: $h_\theta(x) = \theta_0 + \theta_1 * x$. Wir haben eine einzelne Eingabe-Skalarvariable $x$, die eine einzelne Skalarvariable $y$ ausgibt, wobei $\theta_0$ und $\theta_1$ Parameter sind, die wir lernen müssen. Der Vorgang des Einpassens dieser blauen Linie in die Daten wird als lineare Regression bezeichnet. Es ist wichtig zu verstehen, dass wir nur einen Eingabeparameter $x_1$ haben; Viele Hypothesenfunktionen enthalten jedoch auch die Bias-Einheit ($x_0$). Unsere resultierende Hypothese hat also die Form $h_\theta(x) = \theta_0 * x_0 + \theta_1 * x_1$. Aber wir können vermeiden, $x_0$ zu schreiben, weil es fast immer gleich 1 ist.

Zurück zur blauen Linie. Unsere Hypothese sieht aus wie $h(x) = 84 + 1,24x$, was bedeutet, dass $\theta_0 = 84$ und $\theta_1 = 1,24$. Wie können wir diese $\theta$-Werte automatisch ableiten?

Wir müssen eine Kostenfunktion definieren. Im Wesentlichen berechnet die Kostenfunktion einfach den mittleren quadratischen Fehler zwischen der Modellvorhersage und der tatsächlichen Ausgabe.

\[J(\theta) = \frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})^2\ ]

Zum Beispiel sagt unsere Hypothese voraus, dass der Blutdruck eines 48-Jährigen $h(48) = 84 + 1,24 * 48 = 143 mmHg$ betragen sollte; In unserem Trainingsmuster haben wir jedoch den Wert von $130 mmHg$. Daher ist der Fehler $(143 - 130)^2 = 169$. Jetzt müssen wir diesen Fehler für jeden einzelnen Eintrag in unserem Trainingsdatensatz berechnen und dann zusammenzählen ($\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i )})^2$) und daraus den Mittelwert nehmen.

Dies gibt uns eine einzelne skalare Zahl, die die Kosten der Funktion darstellt. Unser Ziel ist es, $\theta$-Werte zu finden, bei denen die Kostenfunktion am niedrigsten ist; mit anderen Worten, wir wollen die Kostenfunktion minimieren. Dies wird hoffentlich intuitiv erscheinen: Wenn wir einen kleinen Kostenfunktionswert haben, bedeutet dies, dass der Vorhersagefehler ebenfalls klein ist.

 import numpy as np # Let's calculate the cost for the hypothesis above h = lambda x, theta_0, theta_1: theta_0 + theta_1 * x def cost(X, y, t0, t1): m = len(X) # the number of the training samples c = np.power(np.subtract(h(X, t0, t1), y), 2) return (1 / (2 * m)) * sum(c) X = dataset.values[:, 0] y = dataset.values[:, 1] print('J(Theta) = %2.2f' % cost(X, y, 84, 1.24))

J(Theta) = 1901.95

Nun müssen wir solche Werte von $\theta$ finden, dass unser Kostenfunktionswert minimal ist. Aber wie machen wir das?

\[minJ(\theta) = \frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})^2\ ]

Es gibt mehrere mögliche Algorithmen, aber der beliebteste ist Gradient Descent . Um die Intuition hinter der Gradientenabstiegsmethode zu verstehen, zeichnen wir sie zuerst in das Diagramm ein. Der Einfachheit halber gehen wir von einer einfacheren Hypothese $h(\theta) = \theta_1 * x$ aus. Als Nächstes zeichnen wir ein einfaches 2D-Diagramm, in dem $x$ der Wert von $\theta$ und $y$ die Kostenfunktion an diesem Punkt ist.

 import matplotlib.pyplot as plt fig = plt.figure() # Generate the data theta_1 = np.arange(-10, 14, 0.1) J_cost = [] for t1 in theta_1: J_cost += [ cost(X, y, 0, t1) ] plt.plot(theta_1, J_cost) plt.xlabel(r'$\theta_1$') plt.ylabel(r'$J(\theta)$') plt.show() 

Eine konvexe Kostenfunktion.

Die Kostenfunktion ist konvex, was bedeutet, dass es auf dem Intervall $[a, b]$ nur ein Minimum gibt. Was wiederum bedeutet, dass die besten $\theta$-Parameter dort liegen, wo die Kostenfunktion minimal ist.

Grundsätzlich ist der Gradientenabstieg ein Algorithmus, der versucht, den Parametersatz zu finden, der die Funktion minimiert. Es beginnt mit einem Anfangssatz von Parametern und unternimmt iterativ Schritte in die negative Richtung des Funktionsgradienten.

Finden des Minimums für eine Kostenfunktion.

Wenn wir die Ableitung einer hypothetischen Funktion an einem bestimmten Punkt berechnen, erhalten wir eine Steigung der Tangente an die Kurve an diesem Punkt. Das bedeutet, dass wir die Steigung an jedem einzelnen Punkt des Diagramms berechnen können.

So funktioniert der Algorithmus:

  1. Wir wählen einen zufälligen Startpunkt (random $\theta$).
  2. Berechnen Sie an dieser Stelle die Ableitung der Kostenfunktion.
  3. Machen Sie den kleinen Schritt zur Steigung $\theta_j := \theta_j - \lambda * \frac{\partial}{\partial \theta_j} * J(\theta)$.
  4. Wiederholen Sie die Schritte 2-3, bis wir konvergieren.

Nun hängt die Konvergenzbedingung von der Implementierung des Algorithmus ab. Wir können nach 50 Schritten, nach einer Schwelle oder irgendetwas anderem aufhören.

 import math # Example of the simple gradient descent algorithm taken from Wikipedia cur_x = 2.5 # The algorithm starts at point x gamma = 0.005 # Step size multiplier precision = 0.00001 previous_step_size = cur_x df = lambda x: 2 * x * math.cos(x) # Remember the learning curve and plot it while previous_step_size > precision: prev_x = cur_x cur_x += -gamma * df(prev_x) previous_step_size = abs(cur_x - prev_x) print("The local minimum occurs at %f" % cur_x)

The local minimum occurs at 4.712194

Wir werden diese Algorithmen in diesem Artikel nicht implementieren. Stattdessen verwenden wir das weit verbreitete scikit-learn , eine Open-Source-Python-Bibliothek für maschinelles Lernen. Es bietet viele sehr nützliche APIs für verschiedene Data-Mining- und Machine-Learning-Probleme.

 from sklearn.linear_model import LinearRegression # LinearRegression uses the gradient descent method # Our data X = dataset[['Age']] y = dataset[['Pressure']] regr = LinearRegression() regr.fit(X, y) # Plot outputs plt.xlabel('Age') plt.ylabel('Blood pressure') plt.scatter(X, y, color='black') plt.plot(X, regr.predict(X), color='blue') plt.show() plt.gcf().clear() 

Eine erlernte lineare Hypothese zum Diagramm Blutdruck vs. Alter

<matplotlib.figure.Figure at 0x120fae1d0>

 print( 'Predicted blood pressure at 25 yo = ', regr.predict(25) ) print( 'Predicted blood pressure at 45 yo = ', regr.predict(45) ) print( 'Predicted blood pressure at 27 yo = ', regr.predict(27) ) print( 'Predicted blood pressure at 34.5 yo = ', regr.predict(34.5) ) print( 'Predicted blood pressure at 78 yo = ', regr.predict(78) )
 Predicted blood pressure at 25 yo = [[ 122.98647692]] Predicted blood pressure at 45 yo = [[ 142.40388395]] Predicted blood pressure at 27 yo = [[ 124.92821763]] Predicted blood pressure at 34.5 yo = [[ 132.20974526]] Predicted blood pressure at 78 yo = [[ 174.44260555]]

Arten von statistischen Daten

Bei der Arbeit mit Daten für maschinelle Lernprobleme ist es wichtig, verschiedene Arten von Daten zu erkennen. Wir können numerische (kontinuierliche oder diskrete), kategoriale oder ordinale Daten haben.

Numerische Daten haben Bedeutung als Maß. Zum Beispiel Alter, Gewicht, Anzahl der Bitcoins, die eine Person besitzt, oder wie viele Artikel die Person pro Monat schreiben kann. Numerische Daten können weiter in diskrete und kontinuierliche Typen unterteilt werden.

  • Diskrete Daten stellen Daten dar, die mit ganzen Zahlen gezählt werden können, z. B. Anzahl der Zimmer in einer Wohnung oder Anzahl der Münzwürfe.
  • Kontinuierliche Daten können nicht unbedingt mit ganzen Zahlen dargestellt werden. Wenn du zum Beispiel die Distanz misst, die du springen kannst, kann es 2 Meter oder 1,5 Meter oder 1,652245 Meter sein.

Kategoriale Daten stellen Werte wie Geschlecht, Familienstand, Land usw. einer Person dar. Diese Daten können numerische Werte annehmen, aber diese Zahlen haben keine mathematische Bedeutung. Sie können sie nicht addieren.

Ordinale Daten können eine Mischung aus den beiden anderen Typen sein, insofern Kategorien mathematisch sinnvoll nummeriert werden können. Ein gängiges Beispiel sind Bewertungen: Oft werden wir gebeten, Dinge auf einer Skala von eins bis zehn zu bewerten, und es sind nur ganze Zahlen erlaubt. Während wir dies numerisch verwenden können, um beispielsweise eine durchschnittliche Bewertung für etwas zu finden, behandeln wir die Daten oft so, als wären sie kategorisch, wenn es darum geht, Methoden des maschinellen Lernens darauf anzuwenden.

Logistische Regression

Die lineare Regression ist ein toller Algorithmus, der uns hilft, numerische Werte vorherzusagen, zB den Preis des Hauses mit der bestimmten Größe und Anzahl der Zimmer. Manchmal möchten wir jedoch auch kategoriale Daten vorhersagen, um Antworten auf Fragen zu erhalten wie:

  • Ist das ein Hund oder eine Katze?
  • Ist dieser Tumor bösartig oder gutartig?
  • Ist dieser Wein gut oder schlecht?
  • Ist diese E-Mail Spam oder nicht?

Oder auch:

  • Welche Nummer ist auf dem Bild?
  • Zu welcher Kategorie gehört diese E-Mail?

Alle diese Fragen sind spezifisch für das Klassifikationsproblem . Und der einfachste Klassifizierungsalgorithmus wird als logistische Regression bezeichnet, die letztendlich mit der linearen Regression identisch ist, außer dass sie eine andere Hypothese hat.

Zunächst einmal können wir dieselbe lineare Hypothese $h_\theta(x) = \theta^TX$ wiederverwenden (diese liegt in vektorisierter Form vor). Während die lineare Regression eine beliebige Zahl im Intervall $[a, b]$ ausgeben kann, kann die logistische Regression nur Werte in $[−1, 1]$ ausgeben, was die Wahrscheinlichkeit ist, dass das Objekt in eine bestimmte Kategorie fällt oder nicht.

Mit einer Sigmoid-Funktion können wir jeden numerischen Wert umwandeln, um einen Wert im Intervall $[−1, 1]$ darzustellen.

\[f(x) = \frac{1}{1 + e^x}\]

Jetzt müssen wir anstelle von $x$ eine bestehende Hypothese übergeben und erhalten daher:

\[f(x) = \frac{1}{1 + e^{\theta_0 + \theta_1 * x_1 + ... + \theta_n * x_n}}\]

Danach können wir einen einfachen Schwellenwert anwenden, der besagt, dass dies ein wahrer Wert ist, wenn die Hypothese größer als Null ist, andernfalls falsch.

\[h_\theta(x) = \begin{cases} 1 & \mbox{if } \theta^TX > 0 \\ 0 & \mbox{else} \end{cases}\]

Das bedeutet, dass wir dieselbe Kostenfunktion und denselben Gradientenabstiegsalgorithmus verwenden können, um eine Hypothese für die logistische Regression zu lernen.

In unserem nächsten Beispiel für maschinelle Lernalgorithmen beraten wir die Piloten des Space Shuttles, ob sie die automatische oder manuelle Landesteuerung verwenden sollten oder nicht. Wir haben einen sehr kleinen Datensatz – 15 Stichproben – der aus sechs Merkmalen und der Grundwahrheit besteht .

In maschinellen Lernalgorithmen bezieht sich der Begriff „ Ground Truth “ auf die Genauigkeit der Klassifizierung des Trainingssatzes für überwachte Lerntechniken.

Unser Datensatz ist vollständig, was bedeutet, dass keine Merkmale fehlen; Einige der Funktionen haben jedoch ein „*“ anstelle der Kategorie, was bedeutet, dass diese Funktion keine Rolle spielt. Wir werden alle diese Sternchen durch Nullen ersetzen.

 from sklearn.linear_model import LogisticRegression # Data data_path = os.path.join(os.getcwd(), "data/shuttle-landing-control.csv") dataset = read_csv(data_path, header=None, names=['Auto', 'Stability', 'Error', 'Sign', 'Wind', 'Magnitude', 'Visibility'], na_values='*').fillna(0) # Prepare features X = dataset[['Stability', 'Error', 'Sign', 'Wind', 'Magnitude', 'Visibility']] y = dataset[['Auto']].values.reshape(1, -1)[0] model = LogisticRegression() model.fit(X, y) # For now, we're missing one important concept. We don't know how well our model # works, and because of that, we cannot really improve the performance of our hypothesis. # There are a lot of useful metrics, but for now, we will validate how well # our algorithm performs on the dataset it learned from. "Score of our model is %2.2f%%" % (model.score(X, y) * 100)

Score of our model is 73.33%

Validierung?

Im vorherigen Beispiel haben wir die Leistung unseres Modells anhand der Lerndaten validiert. Ist dies jetzt jedoch eine gute Option, da unser Algorithmus die Daten entweder unter- oder überpassen kann? Schauen wir uns das einfachere Beispiel an, in dem wir ein Merkmal haben, das die Größe eines Hauses darstellt, und ein anderes, das seinen Preis darstellt.

 from sklearn.pipeline import make_pipeline from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression from sklearn.model_selection import cross_val_score # Ground truth function ground_truth = lambda X: np.cos(15 + np.pi * X) # Generate random observations around the ground truth function n_samples = 15 degrees = [1, 4, 30] X = np.linspace(-1, 1, n_samples) y = ground_truth(X) + np.random.randn(n_samples) * 0.1 plt.figure(figsize=(14, 5)) models = {} # Plot all machine learning algorithm models for idx, degree in enumerate(degrees): ax = plt.subplot(1, len(degrees), idx + 1) plt.setp(ax, xticks=(), yticks=()) # Define the model polynomial_features = PolynomialFeatures(degree=degree) model = make_pipeline(polynomial_features, LinearRegression()) models[degree] = model # Train the model model.fit(X[:, np.newaxis], y) # Evaluate the model using cross-validation scores = cross_val_score(model, X[:, np.newaxis], y) X_test = X plt.plot(X_test, model.predict(X_test[:, np.newaxis]), label="Model") plt.scatter(X, y, edgecolor='b', s=20, label="Observations") plt.xlabel("x") plt.ylabel("y") plt.ylim((-2, 2)) plt.title("Degree {}\nMSE = {:.2e}".format( degree, -scores.mean())) plt.show() 

Dieselben Daten, modelliert durch Polynome ersten, vierten und 30. Grades, um Underfitting und Overfitting zu demonstrieren.

Das Modell des maschinellen Lernalgorithmus ist unzureichend angepasst , wenn es weder die Trainingsdaten noch neue Beobachtungen verallgemeinern kann. Im obigen Beispiel verwenden wir eine einfache lineare Hypothese, die den tatsächlichen Trainingsdatensatz nicht wirklich darstellt und eine sehr schlechte Leistung aufweisen wird. Normalerweise wird Underfitting nicht diskutiert, da es bei einer guten Metrik leicht erkannt werden kann.

Wenn sich unser Algorithmus an jede einzelne Beobachtung erinnert, die ihm gezeigt wurde, weist er bei neuen Beobachtungen außerhalb des Trainingsdatensatzes eine schlechte Leistung auf. Dies wird Überanpassung genannt. Beispielsweise durchläuft ein Polynommodell 30. Grades die meisten Punkte und hat eine sehr gute Punktzahl im Trainingssatz, aber alles andere würde schlecht abschneiden.

Unser Datensatz besteht aus einem Merkmal und lässt sich einfach im 2D-Raum darstellen; Im wirklichen Leben haben wir jedoch möglicherweise Datensätze mit Hunderten von Merkmalen, was es unmöglich macht, sie visuell im euklidischen Raum darzustellen. Welche anderen Möglichkeiten haben wir, um zu sehen, ob das Modell unter- oder überangepasst ist?

Es ist an der Zeit, Ihnen das Konzept der Lernkurve vorzustellen. Dies ist ein einfaches Diagramm, das den mittleren quadratischen Fehler über der Anzahl der Trainingsgebiete darstellt.

In Lernmaterialien sehen Sie normalerweise ähnliche Grafiken wie diese:

Theoretische Lernkurvenvariationen basierend auf dem Polynomgrad.

Im wirklichen Leben erhalten Sie jedoch möglicherweise kein so perfektes Bild. Zeichnen wir die Lernkurve für jedes unserer Modelle.

 from sklearn.model_selection import learning_curve, ShuffleSplit # Plot learning curves plt.figure(figsize=(20, 5)) for idx, degree in enumerate(models): ax = plt.subplot(1, len(degrees), idx + 1) plt.title("Degree {}".format(degree)) plt.grid() plt.xlabel("Training examples") plt.ylabel("Score") train_sizes = np.linspace(.6, 1.0, 6) # Cross-validation with 100 iterations to get a smoother mean test and training # score curves, each time with 20% of the data randomly selected as a validation set. cv = ShuffleSplit(n_splits=100, test_size=0.2, random_state=0) model = models[degree] train_sizes, train_scores, test_scores = learning_curve( model, X[:, np.newaxis], y, cv=cv, train_sizes=train_sizes, n_jobs=4) train_scores_mean = np.mean(train_scores, axis=1) test_scores_mean = np.mean(test_scores, axis=1) plt.plot(train_sizes, train_scores_mean, 'o-', color="r", label="Training score") plt.plot(train_sizes, test_scores_mean, 'o-', color="g", label="Test score") plt.legend(loc = "best") plt.show() 

Trainingsergebnisse im Vergleich zu Testergebnissen für drei Diagramme mit Daten, die durch Polynome ersten, vierten und 30. Grades modelliert wurden.

In unserem simulierten Szenario erscheint die blaue Linie, die den Trainingsstand darstellt, wie eine gerade Linie. In Wirklichkeit nimmt es immer noch leicht ab – Sie können dies tatsächlich in der Polynomgrafik ersten Grades sehen, aber in den anderen ist es zu subtil, um es bei dieser Auflösung zu sagen. Wir sehen zumindest deutlich, dass bei einem „High Bias“-Szenario eine große Lücke zwischen Lernkurven für Training und Testbeobachtungen klafft.

Auf dem „normalen“ Lernratendiagramm in der Mitte können Sie sehen, wie die Trainingsergebnis- und Testergebnislinien zusammenkommen.

Und in der Grafik „hohe Varianz“ können Sie sehen, dass bei einer geringen Anzahl von Stichproben die Test- und Trainingsergebnisse sehr ähnlich sind; Wenn Sie jedoch die Anzahl der Proben erhöhen, bleibt das Trainingsergebnis nahezu perfekt, während das Testergebnis davon wegwächst.


Wir können Underfitting-Modelle (auch Modelle mit hoher Verzerrung genannt) korrigieren, wenn wir eine nicht-lineare Hypothese verwenden, z. B. die Hypothese mit mehr polynomialen Merkmalen.

Unser Overfitting-Modell ( hohe Varianz ) durchläuft jedes einzelne gezeigte Beispiel; Wenn wir jedoch Testdaten einführen, wird die Kluft zwischen den Lernkurven größer. Wir können Regularisierung, Kreuzvalidierung und weitere Datenbeispiele verwenden, um überangepasste Modelle zu korrigieren.

Kreuzvalidierung

Eine gängige Praxis zur Vermeidung von Overfitting besteht darin, einen Teil der verfügbaren Daten festzuhalten und als Testsatz zu verwenden. Bei der Bewertung verschiedener Modelleinstellungen, wie z. B. der Anzahl der Polynommerkmale, besteht jedoch immer noch die Gefahr einer Überanpassung des Testsatzes, da Parameter angepasst werden können, um die optimale Schätzerleistung zu erzielen, und daher unser Wissen über den Testsatz in das Modell eindringen. Um dieses Problem zu lösen, müssen wir einen weiteren Teil des Datensatzes festhalten, der als „Validierungssatz“ bezeichnet wird. Das Training wird auf dem Trainingsset fortgesetzt, und wenn wir der Meinung sind, dass wir die optimale Modellleistung erreicht haben, können wir eine abschließende Bewertung unter Verwendung des Validierungssets vornehmen.

Durch die Aufteilung der verfügbaren Daten in drei Sätze reduzieren wir jedoch die Anzahl der Stichproben, die zum Trainieren der Modelle verwendet werden können, drastisch, und die Ergebnisse können von einer bestimmten zufälligen Auswahl für das Paar von Sätzen aus Training und Validierung abhängen.

Eine Lösung für dieses Problem ist ein Verfahren namens Kreuzvalidierung. Bei der standardmäßigen $k$-fachen Kreuzvalidierung partitionieren wir die Daten in $k$-Teilmengen, sogenannte Folds. Dann trainieren wir den Algorithmus iterativ auf $k-1$-Folds, während wir den verbleibenden Fold als Testsatz verwenden (genannt „Holdout-Fold“).

Ein Raster, das die Position von Holdout-Falten in der k-fachen Kreuzvalidierung zeigt.

Die Kreuzvalidierung ermöglicht es Ihnen, Parameter nur mit Ihrem ursprünglichen Trainingssatz abzustimmen. Auf diese Weise können Sie Ihr Testset als wirklich unsichtbaren Datensatz für die Auswahl Ihres endgültigen Modells aufbewahren.

Es gibt viel mehr Kreuzvalidierungstechniken, wie P out lassen , stratifiziertes $k$-fold , shuffle und split , etc., aber sie würden den Rahmen dieses Artikels sprengen.

Regulierung

Dies ist eine weitere Technik, die helfen kann, das Problem der Modellüberanpassung zu lösen. Die meisten Datensätze haben ein Muster und etwas Rauschen. Ziel der Regularisierung ist es, den Einfluss des Rauschens auf das Modell zu reduzieren.

Ein Graph, der eine ursprüngliche Funktion und ihr regularisiertes Gegenstück gegenüberstellt.

Es gibt drei Hauptregularisierungstechniken: Lasso, Tikhonov und elastisches Netz.

Die L1-Regularisierung (oder Lasso-Regularisierung ) wählt einige Merkmale aus, die auf Null schrumpfen, sodass sie im endgültigen Modell keine Rolle spielen. L1 kann als Methode zur Auswahl wichtiger Merkmale angesehen werden.

Die L2-Regularisierung (oder Tikhonov-Regularisierung ) erzwingt, dass alle Merkmale relativ klein sind, sodass sie weniger Einfluss auf das Modell haben.

Das elastische Netz ist die Kombination aus L1 und L2.

Normalisierung (Feature-Skalierung)

Die Merkmalsskalierung ist auch ein wichtiger Schritt bei der Vorverarbeitung der Daten. Unser Datensatz kann Merkmale mit den Werten $[-\infty, \infty]$ und andere Merkmale mit einem anderen Maßstab enthalten. Dies ist eine Methode, um die Bereiche unabhängiger Werte zu standardisieren.

Die Merkmalsskalierung ist auch ein wichtiger Prozess, um die Leistung der Lernmodelle zu verbessern. Zunächst konvergiert der Gradientenabstieg viel schneller, wenn alle Merkmale auf die gleiche Norm skaliert werden. Außerdem arbeiten viele Algorithmen – zum Beispiel Support Vector Machines (SVM) – mit der Berechnung des Abstands zwischen zwei Punkten, und wenn eines der Merkmale breite Werte aufweist, wird der Abstand stark von diesem Merkmal beeinflusst.

Support-Vektor-Maschinen

SVM ist ein weiterer weit verbreiteter Algorithmus für maschinelles Lernen, der für Klassifizierungs- und Regressionsprobleme verwendet werden kann. In SVM stellen wir jede Beobachtung als Punkt im $n$-dimensionalen Raum dar, wobei $n$ die Anzahl der Features ist, die wir haben. Der Wert jedes Merkmals ist der Wert bestimmter Koordinaten. Dann versuchen wir, eine Hyperebene zu finden, die zwei Klassen gut genug trennt.

Ein Diagramm, das eine Hyperebene zeigt, die zwei Klassen von Datenpunkten trennt, wobei auch einige ihrer Unterstützungsvektoren dargestellt sind.

Nachdem wir die beste Hyperebene identifiziert haben, möchten wir Ränder hinzufügen, die die beiden Klassen weiter trennen würden.

Ein Diagramm, das eine Hyperebene mit Rändern zeigt.

SVM ist sehr effektiv, wenn die Anzahl der Merkmale sehr hoch ist oder wenn die Anzahl der Merkmale größer ist als die Anzahl der Datenproben. Da SVM jedoch auf Vektorbasis arbeitet, ist es entscheidend, die Daten vor der Verwendung zu normalisieren.

Neuronale Netze

Neuronale Netzwerkalgorithmen sind wahrscheinlich das spannendste Gebiet der Studien zum maschinellen Lernen. Neuronale Netze versuchen nachzuahmen, wie die Neuronen des Gehirns miteinander verbunden sind.

Eine Abbildung eines neuronalen Netzwerks, die verschiedene Eingaben zeigt, die temporären Werten zugeordnet sind, die wiederum einer einzigen Ausgabe zugeordnet sind.

So sieht ein neuronales Netz aus. Wir kombinieren viele Knoten miteinander, wobei jeder Knoten eine Reihe von Eingaben übernimmt, einige Berechnungen darauf anwendet und einen Wert ausgibt.

Es gibt eine große Vielfalt an neuronalen Netzwerkalgorithmen für überwachtes und unüberwachtes Lernen. Neuronale Netze können verwendet werden, um autonome Autos zu fahren, Spiele zu spielen, Flugzeuge zu landen, Bilder zu klassifizieren und vieles mehr.

Die berüchtigte Titanic

Die RMS Titanic war ein britisches Passagierschiff, das am 15. April 1912 im Nordatlantik sank, nachdem es mit einem Eisberg kollidierte. Es gab ungefähr 2.224 Besatzungsmitglieder und Passagiere, und mehr als 1.500 starben, was es zu einer der tödlichsten kommerziellen Seekatastrophen aller Zeiten machte.

Da wir nun die Intuition hinter den grundlegendsten maschinellen Lernalgorithmen verstehen, die für Klassifizierungsprobleme verwendet werden, können wir unser Wissen anwenden, um das Überlebensergebnis für diejenigen an Bord der Titanic vorherzusagen.

Unser Datensatz wird von der Kaggle-Plattform für Datenwissenschaftswettbewerbe ausgeliehen.

 import os from pandas import read_csv, concat # Load data data_path = os.path.join(os.getcwd(), "data/titanic.csv") dataset = read_csv(data_path, skipinitialspace=True) dataset.head(5)
Passagier-ID Überlebt P-Klasse Name Sex Zeitalter Geschwister Dörren Fahrkarte Fahrpreis Kabine Eingeschifft
0 1 0 3 Braund, Herr Owen Harris männlich 22.0 1 0 A/5 21171 7,2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs ... weiblich 38.0 1 0 PC17599 71.2833 C85 C
2 3 1 3 Heikkinen, Fräulein Laina weiblich 26.0 0 0 STON/O2. 3101282 7,9250 NaN S
3 4 1 1 Futrelle, Frau Jacques Heath (Lily May Peel) weiblich 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Herr William Henry männlich 35.0 0 0 373450 8.0500 NaN S

Unser erster Schritt wäre, die Daten zu laden und zu untersuchen. Wir haben 891 Testaufzeichnungen; Jeder Datensatz hat die folgende Struktur:

  • PassengerId – ID des Passagiers an Bord
  • Überleben – Ob die Person den Absturz überlebt hat oder nicht
  • pclass – Ticketklasse, z. B. 1., 2., 3.
  • gender – Geschlecht des Passagiers: Männlich oder weiblich
  • Name – Titel enthalten
  • Alter – Alter in Jahren
  • sibsp – Anzahl der Geschwister/Ehepartner an Bord der Titanic
  • parch – Anzahl der Eltern/Kinder an Bord der Titanic
  • ticket – Ticketnummer
  • Tarif – Passagiertarif
  • Kabine – Kabinennummer
  • eingeschifft – Einschiffungshafen

Dieser Datensatz enthält sowohl numerische als auch kategoriale Daten. Normalerweise ist es eine gute Idee, tiefer in die Daten einzutauchen und darauf basierend Annahmen zu treffen. In diesem Fall werden wir diesen Schritt jedoch überspringen und direkt zu den Vorhersagen übergehen.

 import pandas as pd # We need to drop some insignificant features and map the others. # Ticket number and fare should not contribute much to the performance of our models. # Name feature has titles (eg, Mr., Miss, Doctor) included. # Gender is definitely important. # Port of embarkation may contribute some value. # Using port of embarkation may sound counter-intuitive; however, there may # be a higher survival rate for passengers who boarded in the same port. dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=False) dataset = dataset.drop(['PassengerId', 'Ticket', 'Cabin', 'Name'], axis=1) pd.crosstab(dataset['Title'], dataset['Sex'])
Title \ Sex female männlich
Capt 0 1
Kol 0 2
Countess 1 0
Don 0 1
DR 1 6
Jonkheer 0 1
Lady 1 0
Wesentlich 0 2
Meister 0 40
Vermissen 182 0
Mlle 2 0
Mme 1 0
Mr 0 517
Mrs 125 0
Ms 1 0
Rev 0 6
Herr 0 1
 # We will replace many titles with a more common name, English equivalent, # or reclassification dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col',\ 'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Other') dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss') dataset['Title'] = dataset['Title'].replace('Ms', 'Miss') dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs') dataset[['Title', 'Survived']].groupby(['Title'], as_index=False).mean()
Titel Survived
0 Meister 0.575000
1 Vermissen 0.702703
2 Mr 0.156673
3 Mrs 0.793651
4 Andere 0.347826
 # Now we will map alphanumerical categories to numbers title_mapping = { 'Mr': 1, 'Miss': 2, 'Mrs': 3, 'Master': 4, 'Other': 5 } gender_mapping = { 'female': 1, 'male': 0 } port_mapping = { 'S': 0, 'C': 1, 'Q': 2 } # Map title dataset['Title'] = dataset['Title'].map(title_mapping).astype(int) # Map gender dataset['Sex'] = dataset['Sex'].map(gender_mapping).astype(int) # Map port freq_port = dataset.Embarked.dropna().mode()[0] dataset['Embarked'] = dataset['Embarked'].fillna(freq_port) dataset['Embarked'] = dataset['Embarked'].map(port_mapping).astype(int) # Fix missing age values dataset['Age'] = dataset['Age'].fillna(dataset['Age'].dropna().median()) dataset.head()
Survived Pclass Sex Zeitalter SibSp Parch Fare Embarked Titel
0 0 3 0 22.0 1 0 7.2500 0 1
1 1 1 1 38.0 1 0 71.2833 1 3
2 1 3 1 26.0 0 0 7.9250 0 2
3 1 1 1 35.0 1 0 53.1000 0 3
4 0 3 0 35.0 0 0 8.0500 0 1

At this point, we will rank different types of machine learning algorithms in Python by using scikit-learn to create a set of different models. It will then be easy to see which one performs the best.

  • Logistic regression with varying numbers of polynomials
  • Support vector machine with a linear kernel
  • Support vector machine with a polynomial kernel
  • Neural network

For every single model, we will use $k$-fold validation.

 from sklearn.model_selection import KFold, train_test_split from sklearn.pipeline import make_pipeline from sklearn.preprocessing import PolynomialFeatures, StandardScaler from sklearn.neural_network import MLPClassifier from sklearn.svm import SVC # Prepare the data X = dataset.drop(['Survived'], axis = 1).values y = dataset[['Survived']].values X = StandardScaler().fit_transform(X) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = None) # Prepare cross-validation (cv) cv = KFold(n_splits = 5, random_state = None) # Performance p_score = lambda model, score: print('Performance of the %s model is %0.2f%%' % (model, score * 100)) # Classifiers names = [ "Logistic Regression", "Logistic Regression with Polynomial Hypotheses", "Linear SVM", "RBF SVM", "Neural Net", ] classifiers = [ LogisticRegression(), make_pipeline(PolynomialFeatures(3), LogisticRegression()), SVC(kernel="linear", C=0.025), SVC(gamma=2, C=1), MLPClassifier(alpha=1), ]
 # iterate over classifiers models = [] trained_classifiers = [] for name, clf in zip(names, classifiers): scores = [] for train_indices, test_indices in cv.split(X): clf.fit(X[train_indices], y[train_indices].ravel()) scores.append( clf.score(X_test, y_test.ravel()) ) min_score = min(scores) max_score = max(scores) avg_score = sum(scores) / len(scores) trained_classifiers.append(clf) models.append((name, min_score, max_score, avg_score)) fin_models = pd.DataFrame(models, columns = ['Name', 'Min Score', 'Max Score', 'Mean Score'])
 fin_models.sort_values(['Mean Score']).head()
Name Min Score Max Score Mean Score
2 Linear SVM 0.793296 0.821229 0.803352
0 Logistic Regression 0.826816 0.860335 0.846927
4 Neural Net 0.826816 0.860335 0.849162
1 Logistic Regression with Polynomial Hypotheses 0.854749 0.882682 0.869274
3 RBF SVM 0.843575 0.888268 0.869274

Ok, so our experimental research says that the SVM classifier with a radial basis function (RBF) kernel performs the best. Now, we can serialize our model and re-use it in production applications.

 import pickle svm_model = trained_classifiers[3] data_path = os.path.join(os.getcwd(), "best-titanic-model.pkl") pickle.dump(svm_model, open(data_path, 'wb'))

Machine learning is not complicated, but it's a very broad field of study, and it requires knowledge of math and statistics in order to grasp all of its concepts.

Right now, machine learning and deep learning are among the hottest topics of discussion in Silicon Valley, and are the bread and butter of almost every data science company, mainly because they can automate many repetitive tasks including speech recognition, driving vehicles, financial trading, caring for patients, cooking, marketing, and so on.

Now you can take this knowledge and solve challenges on Kaggle.

This was a very brief introduction to supervised machine learning algorithms. Luckily, there are a lot of online courses and information about machine learning algorithms. I personally would recommend starting with Andrew Ng's course on Coursera.

Ressourcen

  • Andrew Ng's course on Coursera
  • Kaggle datasets
  • A deep learning reading list
  • A list of free books on machine learning algorithms, data mining, deep learning, and related topics
  • Eine Einführung in die Theorie des maschinellen Lernens und ihre Anwendungen: Ein visuelles Tutorial mit Beispielen
Related: Machines and Trust: How to Mitigate AI Bias