Sigmoidfunktion mit Python grafisch darstellen

In diesem Blogbeitrag dreht sich alles um die Sigmoidfunktion (auch als logistische Funktion bezeichnet) und ihre Darstellung mithilfe von Python. Das ich gerade zu dieser Funktion einen Artikel schreibe, mag zunächst seltsam erscheinen, tatsächlich aber spielt sie in der Praxis, namentlich bei neuronalen Netzen, eine große Rolle.

Die Sigmoidfunktion ist definiert als:

$$ f(x) = \frac{1}{1 + e^{-x}} $$

Dabei steht $ e $ für die Eulersche Zahl $ 2,71828… $. Die drei Punkte kennzeichnen, dass noch unendlich viele Dezimalstellen folgen.

In Python lässt sich diese Funktion folgendermaßen abbilden:

lambda x: 1 / (1 + np.exp(-x))

Auf zwei Aspekte möchte ich diesbezüglich eingehen. Zum einen liegt hier eine lambda-Funktion, also eine anonyme Funktion vor. Derartige Funktionen haben die Syntax:

lambda arguments : expression

Eine kurze Einführung zu lambda-Funktionen liefert dieser Blogbeitrag. Später wird noch deutlich werden, warum ich hier eine lambda-Funktion nutze.

Zum anderen wird die Methode exp() aus dem Paket NumPy verwendet, das mit pip installiert werden kann:

$ pip3 install numpy  (macOS, Linux)
$ pip install numpy   (Windows 10)

Mit diesem Wissen können wir uns jetzt an die Arbeit machen. Ziel ist es, eine Sigmoidfunktion mithilfe von matplotlib grafisch darzustellen, das ebenfalls mit pip installiert werden kann:

$ pip3 install matplotlib  (macOS, Linux)
$ pip install matplotlib   (Windows 10)

Den Anfang machen die Importanweisungen für numpy und matplotlib:

import numpy as np
import matplotlib.pyplot as plt

Weiter geht es mit den x-Werten. Hier soll eine Sigmoidfunktion mit den Werten von $ x = -10 $ bis $ x = 10 $ dargestellt werden. Hierfür könnte man eine Liste mit beispielsweise 100 Werten innerhalb des genannten Wertebereichs erstellen. Anstatt nun 100 Zahlen von Hand einzutippen, bietet sich mit der Methode linespace() aus dem Paket NumPy ein einfacherer Weg an:

x = np.linspace(-10, 10, 100)

Zur Berechnung der y-Werte kann map() verwendet werden. Dabei handelt es sich um eine Funktion, die als ersten Parameter eine Funktion und als zweiten Parameter eine Sequenz erwartet. Folgender Code wird aber nicht funktionieren:

y = map(1 / (1 + np.exp(-x)), x)

Die Ausführung dieser Zeile endet mit einem TypeError:

TypeError: 'numpy.ndarray' object is not callable

Deswegen wird der Ausdruck 1 / (1 + np.exp(-x) in eine lambda-Funktion „verpackt“, also

lambda x: 1 / (1 + np.exp(-x))

die als Argument an map() übergeben wird. Der Code zur Berechnung der y-Werte sieht jetzt folgendermaßen aus:

y = list(map(lambda x: 1 / (1 + np.exp(-x)), x))

Dabei findet mit list() eine Umwandlung in eine Liste statt, da diese Datenstruktur von der Methode plot() erwartet wird. Ohne die Verwendung von list() also mit

y = map(lambda x: 1 / (1 + np.exp(-x)), x)

würde man ein Iterator-Objekt erhalten, benötigt wird aber eine Sequenz, mithin eine Liste.

Schließlich wird die grafische Darstellung mit folgendem Code erstellt:

plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("Sigmoid(X)")

plt.show()
Sigmoidfunktion mit Matplotlib erstellt

Hier der vollständige Code:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-10, 10, 100)
y = list(map(lambda x: 1 / (1 + np.exp(-x)), x))

plt.plot(x, y)
plt.xlabel("x")
plt.ylabel("Sigmoid(X)")

plt.show()