KI-Konzepte in Python

Markow-Ketten und der Kompromiss zwischen Erkunden und Ausnutzen in Python

KI muss oft unter Unsicherheit handeln. Eine Markow-Kette modelliert, wie ein System mit festen Wahrscheinlichkeiten zwischen Zuständen wechselt, und ein mehrarmiger Bandit zeigt die zentrale Entscheidung des bestärkenden Lernens: etwas Neues ausprobieren oder das nutzen, was bisher am besten funktioniert hat.

Das Konzept in einfachen Worten

KI muss oft unter Unsicherheit handeln. Eine Markow-Kette modelliert, wie ein System mit festen Wahrscheinlichkeiten zwischen Zuständen wechselt, und ein mehrarmiger Bandit zeigt die zentrale Entscheidung des bestärkenden Lernens: etwas Neues ausprobieren oder das nutzen, was bisher am besten funktioniert hat.

Sage künftige Zustände mit einer Markow-Kette voraus und balanciere Erkunden und Ausnutzen mit einem Epsilon-Greedy-Banditen.

Die wichtigsten Ideen

  • In einer Markow-Kette hängt der nächste Zustand nur vom aktuellen Zustand ab.
  • Die Übergangswahrscheinlichkeiten aus einem Zustand ergeben zusammen immer 1.
  • Erkunden findet bessere Optionen; Ausnutzen sammelt Belohnungen mit der besten bekannten Option.
  • Epsilon steuert das Gleichgewicht: Ein größeres Epsilon erkundet mehr.

Wann wird dieser Ansatz verwendet?

  • Verstehen, was in neuronalen Netzen und KI-Bibliotheken passiert.
  • Die Idee lernen, bevor du sie in den passenden Challenges umsetzt.
  • Dich auf Kurse zu maschinellem Lernen, Vorstellungsgespräche und Projekte vorbereiten.

Selbst ausprobieren

Ändere die Übergangswahrscheinlichkeiten des Wetters und sieh, wo sich die Kette einpendelt. Klicke auf Start, damit der Bandit lernt, welcher Automat mehr auszahlt.

Beispielcode

Code ausführen →
main.py
import random

# Markov chain: tomorrow's weather depends only on today's.
transitions = {"sunny": {"sunny": 0.8, "rainy": 0.2}, "rainy": {"sunny": 0.4, "rainy": 0.6}}
dist = {"sunny": 1.0, "rainy": 0.0}
for day in range(1, 4):
    dist = {s: sum(dist[p] * transitions[p][s] for p in dist) for s in dist}
    print(f"day {day}:", {s: round(v, 3) for s, v in dist.items()})

# Epsilon-greedy bandit: usually pick the best arm so far, sometimes explore.
random.seed(1)
true_payouts = [0.3, 0.7]
counts, totals = [0, 0], [0.0, 0.0]
epsilon = 0.1
for _ in range(500):
    if random.random() < epsilon or 0 in counts:
        arm = random.randrange(2)                                  # explore
    else:
        arm = max(range(2), key=lambda a: totals[a] / counts[a])  # exploit
    reward = 1 if random.random() < true_payouts[arm] else 0
    counts[arm] += 1
    totals[arm] += reward
print("pulls per arm:", counts)
print("estimated payouts:", [round(t / c, 2) for t, c in zip(totals, counts)])

Erwartete Ausgabe

day 1: {'sunny': 0.8, 'rainy': 0.2}
day 2: {'sunny': 0.72, 'rainy': 0.28}
day 3: {'sunny': 0.688, 'rainy': 0.312}
pulls per arm: [25, 475]
estimated payouts: [0.16, 0.7]

So funktioniert es

Jeden Tag sind die neuen Wahrscheinlichkeiten die alten mal die Übergangswahrscheinlichkeiten, daher sinkt „sonnig“ in drei Tagen von 1.0 auf 0.688. Der Bandit wählt in 10 % der Fälle einen zufälligen Arm und zieht sonst den Arm mit dem bisher besten Durchschnitt; bald zieht er meist den besseren Arm und schätzt dessen Auszahlung auf etwa 0.7.

Ändere die Werte und führe das Programm im CodeUtility Python Online-Compiler aus, ohne Python lokal zu installieren.

Übungsaufgaben

Verändere Eingaben und Randfälle, bevor du die Lösung mit größeren Datenmengen testest.

  1. Ändere Eingaben oder Gewichte und sage die Ausgabe vor dem Ausführen voraus.
  2. Gib die Zwischenwerte aus, um jeden Rechenschritt zu verfolgen.
  3. Löse die verlinkten Challenges unten, um die Idee selbst umzusetzen.
In der Python-IDE ausführen →

Mit einer Challenge üben

Nutze den Inhalt dieser Lektion, um ein echtes Problem zu lösen. Jede Challenge läuft im Browser, mit sofortigen Tests und einem KI-Review.

Alle Challenges