Verborgene Signale · Begleitseite ← Alle Aktivitäten DE·EN
Kapitel 14 · Die Psychohistorik · Aktivität 14.1

Die Stimmung des Schwarms

Millionen Schlagzeilen, ein Gefühl: Du misst die Laune einer ganzen Menge über acht Jahre und machst sichtbar, wann die Welt hoffte — und wann sie zitterte.

Dauer 90 Min Schwierigkeit mittel Gruppe allein oder zu zweit Voraussetzung Kaggle-Konto (gratis) S

Kurz gesagt

Was: Du nimmst acht Jahre täglicher Nachrichten-Schlagzeilen, gibst jeder einen Stimmungswert — von negativ bis positiv — und mittelst sie zu einer einzigen Kurve: der Laune der Menge über die Zeit. Wo die Kurve einbricht, war etwas los.

Der Kern-Gedanke: Bisher hast du Einzelne gelesen — ein Gesicht, eine Stimme, eine Pflanze. Jetzt liest du die Menge. In der Summe von Millionen Spuren wird die Stimmung einer ganzen Gesellschaft messbar — die alte Science-Fiction-Idee der Psychohistorik, ganz real.

Du brauchst: den Datensatz „Daily News for Stock Market Prediction“ von Kaggle und Python mit pandas, vaderSentiment und matplotlib.

Worum es geht

1951 erdachte Isaac Asimov in Foundation eine Wissenschaft, die es nicht gab: die Psychohistorik. Ihr Erfinder kann das Schicksal eines ganzen Reiches vorausberechnen — nicht das eines einzelnen Menschen, aber das der Masse. Lange war das reine Erfindung. Doch heute hinterlässt jeder von uns ununterbrochen Spuren — Posts, Suchanfragen, Schlagzeilen —, und in der Summe ergeben Millionen solcher Spuren ein Messinstrument für die Stimmung einer Gesellschaft.

Schon 2010 haben wir sechs Monate lang die Stimmung von Millionen Twitter-Nachrichten gemessen — indem wir schlicht positive und negative Wörter zählten. Genau das machst du hier nach, nur mit einem fertigen, klugen Wortzähler und acht Jahren Nachrichten. Am Ende steht eine einzige Linie: die Gefühlskurve der Welt.

Bevor du startest — die Daten

Lade von Kaggle den Datensatz Daily News for Stock Market Prediction (kaggle.com/datasets/aaron7sun/stocknews). Darin steckt RedditNews.csv mit zwei Spalten: Date und News — die 25 meistgelesenen Weltnachrichten je Tag, von 2008 bis 2016. (Die Datei DJIA_table.csv mit den Börsenkursen brauchst du erst in 14.2.)

Ein bisschen Hintergrund

Wie misst man Stimmung? Wir nutzen VADER, einen fertigen Stimmungs-Leser, der eigens für kurze Social-Media-Texte gebaut wurde. Er kennt für Tausende Wörter, wie positiv oder negativ sie sind, achtet auf Verstärker („sehr“), Verneinungen („nicht gut“) und sogar Grossschreibung — und gibt am Ende eine einzige Zahl zwischen −1 (sehr negativ) und +1 (sehr positiv). Du trainierst nichts; du benutzt ein fertiges Werkzeug.

Von vielen Stimmen zu einer. Eine einzelne Schlagzeile sagt wenig. Aber der Durchschnitt vieler Schlagzeilen pro Tag glättet den Zufall heraus und lässt eine gemeinsame Stimmung übrig — so wie das Rauschen vieler Einzelmessungen erst im Mittel ein Signal ergibt. Das ist der Kern der Psychohistorik: Der Einzelne ist unberechenbar, die Menge nicht.

Daten holen

  1. Pakete installieren. pip install pandas vaderSentiment matplotlib.
  2. Datensatz laden. Von Kaggle herunterladen, entpacken und RedditNews.csv neben dein Skript legen.
  3. Kurz hineinschauen. pd.read_csv("RedditNews.csv").head() — zwei Spalten, Date und News. So weisst du, womit du arbeitest.

Die Stimmung berechnen

Jede Schlagzeile bekommt einen Wert, dann mitteln wir pro Tag. Der vollständige Code liegt auf GitHub.

import pandas as pd
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer

nachrichten = pd.read_csv("RedditNews.csv")      # Spalten: Date, News
vader = SentimentIntensityAnalyzer()             # fertiger Stimmungs-Leser (englisch)

# jede Schlagzeile -> ein Wert zwischen -1 (negativ) und +1 (positiv)
nachrichten["stimmung"] = nachrichten["News"].astype(str).apply(
    lambda text: vader.polarity_scores(text)["compound"])

# die Stimmung der Menge pro Tag = Mittelwert aller Schlagzeilen des Tages
taeglich = nachrichten.groupby("Date")["stimmung"].mean()
taeglich.index = pd.to_datetime(taeglich.index)
taeglich = taeglich.sort_index()
print(len(taeglich), "Tage  |  Durchschnittsstimmung:", round(taeglich.mean(), 3))

Die Stimmungskurve zeichnen

Die Tageswerte springen stark — ein gleitendes 30-Tage-Mittel macht den Trend sichtbar.

import matplotlib.pyplot as plt

geglaettet = taeglich.rolling(30, center=True).mean()    # 30-Tage-Mittel gegen das Rauschen
plt.figure(figsize=(11, 4))
plt.plot(taeglich.index, taeglich, color="#cfc6b4", lw=0.6, label="taeglich")
plt.plot(geglaettet.index, geglaettet, color="#2F5D3A", lw=2, label="30-Tage-Mittel")
plt.axhline(0, color="#999", lw=0.8)
plt.ylabel("Stimmung  (-1 negativ ... +1 positiv)")
plt.title("Die Stimmung des Schwarms ueber acht Jahre")
plt.legend(); plt.tight_layout(); plt.show()

Was du sehen solltest

Eine zappelige Tageslinie und darüber eine ruhigere grüne Trendkurve, die meist leicht im Negativen liegt — Weltnachrichten sind selten fröhlich. Interessant sind die Einbrüche: Suche die tiefsten Stellen und schlage nach, was damals geschah (Finanzkrise, Katastrophen, Konflikte). Oft passt die Delle zu einem realen Ereignis — die Kurve hat ein Gedächtnis.

Arbeitsblatt

Die Laune der Welt lesen

  1. An welchen zwei, drei Tiefpunkten liegt die geglättete Kurve am tiefsten? Recherchiere, welches Ereignis dazu passen könnte.
  2. Warum mitteln wir über viele Schlagzeilen und über 30 Tage? Was gewinnst du dadurch, was verlierst du?
  3. VADER liest Wörter, nicht Bedeutung. Nenne ein Beispiel (etwa Ironie oder ein doppeldeutiges Wort), bei dem so ein Werkzeug danebenliegen muss.
  4. Die Kurve liegt fast durchweg im Negativen. Heisst das, die Welt war überwiegend schlecht — oder sagt es eher etwas über die Nachrichten aus?
  5. „Den Einzelnen kannst du nicht vorhersagen, die Menge schon.“ Erkläre an deiner Kurve, warum das Mitteln vieler Einzelstimmen überhaupt erst eine lesbare Stimmung ergibt.
Lösung anzeigen

1. Individuell. Häufig fällt die Kurve rund um die Finanzkrise 2008/09 und in Phasen eskalierender Konflikte. Ziel ist, eine Delle mit einem realen Ereignis zu verknüpfen — und zu merken, dass die Zuordnung plausibel, aber nicht zwingend ist.

2. Der Durchschnitt vieler Schlagzeilen entfernt den Zufall einzelner Wörter; das 30-Tage- Mittel entfernt das Tages-Zappeln und zeigt den Trend. Gewinn: ein ruhiges, lesbares Signal. Verlust: kurze, echte Ausschläge (ein einzelner heftiger Tag) verschwinden.

3. Zum Beispiel „not bad“ (VADER erkennt die Verneinung meist, aber Ironie wie „great, another crisis“ nicht) oder ein Wort wie „positive“ in „positive test result“, das negativ gemeint ist. Ein Wortzähler kennt keinen Kontext.

4. Eher Zweites: Nachrichten berichten überproportional über Probleme und Konflikte, nicht über den ruhigen Alltag. Die Kurve misst die Stimmung der Berichterstattung, nicht direkt die der Welt — ein wichtiger Unterschied.

5. Eine einzelne Schlagzeile ist fast Zufall — mal positiv, mal negativ. Erst der Mittelwert vieler hebt das gemeinsame Signal aus dem Rauschen. Genau darum ist die Menge lesbar, wo der Einzelne es nicht ist.

Wenn's klemmt

ProblemWahrscheinliche Ursache & Lösung
KeyError: 'News'Spalte heisst anders (in mancher Version Headlines). Mit df.columns prüfen und den Namen anpassen.
Text beginnt mit b'...'Die Schlagzeilen sind als Byte-Strings gespeichert. Vorne b' und hinten ' entfernen, z. B. mit str.strip("b'\"").
Sehr langsam~73 000 Schlagzeilen zu bewerten dauert etwas. Einmal rechnen und das Ergebnis mit to_csv zwischenspeichern.
Kurve ist eine gerade LinieDate wurde nicht als Datum sortiert. pd.to_datetime und sort_index() nicht vergessen.
Alle Werte sind 0VADER bekam leere oder Nicht-Text-Werte. Mit .astype(str) absichern und leere Zeilen entfernen.

Zum Nachdenken

Erweiterung

← 13.2 Pflanzen-Emotionen mit KI 14.2 Asimovs Psychohistorik →