Die App, die ich mir vor 25 Jahren gewünscht hätte

Tatah: die App ist da!

Mit den im letzten Beitrag geteilten Ansätzen hast Du die Möglichkeit, das sogenannte „Rendite-Dreieck“ selbst zu erstellen. So kannst Du bequem miteinander vergleichen, welche Rendite langfristige Geldanlagen in der Vergangenheit erbracht haben.

WAHNSINN, oder?

Und ehrlich:

Ich hätte manche Entscheidung anders getroffen,
wenn ich das vor 25 Jahren gekonnt hätte.

Ich habe einigen Freunden und Bekannten von dieser Möglichkeit erzählt.
Und bin auf freundliches Interesse gestoßen.
Das war’s.

Kein „WAHNSINN!!!“.
Nur Thomas wollte den Code.

Falls es Dir ähnlich geht, dann habe ich heute etwas für Dich.
So hoffe ich.

In meinem letzten Beitrag hatte ich nämlich geschrieben:

Eine App muss her. Kurssymbol rein.
Klick auf „als Sparplan“ oder „als Investition“.
Rendite-Dreieck raus. Fertig.

Also, tatah, hier ist sie, die App:

Der „Financialyser“

https://ohlermichael.shinyapps.io/Financialyser/

Screenshot aus der App: Das Renditedreieck für einen monatlichen Sparplan in Gold.

Technischer Hintergrund zu der App

In diesem Blog betreiben wir „Open Source Analytics“ (OSAN) und verwenden dafür frei verfügbare Datenquellen und die Skript-, Berichts- und Webapplikationssprache R, die speziell für die Handhabung von Daten, Texten und Bildern entwickelt wurde. Hier nutze ich die Möglichkeit, eine Webapplikation zu erstellen. Du kannst R kostenfrei installieren.

Warum mir diese App so sehr am Herzen liegt

Mit dieser App kannst Du sehr schnell verschiedene Anlageformen vergleichen:
Wie sieht der DAX im Vergleich zum MSCI World aus? Schnell getan.
Und Gold? Einfach „GC=F“ als Symbol eingeben.

Die Liste aller Symbole findest Du mit einer Internetsuche.
Einige gängige Indizes habe ich gleich beigefügt.

Eine Geschichte vorab

Als ich im September 1990 mein Studium in Frankreich begonnen habe, da kam einer unserer Kommilitonen gerade aus Japan zurück. Er hatte Japanisch gelernt und war ein gefeierter Held. Denn die ganze Welt schaute damals auf Japan:

„Wie machen die das?“

Die japanische Wirtschaft hatte einen jahrelangen Höhenflug hinter sich.
Ein Ende war trotz eines aktuellen Einbruchs nicht in Sicht.

Seinen Höchststand vom 29. Dezember 1989 hat der japanische Nikkei 225 Index seither nicht mehr erreicht. Wenn Du damals eingestiegen wärst, dann würdest Du auch mehr als 30 Jahre später noch auf Verlusten sitzen.

Einzelne Aktien können kippen.
Ganze Märkte können stagnieren.
Und das über Jahrzehnte hinweg.

Schau Dir deshalb mit der App auch das Renditedreieck des Nikkei an (Symbol: ^N225).

Wo wir herkommen und was die App kann

In meinem letzten Beitrag habe ich die Codezeilen geteilt, die brauchst, um Daten von Einzelaktien, Indizes oder Gold herunterzuladen und als Renditedreieck darzustellen.

Die jetzt verfügbare App kann deutlich mehr. Für einen Index Deiner Wahl (z.B. ^GDAXI), für Gold (GC=F) oder für Einzelaktien (z.B. SIE.DE) kannst Du:

  • Den Verlauf darstellen
  • Zu einem Ein- und Ausstiegstermin die Rendite berechnen
  • Und das für eine Einmal-Investition und für einen monatlichen Sparplan
  • Für diese beiden Szenarien das Renditedreieck berechnen
  • Das „Erinnerungsvermögen“ (Autokorrelation) des Kurses bestimmen
  • Damit ein Szenario für mögliche zukünftige Entwicklungen simulieren
  • Die erwartete Renditeverteilung vieler Szenarien  berechnen
  • Simulationen für die Entnahmephase Deiner Anlage erstellen.

Renditeverteilung monatlicher Sparpläne:
Du planst, über die nächsten 20 Jahre hinweg jeden Monat 100 Euro in einen Wert (DAX, Euro Stoxx, MSCI World, Gold, …) zu investieren. Wie könnte am Ende das Ergebnis aussehen?

Regelmäßige Entnahmen:
Du hast insgesamt 250.000 Euro in einem Wert (Dax, …) angespart. Wie lange kannst Du jeden Monat 1500 Euro entnehmen, bis das Geld aufgebraucht ist?

Ich bin kein Anlageberater.
Und die App erlaubt Dir einen „Blick hinter den Vorhang“.

Professionelle Anlageberater können Dir bei der Entscheidung für einen privaten Rentensparplan helfen. Die App und der von mir geteilte Code für seine Erstellung helfen Dir, einen Blick hinter den Vorhang zu werfen. Denn Du wirst von Deinem Bankberater oder Deiner Beraterin hören, dass sie „Hunderte von Monte Carlo Simulationen“ durchgeführt haben und so gewisse Aussagen zu Renditeerwartungen treffen.

Meiner Ansicht nach muss bei so wichtigen Entscheidungen das Verständnis um diese Dinge „demokratisiert“ werden. Was Deine Bank Dir erzählt darf für Dich nicht nach „schwarzer Magie“ klingen. Du solltest nicht unterschreiben, ohne zumindest zu verstehen, woher diese Aussagen kommen.

In diesem Sinne erlaubt Dir die App, „hinter den Vorhang“ zu schauen. Wenn Du dadurch auch nur eine Dir wichtige Frage stellen kannst, dann hat sich die App gelohnt.

Auf keinen Fall jedoch solltest Du die App verwenden, um finanzielle Entscheidungen zu treffen. Überlege nur folgendes: Die App ist Software. Software besteht aus Code. Und Code hat – immer – Fehler. Vielleicht fehlt irgendwo ein Faktor. Oder eine Formel stimmt nicht. Oder es stellt sich im Jahr 2027 ein Szenario ein, das aus der Vergangenheit überhaupt nicht vorhersagbar war.

Wirf deshalb einen Blick hinter den Vorhang.
Und sprich mit den richtigen Leuten.

Ein Appell zum Mitmachen

Das ist die App, die ich vor 25 Jahren gebraucht hätte.
Mit dieser App hätte ich manches anders gemacht.
Vor allem hätte ich mehr selbst in die Hand genommen.

„Finanzielle Mündigkeit“ muss „demokratisiert“ werden.
Die Möglichkeit, sich eine schnelle Übersicht zu verschaffen und
Szenarien „durchzuspielen“ liefern einen wesentlichen Beitrag dazu.

Es freut mich deshalb, wenn Du die App nutzt.
Wenn Du mitmachen möchtest, um sie zu verbessern,
dann freut mich das besonders.

Im Grunde sucht diese App aber ein „neues Zuhause“.
Denn sie ist wichtig. Und wertvoll.
Und muss im richtigen Rahmen genutzt werden.
Ich freue mich über Vorschläge.

Geld in Aktien stecken – oder doch besser unter die Matratze?

Warum Du diesen Beitrag lesen solltest

Aktien- und Rententipps gibt es landauf, landab. Neben einem Hauskauf ist das jahrzehntelange Besparen eines Rentenplans eine der größten finanziellen Entscheidungen, die viele Menschen treffen. Allerdings musst Du den Expertinnen und Experten vieles glauben – und findest ein bis zwei Jahrzehnte später heraus, wie es gelaufen ist. Dieser Blog hilft Dir, rechtzeitig eigene quantitative Überlegungen anzustellen. Und zwar für:

  • Aktienfonds
  • Einzelaktien
  • Gold
  • Immobilien.

Wenn Du als Angestellte oder Angestellter mit Deinem aktuellen Rentenbescheid zufrieden bist, dann: herzlichen Glückwunsch! Denn in dem Fall kannst Du „rein aus Neugierde“ weiterlesen.

Haftungsausschluss

Ich möchte hier explizit auf mein Impressum hinweisen: auch dieser Beitrag dient in erster Linie der „Vision“des Blogs. Ich möchte darstellen, welche Einsichten sich über die Analyse öffentlich verfügbarer Daten gewinnen lassen. Meine Schlussfolgerungen wurden nicht im Vier-Augen-Prinzip von Expertinnen oder Experten validiert und können deshalb keine Grundlage für konkrete Maßnahmen sein. Ich bin auch nicht als Finanzberater ausgebildet.

Die Klage über uns Deutsche ist wohlbekannt

Die Deutschen sparen zu wenig.
So heißt es.

„Wie bitte??“
Magst Du einwenden.
Mit zwei großen Fragezeichen.

Denn immerhin gehören die „schwäbische Hausfrau“ und der schwäbische Hausmann auch dazu. Und zumindest DEREN Sparsamkeit ist ja sprichwörtlich!

Gemeint mit der Klage ist: unser Geld läge unter irgendeiner Matratze. Im Sparstrumpf. Auf dem Girokonto. Eben dort, wo es nicht hinsoll. Geld müsse vielmehr „arbeiten“. Zum Beispiel in AKTIEN investiert werden. Denn das sei SOOO RENTABEL, sagen die einen. Aber auch SOO GEFÄHRLICH, erwidern die anderen: „Alles futsch – verstohsch?“ (Das ist Badisch, wo ich herkomme, nicht Schwäbisch).

Dieser Weg kann ein leichter sein

Sich darüber Gedanken zu machen ist wichtig: es geht um die Rente. Deine Rente. Wenn Du gerade ins Berufsleben eintrittst, dann solltest Du genau jetzt loslegen. Wie Du es anstellst mit Deinem Sparplan für die Rente kann am Ende ohne weiteres für doppelt- oder für halb-soviel Geld sorgen. Es lohnt sich also. Und Du wirst sehen:

Dieser Weg ist eben nicht „steinig und schwer“.

Er wird vielmehr ein überraschend leichter sein.
Um es vorwegzunehmen:

Investiere regelmäßig.
Ziehe die Sache durch.
Entnimm gleichmäßig.

Zum Schluss habe ich noch einige persönliche Tipps, falls Du auch mit Deiner Bank darüber sprechen möchtest. Und ich glaube, dass Du das tun solltest.

Drei Wege zur Glückseligkeit

Vereinfacht gesagt hast Du drei Möglichkeiten:

  1. Nichts tun. Das ist bequem. Es kommt vermutlich nur weniger dabei heraus.
  2. Vertraue dem Banker. Auch gut. Denn das ist besser als nichts zu tun.
  3. DIY. Do it yourself. Klingt kompliziert. Ist es aber nicht. Du wirst sehen.

Meine Überzeugung vorab:
Wenn Du selbst die Winterreifen aufziehst,
oder Terrassenplatten eigenhändig verlegst,
zumindest die Zwiebeln selbst schneidest,
dann solltest Du überlegen,
ob DIY nicht Dein Weg ist.
Zumindest für einen Teil.
Deines Geldes.

Coden ist kein Hexenwerk

Um in diesem Blog zu unseren Schlüssen zu kommen, betreiben wir „Open Source Analytics“ (OSAN) und verwenden dafür frei verfügbare Datenquellen und die Skript-, Berichts- und Webapplikationssprache R, die speziell für die Handhabung von Daten, Texten und Bildern entwickelt wurde. Du kannst Sie kostenfrei installieren. Sprachen wie R und auch Python bieten Dir viele Vorteile, zum Beispiel diese:

  1. Du hast auf einen Schlag Zugang zu den neuesten und besten Analysewerkzeugen inklusive Dokumentation. Du kannst Dich auch bequem von „generativer“ künstlicher Intelligenz wie ChatGPT bei der Erstellung Deines Skripts coachen lassen.
  2. Du kannst Deine Analysen ständig aktuell halten: Einmal „Run“ gedrückt und schon lädt Dein Skript wieder die neuesten Daten herunter und wertet sie für Dich aus.
  3. Als Team ist Eure Lernkurve steiler: Anders als bei „Klicksoftware“ kannst Du Dein Vorgehen, inklusive aller „Tricks und Kniffe“, in einem Skript festhalten. So könnt Ihr Euer Vorgehen leicht untereinander teilen. Versuche einmal, das was wir hier tun, in Excel nachzubauen, was möglich ist, und das Excel-Blatt dann anderen zu erklären…
  4. Im Vergleich zu Tabellenkalkulationsprogrammen liegt der Unterschied darin, dass Deine Algorithmen von den Daten getrennt und nicht per Formeln in die Zellen verwoben werden. So ist viel deutlicher ersichtlich und nachvollziehbar, was Du tust.
  5. Deshalb ist es auch viel einfacher, Fehler, die sich immer einschleichen, in Deiner – oder meiner – Analyse aufzuspüren und zu korrigieren.

Wie sonst auch kannst Du diesen Beitrag auch ohne die Code-Zeilen lesen. Die Zwischenüberschriften erlauben Dir zu springen, falls bestimmte Abschnitte Dich mehr als andere interessieren.

Das „Rendite-Dreieck“: eine wichtige Visualisierung

Wie andere Tageszeitungen auch, so hat sich der Finanzteil der FAZ offensichtlich der Mission verschrieben, das Wissen um Geldfragen zu „demokratisieren“.

So lerne ich in einem Beitrag vom 19. Mai 2023 („MSCI World besser als der DAX“) das „Renditedreieck“ (siehe unten) kennen: eine aufschlussreiche Visualisierung, die wichtige, praktische Schlüsse zulässt. In diesem FAZ-Artikel stoße ich auch auf den Satz, der den heutigen Beitrag motiviert:

„… Insofern ist es verdienstvoll, dass das Deutsche Aktieninstitut nach dem Dax, dem Euro Stoxx 50 und Einzelaktien für Mitarbeiter nun auch den MSCI World als Renditedreieck gerechnet hat, und zwar in der Variante als monatlicher Sparplan“.

Echt jetzt?

Ein ganzes Institut rechnet erst „den Dax“, vielleicht nach eine Erholungspause „den Euro Stoxx 50“ und dankenswerterweise „nun auch“ den MSCI World? Das klingt nach einer Menge Arbeit. Das DAI veröffentlicht auch tatsächlich regelmäßig Renditedreiecke. Übrigens graphisch und didaktisch sehr gut aufbereitet und zum Download verfügbar. Vielleicht wurde es dort auch erfunden? Dir ist aber vermutlich klar, was das alles im Rahmen dieses Blogs bedeutet:

Eine App muss her. Kurssymbol rein.
Klick auf „als Sparplan“ oder „als Investition“.
Rendite-Dreieck raus. Fertig.

Der Dax auf Achterbahnfahrt

Dank Yahoo Finance, des quantmod-Pakets und der getSymbols-Funktion sind zumindest die Daten schnell beschafft und für unsere Zwecke aufbereitet, hier für den Dax (^GDAXI):

# Index oder Aktie:
stock <- "^GDAXI" 

# Wir wollen so weit wie möglich zurückblicken:
Horizont.Jahre <- 50 
end <- Sys.Date() - 1 # gestern
start <- end - 365*Horizont.Jahre

# Daten von Yahoo Finance herunterladen und aufbereiten:
Stock <- getSymbols(stock, 
                    from = start, 
                    to = end, 
                    auto.assign = FALSE) %>% 
         as.data.frame() %>% 
         rownames_to_column() %>% 
         drop_na() %>% 
         select(1, 5) %>% 
         rename_with(~ c("Date", "Stock"), 1:2) %>% 
         mutate(Date = as.Date(Date))

# Graphische Darstellung
ggplot() +
    geom_point(data = Stock,
               aes(x = Date, y = Stock)) +
    theme_minimal() +
    ylab(stock)

Verlauf des Dax seit dem Jahr 1987. Mit dem vorigen Code direkt aus tagesaktuellen Daten erstellt.

Was für eine Achterbahnfahrt!

Wenn Du im Jahr 2000 bei einem Kurs von 8000 eingestiegen wärst, dann hättest Du fast acht Jahre warten müssen, um Dein Geld wiederzusehen. Gleich danach wärst Du wieder „abgesoffen“ und erst im Laufe des Jahres 2014 da gelandet, wo Du im Jahr 2000 eingestiegen bist.

Angesichts solch einer Achterbahnfahrt sind Sorgen bezüglich Aktien berechtigt!

Dann allerdings, ab 2014, hätte sich Deine Anlage in den folgenden knapp 10 Jahren mehr als verdoppelt – was einer jährlichen Verzinsung von etwas mehr als 7% entspricht.

Lohnt sich das?
Oder ist das „Zockerglück“?

Darum soll es heute gehen.

Unser Zweck: die langfristige Perspektive

Es geht hier nicht um Chart-Analysen, „Unterstützungslinien“ und selbstgebastelte Aktientipps. Wir interessieren uns vielmehr für eine Perspektive von Jahrzehnten, von Deinem Einstieg ins Berufsleben bis hin zur Rente. Es geht uns auch um die Frage, ob eine Anlage in den Dax, den MSCI World, einen anderen Index-Fonds oder vielleicht auch in Gold oder Einzelaktien für die Altersvorsorge taugt. Denn wenn dem so wäre, dann könntest Du inzwischen über Direktbanken sehr günstig solche Zertifikate erwerben und halten. Die fälligen Kosten und Steuern – sowie die leidige Inflation – lasse ich aus unserer Betrachtung heraus.

Dieser Beitrag darf, kann und will Dir Deine eigene Entscheidung jedoch nicht abnehmen. Aber mit dem Renditedreieck, das Du für jeden Index, jede Aktie und auch für Gold selbst erstellen kannst, hast Du eine wichtige Entscheidungsgrundlage. Du musst nur in dem hier geteilten Code die Variable „stock“ (siehe oben im Code) anpassen.

Das Szenario „kaufen – halten – verkaufen“

Zunächst einmal möchte ich folgendes einfache Szenario betrachten: Du kaufst einen ETF (Exchange Traded Fund) zum Beispiel auf den Dax und lässt ihn einfach liegen. Wir möchten wissen, wie sich Deine Investition im Laufe der Jahre entwickelt. Das möchten wir für verschiedene Einstiegszeitpunkte betrachten und graphisch darstellen.

Auch wenn die Daten auf Tagesbasis vorliegen, betrachten wir bei diesem Anlagehorizont Jahresscheiben und bereiten die Daten entsprechend auf. Wir wählen deshalb den Kursstand zu jedem Jahresstart aus den Daten aus. Indem Du die Variable „period“ änderst, kannst Du selbstverständlich auch einen anderen Rhythmus wählen:

# In diesem Rhythmus betrachten wir die Entwicklung:
period <- "year"  

# Jahresscheiben erstellen:
t <- Stock %>%                                    
  mutate(Period = floor_date(Date, period)) %>% 
  group_by(Period) %>% 
  filter(Date == min(Date)) %>% 
  select(Period, Stock)

# Kauf- und Verkaufstabelle erstellen.
# Dafür kreuzen (crossing) wir die Kaufs- und Verkaufstabellen,
# filtern SellDate > BuyDate
# und berechnen neue Spalten mit mutate:
t2 <- t %>%
  select(Period, Stock) %>%
  rename(BuyDate = Period, 
         BuyValue = Stock) %>%
  crossing(t %>%
             select(Period, Stock) %>%
             rename(SellDate = Period, 
                    SellValue = Stock)) %>% 
  filter(SellDate > BuyDate) %>% 
  mutate(HoldTime.Days = difftime(SellDate, 
                                  BuyDate,  
                                  units = "days") %>% 
                         as.numeric()) %>% 
  mutate(HoldTime.Years = round(HoldTime.Days/365, 1)) %>% 
  mutate(Ratio = SellValue/BuyValue) %>% 
  mutate(Percent.per.Year = Ratio^(365/HoldTime.Days) - 1) %>% 
  mutate(Percentage = paste(round(Percent.per.Year*100, 0), 
                            "%", sep = "")) %>% 
  mutate(Intervals = cut(Percent.per.Year, 
                         breaks = my_breaks, 
                         labels = my_labels)) %>% 
  mutate(Intervals = factor(Intervals, levels = my_labels))

In dieser Tabelle t2 liegen nun alle Daten vor. Das Weitere ist ausschließlich der Visualisierung gewidmet – wie auch schon die letzten drei mutate-Anweisungen.

Erstellung des Renditedreiecks

Ich möchte, dass das Renditedreieck für verschiedene Aktien und Indizes jeweils die gleichen Farbskala aufweist. So lässt sich der MSCI World leichter mit dem Dax, dem Euro Stoxx 50 und auch mit Einzelwerten vergleichen. Diese Anforderung macht meinen Code etwas komplizierter. Deshalb habe ich in den obigen Zeilen die Renditewerte („Percent.per.Year“) mit „my_breaks“ in Intervalle aufgeteilt, diese mit „my_labels“ beschriftet und zudem eine eigene Farbtabelle erstellt. Breaks, Labels und Farbtabelle kannst Du selbstverständlich anpassen:

# So erstellen wir die Farb-Umbrüche:
my_breaks <- c(-Inf, -0.5, -0.4, -0.3, -0.2, -0.1, -0.05, -0.03, -0.01, 
               0.01, 0.03, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, Inf)

my_labels <- c("<-50%", "-50%..-40%", "-40%..-30%", "-30%..-20%", 
               "-20%..-10%", "-10%..-5%", "-5%..-0.3%", "-3%..-1%", 
               "-1% .. 1%", "1%..3%", "3%..5%", "5%..10%", "10%..20%", 
               "20%..30%", "30%..40%", "40%..50%", ">50%")

# Farbcodes:
color1 <- "#8B0000" # dark red
color2 <- "#FFFFFF" # white
color3 <- "#006400" # dark green

colourtable <- data.frame(
   Intervals = my_labels,
   colours = colorRampPalette(colors = c(color1, color2, color3))(17)
)

Die Schwierigkeit besteht nun darin, dass nicht jedes Renditedreieck alle Intervalle ausgeschöpft. Deshalb untersuche ich zunächst, welche aktuellen Farben („current_colours“ im nächsten Code-Block) vorliegen und verwende diese für die Einfärbung der Kacheln (tiles) in ggplot. Falls Du lieber Quartals- als Jahresscheiben betrachtest, was Du oben über die Variable „period“ einstellen kannst, dann lasse ich Dir die Fallunterscheidung noch im Code, sodass auch die Prozentwert-Beschriftungen in den Kacheln in einer passenden Größe erscheinen. Die vielen Formatanweisungen des ggplot lasse ich ebenfalls stehen – auf die Gefahr hin, dass es abschreckend wird. Aber so kannst Du den Code übernehmen und gleich loslegen:

# Wir berechnen die Farben DES VORLIEGENDEN Graphen, 
# in der richtigen Reihenfolge:
current_colours <- t2 %>% 
     arrange(Percent.per.Year) %>% 
     select(Intervals) %>% 
     unique() %>% 
     left_join(colourtable)

# Textgröße für Beschriftung der Zellen im Dreieck:
text.size <- case_when(
    period == "year" ~ 3,
    period == "quarter" ~1)

p <- ggplot(data = t2,
            aes(x = SellDate,
                y = BuyDate,
                fill = Intervals)) +
     geom_tile() +
     scale_fill_manual(values = current_colours$colours) +
     labs(title = paste("Renditedreieck", stock, sep = " "),
          x = "Verkauf",
          y = "Kauf") +
     # Ab hier folgen Formatanweisungen für die Darstellung:
     theme_minimal() +
     theme(panel.background = element_rect(fill = "white")) +
     scale_y_date(date_labels = "%Y", 
                  date_breaks = "5 years",
                  date_minor_breaks = "1 year") +
     scale_x_date(date_labels = "%Y", 
                  date_breaks = "5 years",
                  date_minor_breaks = "1 year") +
     geom_text(aes(label=paste(round(Percent.per.Year*100),
                               "%", sep = "")), 
               color="black",
               size = text.size) +
      guides(fill = guide_legend(title = NULL)) +
      theme(legend.position = c(0, 1), 
      legend.direction = "horizontal",
      legend.justification = c(0,1))

p

# Falls Du die Graphik abspeichern möchtest:
ggsave(filename = "MeinErstesrenditeDreieck.png",
       width = 20, height = 10, dpi = 300)

So erhalten wir nun endlich das Renditedreieck:

Renditedreieck des Dax für das Szenario: Kaufen – Liegen lassen – Verkaufen. Im Jahresrhythmus gerechnet. Vertikale Achse: Jahr des Kaufs. Horizontale Achse: Jahr des Verkaufs. In den Zellen abgebildet ist die jeweilige jährliche Rendite der Investition, Jahr für Jahr. Ohne Gebühren und Steuern gerechnet. Je nach dem, welchen Bildschirm Du verwendest, musst Du das Bild vergrößern, um alles lesen zu können. Du kannst es auch abspeichern (dafür mit der rechten Maustaste darauf klicken).

Wie Du das Renditedreieck liest

Auf der vertikalen Achse ist das Jahr des Kaufs dargestellt, auf der horizontalen das des Verkaufs. Es ergibt sich ein aufsteigendes Treppchen, weil man natürlich nicht früher verkaufen als kaufen kann. In den Kacheln dargestellt ist die jeweils erzielte Rendite der Anlage. Für jedes Verkaufsjahr entspricht die oberste Kachel, die „Stufe“ also, einer Haltezeit von einem Jahr. Bei einem gegebenen Einkaufsjahr gehst Du für längere Haltezeiten horizontal in das Dreieck hinein. Rote Kacheln entsprechen Verlusten, grüne Kacheln entsprechen Gewinnen und bei weißlich gefärbten wärst Du mehr oder weniger bei Null herausgekommen.

Schauen wir uns ein Beispiel an.

Wenn Du am 1. Januar 2002 in den Dax eingestiegen (vertikale Achse) und am 1. Januar 2003 schon wieder ausgestiegen wärst (horizontale Achse), was einer Haltezeit von einem Jahr entspricht, dann hättest Du satte 40% verloren. Allerdings hätte es sich gelohnt, die Nerven zu bewahren: bei einem Ausstieg schon im Folgejahr (eine Kachel weiter in horizontaler Richtung) hätten sich Deine Verluste auf 12% p.a. und bei einem Verkauf zum 1. Januar 2005 auf 6% p.a. begrenzt. Ab dem Jahr 2014 (bei gleicher vertikaler Position gehen wir auf der horizontalen Achse auf dieses Jahr) hättest Du aus Deiner Investition sogar eine jährliche Rendite von 5% herausgeholt. Bei einer Anlage von 1000 Euro im Jahr 2002 wären bis Anfang 2023 also 2790 Euro zusammengekommen, also mehr als doppelt soviel.

Ist das Zockerglück?

Für diese Frage schauen wir uns das Rendite-Dreieck genauer an: parallel zur Hypotenuse verlaufen die Linien gleichen Investitionshorizonts. Je größer der Abstand einer roten Kachel von der Hypotenuse desto länger hättest Du für diese Investition auf Dein Geld warten müssen. Über den gesamten Zeitraum betrachtet wäre eine Investition am 1. Januar 2000 die schlechteste gewesen, denn Du hättest selbst im Jahr 2010 noch ein Minus von einem Prozent pro Jahr gemacht. Das nächst-schlechte Einstiegsjahr wäre 2007 gewesen: bei einem Verkauf im Jahr 2012 hättest Du 2% Verluste pro Jahr eingefahren. Aber danach geht es nach oben.

Ist das „Zocken“?
Oder zahlt sich letztlich Geduld aus?

Wenn Du auf den Dax setzt, dann schließt Du eine Wette darauf ab, dass es mit der deutschen Wirtschaft, zumindest langfristig, „schon irgendwie bergauf gehen wird“. Im Betrachtungszeitraum heißt „langfristig“, dass Du einen Horizont von mehr als 10 Jahren mitbringen solltest, um auf der sicheren Seite zu liegen. Bei Berufseinstieg bringst Du etwa 40 Jahre mit.

Dax, Dow Jones oder MSCI World?

Eine andere spannende Frage ist natürlich: Soll ich wirklich in den Dax investieren? Oder lieber auf den Dow Jones setzen, einen MSCI-World-ETF kaufen oder doch in Einzelaktien gehen?

Solche Fragen beantwortet Dir Deine Bank sicher gerne – und empfiehlt Dir vielleicht stattdessen auch ein paar gemanagte Fonds – mit Ausgabeaufschlägen und Verwaltungsgebühren. Das kann durchaus eine sinnvolle Ergänzung oder Alternative sein. Dazu unten einige persönliche Gedanken.

Mein Vorschlag ist: baue das oben dargestellte Skript nach und passe die Variable „stock“ für den Index oder die Aktie an, die Dich interessieren. Und rechne auch einmal das Renditedreieck für den Nikkei. Du erinnerst Dich vielleicht: der hatte im Jahr 1990 seinen Höchststand…

Das Renditedreieck für den kontinuierlichen Sparplan

Unser bisheriges Szenario ist natürlich unrealistisch: Rentenpläne werden in der Regel kontinuierlich bespart. So könntest Du zum Beispiel beschließen, Monat für Monat 100 Euro zurückzulegen. Schön wäre es, wenn Du dabei nicht nachdenken müsstest: „Soll ich diesen Monat besser nicht, oder vielleicht ‚jetzt erst recht‘ kaufen?“

Ohne solche Gedanken hättest Du weniger Kopfschmerzen: Wenn alle von „Krise“ sprechen, dann machst Du genauso weiter wie zu Zeiten größter Euphorie. So wirst Du manchmal teuer einkaufen (zu „Bullenmarkt“-Zeiten, wenn alle sagen, dass Du kaufen sollst), manchmal günstig (in einer „Bärenmarkt“-Stimmung, wenn alle Dir davon abraten). Interessant wäre also, wie das Renditedreieck für dieses Szenario aussähe – und das hat ja schließlich auch das Deutsche Aktieninstitut gerechnet.

Wir stellen wir uns deshalb die Frage: welche Rendite, Jahr für Jahr, erhalten wir für solch eine kontinuierliche Investition? Um das zu rechnen, betrachten wir die Zahlungsströme: Monat für Monat gehen von Deinem Konto zum Beispiel 100 Euro in Richtung Sparplan ab und am Ende fließt Dir der Gesamtbetrag wieder zu. In Excel kannst Du mit der IKV-Funktion den „internen Zinsfluss“ oder „Zinsfuß“ solcher Geldströme berechnen. Meine Empfehlung ist: baue Dir damit ein Excelblatt. Das ist schnell gemacht.

Oder vielleicht doch lieber eine Wohnung kaufen? Oder Gold?

Solch ein Excelblatt kannst Du auch für andere Investitionen wie zum Beispiel für den Kauf einer Wohnung oder für die Bewertung eines Bausparvertrages, von der Spar- bis zur Darlehensphase, nutzen. Du erfasst in einer Spalte alle zunächst abfließenden und später eingehenden Zahlungsströme und berechnest dann den Zinsfluss mittels IKV-Funktion.

Diese Themen sind jedoch nicht meine Schwimmbahn. Anders als zum Beispiel in den USA sind in Deutschland die Daten zu Immobilienpreisen leider nicht transparent und öffentlich zugänglich. Für diesen Blog nutze ich öffentlich zugängliche Daten. Wenn Du also Ideen für Finanzmodellierungen einer Investition suchst, dann musst Du anderweitig fündig werden.

Und Gold?

Das wiederum ist sehr einfach: für die Variable „stock“ oben setzt Du „GC=F“ ein. Das ist das Symbol für den Goldpreis. Und schon hast Du Dein Gold-Renditedreieck.

Zur Berechnung des „Zinsfußes“

In R verwende ich das Paket jrvFinance und die irr()-Funktion („internal rate of return“). Ich möchte hier meine Vorgehensweise möglichst genau darstellen (ein großer Vorteil von R, Python & Co), sodass Du meinen Ansatz überprüfen kannst. Wenn ich einen Fehler mache, dann bitte ich um einen Hinweis!

Ich investiere jeden Monat den Wert 1 in ein Wertpapier, das zu diesem Zeitpunkt je Anteil beim Kurswert x steht. Das heißt: ich erwerbe 1/x Anteile. Wenn ich nun Monat für Monat den Wert 1 investiere, dann muss ich die Kehrwerte 1/x über alle Monate aufsummieren, um zu berechnen, wie viele Anteile ich im Laufe der Zeit erworben habe. Diese Anteile verkaufe ich am Ende der Zeit zu dem dann gültigen Kurswert. So erstelle ich folgende Funktion, die mir aus

  • dem „Einkaufskalender“ („schedule“: mit Spalten „Period“ und „Stock“)
  • dem Startdatum („date1“) der Käufe und
  • dem Verkaufsdatum („date2“)

den jeweiligen Zinsfuß berechnet:

Zinsfuss <- function(date1, date2) {

# Vektor aller Einkaufspreise:
buy <- schedule %>% 
       filter(Period >= date1, 
              Period < date2) %>% 
       pull(Stock)

# Anzahl der erworbenen Anteile:
shares <- sum(1/buy)

# Verkaufserlös:
sell <- shares*schedule$Stock[schedule$Period == date2]

# Da wir jeweils 1 investiert haben, 
# ist unsere Investitition rentabel 
# solange sell > length(buy) ist.

# Cashflow-Vektor:
my_cf <- rep(-1, length(buy)) %>% append(sell)

# Zinsfuss berechnen:
Zf <- jrvFinance::irr(my_cf)

# Das ist jedoch nur der monatliche Zinsfuss.
# Den müssen wir jetzt noch auf das Jahr umrechnen:
Zf.pa <- (1 + Zf)^12 - 1

return(Zf.pa) 

}

Diese Funktion greift auf die in der Variablen „schedule“ abgelegten monatlichen Aktienstände zurück, die wir wie folgt aus dem Yahoo-Finance-Download, also der Variable „Stock“, berechnen:

schedule <- Stock %>% 
     mutate(Period = floor_date(Date, "1 month")) %>% 
     group_by(Period) %>% 
     filter(Date == min(Date)) %>% 
     select(Period, Stock)

Mit dieser Funktion Zinsfuss() durchlaufe ich nun eine Schleife über die gesamte Tabelle t2 und erhalte folgendes Rendite-Dreieck:

Rendite-Dreieck des Dax bei monatlich gleichbleibenden Zukäufen.

„Von weitem betrachtet“ sieht dieses Dreieck dem vorherigen recht ähnlich. Bei näherem Augenschein sind durchaus Unterschiede erkennbar: vor allem treten zu Krisenzeiten deutliche vertikale Strukturen hervor: da Du zu Krisenzeiten günstig nachkaufst, überstehst Du die Krisen schneller!

Durch regelmäßigen Nachkauf kannst Du Krisen „aussitzen“. Bei Nachkauf bei Bärenstimmung und dann günstigeren Preisen hat sich Deine Anlage schneller wieder „berappelt“ als bei einer Einmal-Investition.

Wärst Du zum Beispiel zum 1. 1. 2000 eingestiegen, dann hättest Du im ersten Jahr 21% Verlust gemacht. Bei Ausstieg am 1. 1. 2003 wärst Du sogar bei -32% p.a. gelandet. Gerade jetzt wäre aber „Ruhe bewahren“ richtig gewesen, denn bis zum 1. 1. 2006 hättest Du mit Deinen monatlichen Investitionen „im Schnitt“ einen Zinsfluss von 7% p. a. erwirtschaftet.

Dein „wahres“ Investitionsszenario ist noch entspannter

Der kontinuierliche Kauf „entschärft“ also das Problem der Volatilität. Gerade wenn Du Deine Anlage als Altersvorsorge betrachtest, dann wirst Du vermutlich auch nicht alles auf einen Schlag abziehen. Vielmehr wirst mit Rentenbeginn auch kontinuierlich, zum Beispiel monatlich, entnehmen: in Bullenjahren wenige, hochpreisige Anteile und in Bärenjahren mehr niedrigpreisige Anteile, um so einen monatlich gleichbleibenden Bedarf zu decken. Dadurch entspannt sich die Situation noch einmal. Das heißt:

Je länger und je kontinuierlicher Du investierst und gleichmäßiger Du entnimmst, desto mehr bildet Deine Investition die langfristige Entwicklung ab.

Wenn Du also glaubst, dass es mit der deutschen, der amerikanischen, der Weltwirtschaft langfristig bergauf geht, dann solltest Du über einen Rentensparplan in ein Papier, das Deinen bevorzugten Index nachbildet, ernsthaft nachdenken. Das Renditedreieck hilft Dir bei der Entscheidung.

Die Vergangenheit lässt keine Rückschlüsse auf die Zukunft zu

Zu recht magst Du nun sagen: Schön und gut – aber kann ich mich auch in Zukunft darauf verlassen, dass meine Anlage nach spätestens 10 Jahren wieder gut dasteht?

Die Antwort kennst Du selbst.
Nein, verlassen können wir uns auf die Zukunft nicht.

Es stehen große Herausforderungen an: Vielleicht wandert die deutsche Industrie ja dorthin ab, wo die Energie billiger ist. Oder wir kriegen die Digitalisierung nicht hin. Oder in Deutschland oder Europa entstehen „japanische Verhältnisse“. Oder die Klimakrise stürzt die ganze Welt in den Abgrund. Oder die USA versinken im Chaos. Oder, oder, oder.

Vielleicht. Und deshalb müssen wir die Ärmel hochkrempeln. Aussitzen können wir – als Menschheit – diese Themen nicht. „Als Menschheit“ haben wir aber auch andere Dinge hingekriegt: nach zwei Weltkriegen eine neue Wirtschaftsordnung aufgebaut, extreme Armut halbiert, Corona irgendwie überstanden. Vielleicht wird jetzt trotzdem alles anders und schlimmer. Oder aber wir kriegen das Problem mit dem Fachkräftemangel in den Griff. Vielleicht startet Deutschland auch dank künstlicher Intelligenz so richtig durch. Aber all das ist eine andere Geschichte. Und die musst Du mit jemand anderem besprechen, denn als „Schuster“ bleibe ich hier bei meinem „OSAN-Leisten“.

Wie Du Dich zu diesen Themen positionierst hat natürlich auch Konsequenzen für Deine Wahl. Denn falls Du in den DAX investierst, dann wettest Du darauf, dass es mit der deutschen Wirtschaft gut weiter geht. Vielleicht traust, nur als Beispiel, den USA mehr zu? Dann könntest Du den Dow Jones wählen. Oder Du siehst über die nächsten Jahrzehnte Indien oder China vorn? Dann suche Dir entsprechende ETFs aus und schaue ihre Rendite-Dreiecke an. Oder Du wettest einfach darauf, dass es mit der gesamten Welt „schon irgendwie weitergeht“? Dann könntest Du den MSCI World auswählen (der allerdings Nordamerika übergewichtet – schaue deshalb bei jedem ETF oder Fonds rein, was drin ist in der Packung).

Eine nützliche Faustformel

Was Du im Hinterkopf behalten solltest:

Eine Geldanlage, die zum Zinssatz x% verzinst wird,
verdoppelt nach etwa 70/x Jahren ihren Wert.

Bei 2% also nach 35 Jahren. Bei 5% schon nach 14 Jahren und bei 7% nach 10 Jahren. Wenn Du rechtzeitig anfängst und so Zeit mitbringst, dann solltest Du Dir diese Effekte nicht entgehen lassen. Vor allem, wenn Du erst in 40 Jahren in Rente gehst.

Ein paar Tipps möchte ich Dir noch mit auf den Weg geben

So schwer ist es also nicht, mit doppelt soviel Geld in Rente zu gehen. Und so „steinig und schwer“ ist der Weg dahin auch nicht, selbst wenn Du ihn alleine gehst: Du musst regelmäßig Geld beiseite legen, in guten wie in schlechten Zeiten „einfach weitermachen“ und am besten schließlich genauso kontinuierlich Geld entnehmen.

Ich denke jedoch auch, dass dieses Thema wichtig genug ist und dass Du eigene Recherchen anstellen, mit Freunden, Eltern und mit Deiner Bank darüber sprechen solltest.

Meine „Schwimmbahn“ ist die Visualisierung von Daten. Die folgenden Gedanken möchte ich Dir dennoch nicht vorenthalten, da sie Dir helfen können, Dich auf diese Gespräche vorzubereiten. Du solltest sie aber unter dem Vorbehalt lesen, dass ich hier meinen Kompetenzbereich verlasse.

Bevor Du bei der Bank unterschreibst: Frage nach, welche Möglichkeiten deren Anlage Dir für Spar- und Entnahmephase bietet (z. B. die Möglichkeit, auch einmal auszusetzen, ganz auszusteigen oder eine größere Einzahlung zu tätigen) und wie hoch die Kosten dafür sind. Bei 5% Ausgabeaufschlag und 2% Verwaltungsgebühren pro Jahr muss ein Fonds schon richtig gut gemanagt sein, um „den Markt“, also den von Dir für einen ETF gewählten Index, zu schlagen. Bei all den zusätzlichen Features wie „Airbag“, „dynamische Anpassungen ohne zusätzliche Gesundheitsprüfung“ und „eingebaute Berufsunfähigkeitsversicherung“ lässt sich vielleicht gar nicht so genau sagen, wie hoch diese Gebühren tatsächlich sind. Dann ist für Dich der Geldfluss wichtig, den Du in Excel mit der IKV-Funktion in den Griff kriegst. Und stelle die Frage: ich schließe heute ab und verkaufe morgen wieder. Wieviel kriege ich zurück? – Denn DAS ist der Ausgabeaufschlag.

Eine weitere Idee Deiner Bank könnte sein, das Geld „zur Sicherheit“ mehreren Managern anzuvertrauen („lege niemals alle Eier in einen Korb“). Bei diesem Vorschlag solltest Du folgendes überlegen: Alle Manager zusammen bilden den Markt ab: manche performen besser, manche schlechter. Wie viele verschiedene Manager musst Du im Portfolio haben, um den Markt tatsächlich mehr oder weniger abzubilden? „Zur Sicherheit“ zehn? – Vielleicht kannst Du Dir dann die Verwaltungsgebühren für diese Manager auch sparen und gleich einen Index-ETF kaufen.

Aber Achtung: ETF ist nicht gleich ETF, auch wenn die Gebühren vernachlässigbar sind. Das siehst Du auch, wenn Du deren Renditedreiecke rechnest (sehr einfach: Du änderst die Variable „stock“ in dem Code oben).

Hier sind noch meine eigenen „Leitplanken“ für Investitionen – zum Teil habe ich dafür Lehrgeld bezahlt, das Du Dir vielleicht sparen kannst:

  • Ich kaufe ETFs nur zu transparenten und gut regulierten Märkten. Übersetzt für mich heißt das, dass ich mich auf demokratisch regierte Länder beschränke.
  • Ich bin vorsichtig bei „Nischen-ETFs“. Vieles klingt gut („Wasserstoff“, „ökologisch“, „sozial“, …). Und es ist sicher richtig, auf solche Trends zu setzen, wenn man an sie glaubt. Wenn mein „Traum-ETF“ aber eine Nische besetzt (wenige, kleine Unternehmen) und viele andere meinen Traum teilen, dann kann durch eben diese Anlagemöglichkeit die Nische „hochgejazzt“ werden – und es entsteht ein Blase. Ich schaue mir also an, welche und wie viele Unternehmen drin sind in dem ETF, wo sie beheimatet sind und wie groß sie sind.

Die Idee, die wir hier verfolgen, ist ohnehin: lasst uns nicht zu clever sein. Wir sind lieber konsistent (regelmäßig anlegen, liegen lassen, viel später regelmäßig entnehmen). Denn wenn Du auf den „Geheimtipp-ETF“ setzt, dann sagst Du ja insgeheim doch, dass Du schlauer bist als der Markt. Oder?

Ein Nachtrag noch: am 8. Juni hat die FAZ einen meiner Ansicht nach guten Artikel genau zu diesen Fragen veröffentlicht: „Sind ETFs wirklich besser?“. Vielleicht steigst Du damit einmal ein.

Wo ich Unterstützung gebrauchen kann

Es gelingt mir nicht, die exakten Werte des Rendite-Dreiecks für den MSCI World in dem oben zitierten Artikel der FAZ nachzubauen. Vielleicht wird mit einem anderen Stichdatum als dem 1. Januars gerechnet? Meine Zahlen erscheinen zudem allgemein etwas niedriger als die des Deutschen Aktieninstituts zu sein. Ist meine Zinsfußberechnung vielleicht doch falsch? Die Schlussfolgerungen bleiben die gleichen. Aber diese Unstimmigkeit würde ich gerne aufklären.

Welches Land ist „Klima-Weltmeister“?

Warum Du diesen Blog lesen solltest

Wenige Themen werden in der letzten Zeit so heiß diskutiert, wie das Klima. Das ist gut: als Gesellschaft müssen wir über die wichtigen Themen sprechen und brauchen eine Kultur der Debatten. Dabei lohnt es sich, auch einmal andere Länder unter die Lupe zu nehmen und zu schauen, was dort schon erreicht wurde.

In diesem Blog erfährst Du, wie Du selbst solche Vergleiche anstellen und danach gezielt nach Ländern suchen kannst, die Dich interessieren.

„Traue nur den Statistiken, die Du verstehst“

Ich möchte noch einmal auf meinen Beitrag vom Januar zurückkommen. Wir hatten damals gesehen:

  • Ein interessantes Maß für die Klimaeffizienz einer Volkswirtschaft ist das Bruttosozialprodukt, das je Kilogramm eingesetztes CO2 erwirtschaftet wird.
  • Es ist dabei sinnvoll, sowohl das absolute als auch das kaufkraftparitätische Bruttosozialprodukt zu betrachten.
  • Welches Land als „Sieger“ abschneidet hängt davon ab, wie viele der größten CO2-Emittenten in die Untersuchung einbezogen werden.
  • Wenn wir die 10 größten Emittenten betrachten, dann steht Deutschland vorn, unter den 20 größten schneidet Frankreich am besten ab.

Solche Ergebnisse erscheinen zwar interessant, laufen aber auf ein „es kommt halt darauf an“ hinaus und sind somit letztlich unbefriedigend. Vor allem möchte ich die Schlussfolgerung vermeiden, man solle keiner Statistik trauen, „die man nicht selbst gefälscht hat“. Denn worauf wollen wir uns bei wichtigen Themen sonst verlassen, wenn nicht auf wissenschaftliche Erkenntnisse und Statistiken?

Deshalb heute ein neuer Anlauf – mit einigen, so finde ich, interessanten Einsichten.

Um die Ergebnisse vorweg zu nehmen

  • Wenn Ihr mich fragt, dann ist die Schweiz Klimaweltmeister.
  • Dänemark hat über die letzten 30 Jahre seine Klimaeffizienz am meisten, nämlich um 440% gesteigert.
  • Es lohnt sich auch, in Frankreich, England und den nordischen Ländern (Schweden, Norwegen, Island, Irland) zu schauen, was sich dort über Klimaeffizienz lernen lässt
  • Ein Blick nach Singapur kann wichtige Einsichten geben, wenn es darum geht, Großstädte klimaeffizient zu gestalten und
  • der Stimme Brasiliens sollte im Klimakonzert das Gehör gegeben werden, das das Land sich als einer der „Gruppensieger“ verdient hat.

Wenn Du das nachprüfen möchtest, dann findest Du am Ende die wesentlichen Code-Zeilen dafür.

Wir verwenden R für unsere OSAN-Analysen

Wir betreiben „Open Source Analytics“ (OSAN) und verwenden dafür frei verfügbare Datenquellen und die Skript-, Berichts- und Webapplikationssprache R, die speziell für die Handhabung von Daten, Texten und Bildern entwickelt wurde. Du kannst Sie kostenfrei installieren. Sprachen wie R und auch Python bieten Dir viele Vorteile, zum Beispiel diese:

  1. Du hast auf einen Schlag Zugang zu den neuesten und besten Analysewerkzeugen inklusive Dokumentation. Du kannst Dich auch bequem von „generativer“ künstlicher Intelligenz wie ChatGPT bei der Erstellung Deines Skripts coachen lassen.
  2. Du kannst Deine Analysen ständig aktuell halten: Einmal „Run“ gedrückt und schon lädt Dein Skript wieder die neuesten Daten herunter und wertet sie für Dich aus.
  3. Als Team ist Eure Lernkurve steiler: Anders als bei „Klicksoftware“ kannst Du Dein Vorgehen inklusive aller „Tricks und Kniffe“ in Deinem Skript festhalten. So könnt Ihr beste Praktiken leicht untereinander teilen.
  4. Eventuelle Fehler in Deiner Analyse können von Dir oder anderen aufgespürt und korrigiert werden: Denn anhand des Skriptes können alle Dein Vorgehen genau nachvollziehen.

Heute möchte ich eine weitere Möglichkeit von R nutzen und aus mehreren Graphiken einen „Film“ erstellen. So lassen sich Daten Einsichten entlocken, die sonst vielleicht verborgen geblieben wären.

Unsere heutige Fragestellung und unser Vorgehen

Wenn nun davon abhängt, wie viele Länder in unsere Untersuchung einbezogen werden – vom größten bis zum kleinsten Emittenten, dann wollen wir jetzt wissen: Wer ist „Sieger“, wenn wir die größten 3, 5, 10, 30 oder 100 Emittenten einbeziehen? Wir gehen deshalb wie folgt vor:

  1. Wir besorgen uns den neuesten derzeit von der Weltbank zur Verfügung gestellten Datensatz. Das sind die Daten für das Jahr 2019 und zwar für 181 Länder.
  2. Wir sortieren diesen Datensatz absteigend nach den CO2-Emissionen je Land.
  3. Mit einer Variablen i durchlaufen wir dann eine Schleife über alle Länder.
  4. In jeder Schleife wählen wir die größten i CO2-Emittenten aus und sortieren diese absteigend nach ihrem Bruttosozialprodukt je kg CO2-Emission.

So können wir für die jeweilige Auswahl von Ländern

  • den jeweiligen „Klimaeffizienz-Gruppensieger“ innerhalb der i größten Emittenten ermitteln und
  • das dazugehörige „Siegertreppchen“ (erster Platz, zweiter Platz, …) graphisch darstellen.

Welches Land hält sich am längsten auf dem Siegerpodest?

Beim Durchlaufen dieser Schleifen fällt auf, dass manche Länder bei Hinzunahme von weiteren Ländern schnell vom „Siegerpodest gestoßen“ werden, andere sich länger halten. Diese jeweiligen „Gruppensieger“ unter den i = 1, 2, 3, … 181 größten Emittenten von CO2 können wir graphisch wie folgt darstellen. Die Schweiz ist nicht nur Siegerin, sie hält sich auch am längsten:

„Gruppensieger“ in Sachen Klimaeffizienz. Bruttosozialprodukt in Dollar.

Lesen wir diese Graphik einmal genauer: Wenn wir nur den größten Emittenten China einbeziehen, dann ist, trivialerweise, China mit einem Bruttosozialprodukt von $1.33 je kg CO2 der „einsame Sieger“. Unter den ersten zwei bis vier größten Emittenten schneiden zunächst die USA am besten ab, dann übernimmt kurzfristig Japan. Deutschland steht vorn, sobald die größten sechs Emittenten betrachtet werden und wird erst von dem Emittenten Nr. 17, dem Vereinigten Königreich abgelöst, das kurz darauf an Frankreich abgibt bis schließlich der Emittent Nr. 60, die Schweiz, die Nase vorn hat und behält: die Schweiz erwirtschaftet sagenhafte $19.30 je eingesetztes Kilogramm CO2.

Nun ist diese Betrachtung ein wenig „ungerecht“: die Kaufkraft eines Dollars ist von Land zu Land verschieden. Kaufkraftparitätisch betrachtet stellt sich die Lage tatsächlich mit interessanten Nuancen dar.

So übernimmt zwischenzeitlich Brasilien mit $4.76 je kg CO2 die Führung: angesichts der Kaufkraft eines Dollars in Brasilien setzt das Land seine CO2-Emissionen also im Sinne der eigenen Bevölkerung effizient für die Erwirtschaftung des Bruttosozialprodukts ein. Wenn Präsident Lula eine Führungsrolle im Kampf gegen den Klimawandel beansprucht, dann legt das Land dafür also durchaus eigene Leistungen in die Waagschale – was nicht zuletzt auch Deutschland neulich durch eine Einzahlung in Höhe von 35 Millionen Euro in den Amazonas-Fond honoriert hat.

Kurzfristig erscheint auch Singapur als „Gruppensieger“ zwischen Frankreich und der Schweiz: ein Pionier, wenn es darum geht, Großstädte grüner und klimaeffizienter zu gestalten. In dieser Betrachtung wird auch die Schweiz von Uganda und Uganda schließlich von der Demokratischen Republik Kongo abgelöst. Auch hier bleibt die Schweiz am längsten in der Pole-Position:

„Gruppensieger“ in Sachen Klimaeffizienz. Kaufkraftparitätisches Bruttosozialprodukt. Die Schweiz bleibt am längsten in der Pole-Position.

Wir halten fest:

Unter den derzeit 36 OECD-Ländern (Organisation for Economic Co-Operation and Development, laut Economist ein „Club zumeist reicher Länder„) ist die Schweiz der eindeutige Sieger. Sie hat auch am längsten „die Nase vorn“ und erwirtschaftet ca. 19 Dollar Bruttosozialprodukt je eingesetztes Kilogramm CO2.

Deutschland mag vielleicht nur wenige Inspirationsquellen in Uganda oder der demokratischen Republik Kongo finden, die in der kaufkraftparitätischen Betrachtung deutlich besser abschneiden. Ein Blick über die Grenze nach England, Frankreich oder in die Schweiz erscheint aber durchaus lohnenswert: diese Volkswirtschaften sind so unterschiedlich nicht. So kommen zum Beispiel der Schweizer Verwaltung zufolge 61,5% des eidgenössischen Stroms aus Wasserkraft, 28,9% aus Kernkraft und weitere 7,7% aus neuen erneuerbaren Energien. Die Liste der deutschen Wasserkraftwerke ist ebenfalls beachtlich. Wie könnten diese im Verbund mit Wind und Sonne am besten genutzt werden?

Oder – wir setzen uns jetzt den schwarzen Denkhut auf – ist die Schweizer Wasserkraft vielleicht durch sinkende Schneemengen in den Alpen bedroht? Und wo kommen die Brennstäbe  für die Atomkraftwerke in Frankreich und der Schweiz her? Wo landen sie, wenn sie ausgebrannt sind? Wir könnten uns hier auf eine Diskussion um Atom, Wasser, Wind und Sonne nur insofern einlassen, als ein neugieriger Blick auf unsere Nachbarn bestimmt nicht schadet.

Und wie sieht das jeweilige Siegertreppchen aus?

Die vorherigen Graphiken zeigen, welches Land wie lange „die Nase vorn hat“. Aber welche Länder folgen darauf und wie dicht sind sie dem jeweiligen Sieger auf den Fersen? Vielleicht stoßen wir ja auf weitere Länder, von denen sich etwas lernen ließe.

Beim Durchlaufen der oben besprochenen Schleife habe ich deshalb das „Siegertreppchen“ auch graphisch dargestellt (z.B. die 10, 20 oder 30 größten Emittenten nach absteigender Klimaeffizienz angeordnet) und daraus einen „Film“ erstellt. Dank R ist das mit wenigen Zeilen Code getan:

„Siegertreppchen“ in Sachen Klimaeffizienz der Volkswirtschaft – je nachdem wie viele der größten CO2-Emittenten betrachtet werden. Bruttosozialprodukt in Dollar.

Wir sparen uns hier den „Film“ in kaufkraftparitätischer Betrachtung und stellen vielmehr fest, dass die „nordischen Länder“ Schweden, Norwegen, Island, Irland und Dänemark in Sachen Klimaeffizienz ebenfalls weit vorne liegen.

Wie entwickelt sich die Klimaeffizienz der Länder über die Zeit?

Hier möchte ich die deutsche Perspektive einnehmen und deshalb die eher vergleichbaren Volkswirtschaften der „high income countries“ (blau in der Graphik) hervorheben. Die Entwicklung aller anderen Länder sollen jedoch (in grau) sichtbar bleiben. Unter den anderen Ländern wähle ich zudem die vier größten Emittenten aus, sodass wir auch diese verfolgen können. Da die Länder sehr verschieden groß sind, stelle ich die Emissionen auf der vertikalen Achse in logarithmischer Auftragung dar:

Emissionen der high-income Länder im Laufe der Zeit – aufgetragen gegen die Klimaeffizienz. Das Bruttosozialprodukt wird in „current dollars“ (CD) und nicht in kaufkraftparitätischen gemessen.

Ich finde erstaunlich, wie gut in dieser Darstellung das „Durchstarten“ in Sachen Klimaeffizienz der Länder Schweiz, Schweden, Norwegen und auch Dänemark sichtbar wird: bei nahezu konstanten Emissionen vergrößern sie signifikant ihre Volkswirtschaften und die Klimaeffizienz (GDP.CD.per.CO2E.kg) driftet folglich horizontal weg. Wir schauen uns deshalb den zeitlichen Verlauf gesondert an:

Zeitliche Entwicklung der Klimaeffizienz ausgewählter Volkswirtschaften.

Die Schweiz hat also die Klimaeffizienz ihrer Wirtschaft in dem Zeitraum von 1990 bis 2919 mehr als verdreifacht, von 6,13 Dollar Bruttosozialprodukt je eingesetztes Kilogramm CO2 auf 19,30 Dollar. Auch Deutschland hat solch eine Verdreifachung erreicht, und zwar von 1,80 Dollar/kg auf 5,91 Dollar/kg. Wir sind also im Jahr 2019 fast dort, wo die Schweiz im Jahr 1990 stand.

Nun magst Du diese absolute Betrachtung für „ungerecht“ halten: wenn Du am Anfang eines Fitnessprogramms zwei Klimmzüge geschafft hast und nachher sechs, dann ist bist Du vielleicht noch mehr stolz darauf als jemand, der sich von 10 auf 14 gesteigert hat. Wir schauen uns das deshalb genauer an und beziehen dafür die Werte für jedes Jahr und Land auf die jeweiligen Werte des Jahres 1990:

Klimaeffizienz im Vergleich zum Bezugsjahr 1990. Dänemark erreicht eine Steigerung um 440%.

Der Überraschungssieger in dieser Auftragung heißt

Dänemark.

Dänemark holt im Jahr 2019 im Vergleich zum Bezugsjahr 1990 fast viereinhalb mal soviel Bruttosozialprodukt aus jedem Kilogramm eingesetzten CO2 heraus.

Nun magst Du zu recht einwenden, dass wir unsere Betrachtungen auf die Werte eines einzigen Jahres beziehen: was wäre, wenn wir stattdessen die Werte des Jahres 1989 (die nicht vorliegen) oder die des Jahres 1991 zugrunde gelegt hätten? Anstatt das auszuprobieren, ziehen wir alle zur Verfügung stehenden Jahre heran und führen in einer Schleife, Land für Land, eine Regressionsanalyse durch und bestimmen so die durchschnittliche jährliche Änderung.

Lass mich hier – als Übergang zum folgenden DIY-Abschnitt – dafür den Code teilen und erläutern. Zunächst erstellen wir eine Tabelle t für die Jahre, die unsere Werte enthalten (1990 bis 2019). Wir nehmen Zeilen mit NA-Werten und solche Werte heraus, die durch Teilen durch Null erzeugt wurden und wählen die uns interessierenden Spalten aus. Wir ziehen uns daraus eine Liste der Länder und zählen diese:

t <- indicatortable %>% 
        filter(year >= 1990, year <= 2019) %>% 
        drop_na() %>% 
        filter(!is.infinite(GDP.CD.per.CO2E.kg)) %>% 
        select(year, country, 
               EN.ATM.CO2E.KT, 
               NY.GDP.MKTP.CD, 
               GDP.CD.per.CO2E.kg)

laender <- unique(t$country)
anz <- length(laender)

So können wir die gewünschte Ergebnistabelle erstellen, die wir dann in der folgenden Schleife mit Werten befüllen. „Puristen“ mag das hemdsärmelig erscheinen. Wenn Du eine elegantere Methode kennst, dann lass mich das gerne wissen!

res <- data.frame(
   Land = rep(NA, anz),
   Steigerung = rep(NA, anz), # jährl. Steigerung der Klimaeffizienz
   R2 = rep(NA, anz),         # R2 dieser Steigerung
   PWert = rep(NA, anz),      # Signifikanz der Steigung
   Emissionen = rep(NA, anz), # Emissionen in kt im letzten Jahr
   GDP = rep(NA, anz),        # BSP in current dollar im letzten Jahr
   Effizienz = rep(NA, anz)   # Klimaeffizienz im letzten Jahr
)

Nun können wir die Tabelle befüllen. Dafür filtern wir aus t zunächst nur das jeweilige Land, führen eine Regressionsanalyse durch (lm, „linear model“), legen die Ergebnisse in der Variablen s ab und ziehen uns dann den Koeffizienten der Steigung, den Regressionskoeffizienten R2 und den P-Wert. Ein bisschen Debugging für fehlende Werte kommt noch hinzu:

for (i in 1:length(laender)) {

  land <- laender[i]

  dat <- t %>% filter(country == land)
  model <- lm(data = dat, 
                     GDP.CD.per.CO2E.kg ~ year)
  s <- summary(model)

  res[i, 1] <- land
  res[i, 2] <- s$coefficients[2,1]
  res[i, 3] <- s$r.squared
  res[i, 4] <- round(s$coefficients[2,4], 3) # P-Wert linear

  # Wir müssen noch einen Fehler abfangen, 
  # denn für manche Länder gibt es keine Daten.
  if(2019 %in% dat$year) {
    res[i, 5] <- dat$EN.ATM.CO2E.KT[dat$year == 2019]
    res[i, 6] <- dat$NY.GDP.MKTP.CD[dat$year == 2019]
    res[i, 7] <- dat$GDP.CD.per.CO2E.kg[dat$year == 2019]
  }
}

Mit dieser Ergebnis-Liste res kannst Du viel anfangen. So finden wir zum Beispiel über

nochange <- res %>% 
   filter(PWert > 0.05)

alle Länder, in denen sich die Klimaeffizienz in den fast 30 Jahren nicht signifikant geändert hat und mit

degradation <- res %>% 
   filter(Land %notin% nochange$Land) %>% 
   filter(Steigerung < 0)

einige Länder, in denen sich die Lage sogar verschlechtert hat. Anschauen möchten wir uns die Länder, in denen sich die Lage verbessert hat. Dafür sortieren wir absteigend um das Land in dieser Reihenfolge für die folgende Graphik als Faktor zu definieren:

improvement <- res %>% 
   filter(Land %notin% nochange$Land) %>% 
   filter(Land %notin% degradation$Land) %>% 
   arrange(desc(Steigerung))

improvementdata <- t %>% 
  filter(country %in% improvement$Land)

improvementdata$country <- factor(improvementdata$country, 
                                  levels = improvement$Land)

ggplot(data = improvementdata %>%
         filter(country %in% improvement$Land[1:12]),
       aes(x = year,
           y = GDP.CD.per.CO2E.kg)) +
  geom_line() + 
  geom_smooth(method = "lm", 
              formula = y ~ x, 
              se = T) +
  facet_wrap(~ country, ncol = 3)

So erhalten wir folgende Graphik:

Länder mit der größten jährlichen Steigerung der Klimaeffizienz ihrer Volkswirtschaft

Wir stoßen auf alte Bekannte wie die Schweiz, die nordischen Länder und Singapur. Aber auch Ruanda hat seine Klimaeffizienz Jahr für Jahr um 25 Dollarcent je Kilogramm CO2 verbessert. Malta hat gerade in den letzten Jahren stark zugelegt: was ist da geschehen? Und seit Daten für diese Länder vorliegen sind auch Djibouti – sogar noch vor der Schweiz – und Somalia mit dabei. Uganda ist in dieser Betrachtung, in der es nicht um „Leistung“ sondern um Verbesserung geht, weit abgeschlagen.

Du magst Dich fragen: wo sind Länder wie die Niederlande, Belgien, Luxemburg oder auch Finnland? Die sind alle da. Sie haben sich nur nicht in unseren Algorithmen „verheddert“. In der letzten Untersuchung der Verbesserung finden wir für Luxemburg eine jährliche Steigerung von $0.24/kg (sehr konsistent bei einem R^2 = 94%), Finnland legt Jahr für Jahr um $0.17/kg (bei R^2 = 86%) zu, Belgien liefert $0.16/kg ab (R^2 = 88%) und die Niederlande $0.15/kg (R^2 = 87%).

Jede Auswahl ist ungerecht – egal welcher Algorithmus sie trifft. Deshalb also mein Tipp:

Do it yourself!

Ich teile im Folgenden die wichtigsten Codezeilen, sodass Du diese Überlegungen nachvollziehen, prüfen oder erweitern kannst.

Ich habe die folgenden Bibliotheken verwendet:

library(WDI)                   # Zugang zu den Weltbankdaten
library(ggrepel)               # Daten ohne Überlapp beschriften
library(tidyverse)             # Einfache Handhabung von Daten
library(ggthemes)              # Schöne Graphiken

'%notin%' <- Negate('%in%')    # Vereinfacht einige Code-Zeilen

So beschaffst Du Dir die Daten der Weltbank und bereitest sie auf:

# Wir wählen die uns interessierenden Indizes heraus.
# https://data.worldbank.org/, "browse by indicator").

indicators <- data.frame(
    ID = 
       c("EN.ATM.CO2E.PC", 
         "EN.ATM.CO2E.KT", 
         "NY.GDP.MKTP.CD",
         "NY.GDP.PCAP.PP.CD", 
         "NY.GDP.MKTP.PP.CD", 
         "SP.POP.TOTL"),
    details = 
       c("CO2 emissions (metric tons per capita)", 
         "CO2 emissions (kt)", 
         "GDP (current US$)",
         "GDP per capita, PPP (current international $)", 
         "GDP, PPP (current international $)", 
         "Population, total")
)

# Indizes laden:
indicatortable <- WDI(indicator = indicators$ID,
                      extra = TRUE)

# Klimaeffizienz berechnen, in 
# - Kaufkraftparität (PP)
# - und in "Current Dollars" (CD):
indicatortable <- indicatortable %>% 
  mutate(GDP.PP.per.CO2E.kg = NY.GDP.MKTP.PP.CD/EN.ATM.CO2E.KT/1e6,  
         GDP.CD.per.CO2E.kg = NY.GDP.MKTP.CD/EN.ATM.CO2E.KT/1e6) 

# Letztes verfügbares Jahr:
y2019 <- indicatortable %>% 
             filter(year == 2019)

So erstellst Du das „Siegertreppchen“:

# Anzahl der betrachteten größten CO2-Emittenten:
n <- 70

# Aus diesen: Anzahl der CO2-effizientesten Länder:
m <- 30

# Daten erstellen:
plotdat <- y2019 %>% 
    arrange(desc(EN.ATM.CO2E.KT)) %>% 
    slice(1:n) %>% 
    arrange(desc(GDP.CD.per.CO2E.kg))

# Reihenfolge in der Graphik über Faktor festlegen:
plotdat$country <- 
  factor(plotdat$country, 
         levels = rev(plotdat$country))

# Wesentliche Element des Plots.
# "Verschönerungen" habe ich der Einfachheit weggelassen:
ggplot(data = plotdat[1:m, ], 
       aes(x = GDP.CD.per.CO2E.kg, 
           y = country)) +
geom_bar(stat = "identity") +
geom_text(aes(label = paste("$", 
                            round(GDP.CD.per.CO2E.kg,2), 
                            sep = "")), 
          position = position_dodge(width = 1),
                                    hjust = 0, 
                                    vjust = 0.5)

So erstellst Du die Graphik für die „high income“ Länder und speicherst in einer Schleife die Graphiken ab:

# Liste aller high-income Länder in 2019:
hic2019 <- y2019 %>% 
  filter(income == "High income") %>% 
  select(country) %>% pull()

# Große Emittenten, die wir auch namentlich benennen wollen:
special <- y2019 %>% 
  filter(country %notin% hic2019) %>% 
  arrange(desc(EN.ATM.CO2E.KT)) %>% 
  slice(1:4) %>% 
  pull(country)

# Graphik fest skalieren:
xmax_graph <- max(indicatortable$NY.GDP.MKTP.CD, na.rm = T)
ymax_graph <- max(indicatortable$EN.ATM.CO2E.KT, na.rm = T)


# Schleife:

for (my_year in 1990 : 2019) {
  
  
  t <- indicatortable %>% 
    filter(year == my_year)
  
  # Zwei Gruppen:
  hic <- t %>% 
    filter(country %in% hic2019)
  
  rest <- t %>% 
    filter(country %notin% hic2019)
  
  # Grosse Emittenten:
  grE <- t %>% 
    filter(country %in% special)
  
  # Ein recht komplexer Plot mit vielen "Layers":
  plot <- ggplot() +
    geom_point(data = rest,              # Rest soll unten liegen
               aes(x = NY.GDP.MKTP.CD,
                   y = EN.ATM.CO2E.KT,
                   size = SP.POP.TOTL),
               fill = "grey", 
               shape = 21) +
    geom_point(data = hic,               # Darüber hi-Länder
               aes(x = NY.GDP.MKTP.CD,
                   y = EN.ATM.CO2E.KT,
                   size = SP.POP.TOTL),
               fill = "blue",
               shape = 21) +
    geom_text_repel(data = hic,          # Beschriftung hic
                    aes(x = NY.GDP.MKTP.CD,
                        y = EN.ATM.CO2E.KT,
                        label = country)) +
    geom_text(aes(x = xmax_graph,        # Jahreszahl der Graphik
                  y = 0, 
                  label = my_year), 
              hjust = 1, vjust = 0, size = 20) +
    geom_text(data = grE,                # Beschriftung rest-Länder
              aes(x = NY.GDP.MKTP.CD, 
                  y = EN.ATM.CO2E.KT, 
                  label = country),
              color = "black") +
    xlim(c(0,xmax_graph)) + 
    ylim(c(0,ymax_graph)) +
    scale_y_continuous(trans='log10') + 
    scale_x_continuous(trans='log10')

  
  name <- paste("graph", my_year, ".png", sep = "")
  ggsave(name,
         plot, 
         width = width, height = height)
  
  print(my_year)   # Damit uns nicht langweilig wird
}

So erstellst Du den „Film“ für diese Graphiken. Den „Treppchenfilm“ erstellst Du analog:

library(gifski)
imgs <- list.files(pattern="*.png")
imgwidth <- 1000
imgheight <- round(imgwidth/ratio, 0)
gifski(imgs, 
       gif_file = "name_der_animation.gif", 
       width = imgwidth, 
       height = imgheight, 
       delay = 0.5) # delay in Sekunden

Hier erstellen wir die Graphik für die Klimaeffizienz der ausgewählten Länder:

# Liste L, gleich in richtiger Reihenfolge für Faktor:
L <- c("Switzerland", "Sweden", "Denmark", 
       "Norway", "France", "Germany") 

# Datentabelle erzeugen:
t <- indicatortable %>% 
     filter(country %in% L,
            year >= 1990) %>% 
     select(year, country, 
            EN.ATM.CO2E.KT, 
            NY.GDP.MKTP.CD, GDP.CD.per.CO2E.kg) %>% 
mutate(country = factor(country, levels = L))

# Graphik, ohne "Verschönerungen:
ggplot(data = t, 
       aes(x = year,
           y = GDP.CD.per.CO2E.kg,
           colour = country))

# So berechnen wir die Daten für die "relativ-Graphik":
trel <- t %>%
  select(year, country, GDP.CD.per.CO2E.kg) %>% 
  arrange(country, year) %>% 
  group_by(country) %>%
  mutate(Relativ = GDP.CD.per.CO2E.kg / GDP.CD.per.CO2E.kg[1])

Wir tummeln uns am Aktienmarkt

Warum Du diesen Beitrag lesen solltest

Vielleicht interessieren Dich Aktien. Vielleicht findest Du aber einfach auch nur spannend, welche Einsichten möglich sind, wenn Märkte transparent und Daten dazu verfügbar sind? Dann bietet Dir dieser Beitrag einen ersten Einblick. Wie sonst auch ist der Ansatz, die Analysen selbst durchzuführen.

Unsere heutige Fragestellung

Wir haben uns bisher öffentlich verfügbare Daten im Licht „einer großen Sache“ angesehen: Klimawandel oder Demokratie. Heute wollen wir die Füße auf dem Boden behalten und über Aktien sprechen.

Hältst Du Aktien und möchtest wissen, wie sie „performen“? Wenn Du „Adidas Aktie“ in Deine Suchmaschine eingibst, dann siehst Du sofort Stand  und Entwicklung. Das ist sehr praktisch. Aber vielleicht möchtest Du sehen, wie sich Deine Aktie im Vergleich zum DAX oder zu anderen Werten entwickelt hat. So fragt zum Beispiel der Economist vom 25. März 2023, ob Adidas jemals zu Nike wird aufschließen können und nimmt in dem Artikel „No Yeezy answers“ dabei auch die Aktie von Puma mit in den Blick.

Wenn Du „richtig“ mit Aktien handelst, dann kennst Du für solche Vergleiche vermutlich einige einschlägige Seiten, die auch weitergehende Analysen erlauben. Aber warum solltest Du Dich damit auseinandersetzen und all die Tricks und Kniffe lernen, wenn Du Dir mit wenigen Zeilen Code Deine eigenen Analysewerkzeuge bauen kannst?

Der Vorteil von DIY („do it yourself“):

Du bist von niemandem abhängig.

Du weißt genau, was Du tust.

Du bleibst flexibel.

Wie wir vorgehen wollen

Wir verwenden wieder die Skript-, Berichts- und Webapplikationssprache R, die speziell für die Handhabung von Daten, Texten und zunehmend auch Bildern entwickelt wurde. Du kannst Sie kostenfrei installieren und hast so auf einen Schlag Zugang zu den neuesten und besten Analysewerkzeugen.

Der Vorteil unserer Herangehensweise hier liegt vor allem auch darin, dass Du Deine Analysen ständig aktuell halten kannst: einmal „Run“ gedrückt und schon lädt Dein Skript wieder die neuesten Daten von Adidas, Puma, Nike und welchem Unternehmen oder Aktienindex auch immer herunter und wertet sie für Dich aus. Wenn Du möchtest, dann kannst Du Dein Skript auch in eine Webapplikation einbauen und schon sind Deine Werkzeuge und Analysen allgemein zugänglich.

Diese Möglichkeiten hast Du auch mit Python. Ich verwende R.

Ein Beispiel von dem, was möglich ist

Bevor wir loslegen, möchte ich Dir ein Beispiel dafür zeigen, was sich mit frei verfügbaren Aktiendaten machen lässt.  Diese App erlaubt Dir, den Aktienstand und die Entwicklung verschiedener Unternehmen zu vergleichen. Dabei habe ich eine gewisse Auswahl getroffen, die hier jedoch keine Rolle spielt. Schau es Dir einfach an: so etwas ist möglich.

Warum wir heute auf ausgefeilte Werkzeuge verzichten

Mit Aktiendaten lassen sich Einsichten gewinnen und mit Einsichten fällst Du bessere Entscheidungen. Also sind Aktiendaten etwas wert. Interessanterweise stellt Yahoo Finance trotzdem sämtliche Aktiennotierungen umsonst zur Verfügung. Mit dem Paket „quantmod“ kannst Du Dir die Daten einfach beschaffen und zahlreiche ausgebuffte Analysen durchführen (siehe dazu die Doku). Wir wollen darauf verzichten und nutzen quantmod nur, um an die Daten heranzukommen.

Falls Du ein Trader bist, der sich mit mit diesem Paket ausgetüftelte Analysen zurechtlegt, dann mag Dir mein heutiges Vorgehen wie eine Verschwendung vorkommen: all diese tollen Werkzeuge einfach links liegen lassen! Ich ziehe in diesem Blog jedoch, egal mit welchen Daten, „einfach immer den gleichen Stiefel durch“. Es geht mir nicht um das Traden sondern um die Analyse von frei verfügbaren Daten. Beim nächsten Mal werden wir uns wieder andere Daten anschauen und wollen möglichst analog vorgehen können.

Falls Du ein Trader bist oder werden möchtest und Du Dir nach diesem Beitrag R herunterlädst und Dich in quantmod einfuchst, dann lass es mich wissen, denn dann, aber nicht nur dann, hat sich dieser Beitrag gelohnt.

Woher Aktiendaten nehmen wenn nicht stehlen?

Ehrlich gesagt weiß ich gar nicht, ob Du Dir Aktiendaten auch anderweitig bequem herunterladen und dann mit Excel analysieren kannst. Mit R ist es jedenfalls sehr einfach:

# Verwendete Pakete
library(tidyverse)
library(quantmod)

# Diese Kurse wollen wir uns beschaffen:
aktie <- "ADS.DE"        # Adidas an der Frankfurter Börse
index <- "^GDAXI"       # DAX

# Wir wollen ständig 20 Jahre zurückblicken können:
end <- Sys.Date()-1     # gestern
start <- end - 365*20   # vor 20 Jahren


Stock <- getSymbols(aktie, 
                    from = start, 
                    to = end, 
                    auto.assign = FALSE)

Das war’s eigentlich schon. Wenn Du Dir das so erzeugte xts-Objekt anschaust, dann siehst Du, dass Tag für Tag Werte für Open, High, Low, Close, Volume und „Adjusted“ erfasst werden. Das ist für Aficionados. Wir verzichten hier darauf. In der praktischen „Pipe“-Logik tun wir folgendes (ich beschreibe den folgenden Code, und lese dabei die Pipe „%>%“ als „dann“):

  • Nimm die Daten in der Variablen „Stock“
  • Dann mache daraus einen data.frame
  • Dann erstelle aus den Zeilennamen eine Spalte
  • Dann lass alle na-Einträge fallen
  • Dann wähle nur Spalte 1 und 5.

Wir vergeben zudem handliche Spaltennamen und verwandeln die Datumsspalte vom Typ „character“ in den Typ „date“, sodass wir damit rechnen können. Diese beiden Zeilen habe ich nicht in die „Pipe“ mit eingefügt. Ich halte meinen Code so für lesbarer.

Jetzt können wir uns die Entwicklung des Aktienkurses anschauen. Falls Du ggplot kennst, dann möchte ich hinzufügen: es gibt Gründe, die Du später erkennen wirst, warum ich die Definition der Daten und der Ästhetik (aes) in geom_point() hereinnehme und nicht bei ggplot() belasse:

Werte <- Werte %>% 
         as.data.frame() %>% 
         rownames_to_column() %>% 
         drop_na() %>% 
         select(1, 5)



colnames(Stock) <- c("Datum", "Adidas")
Stock$Datum <- as.Date(Stock$Datum)

ggplot() +
  geom_point(data = Stock,
             aes(x = Datum, y = Adidas))

Aktienkurs der letzten 20 Jahre von Adidas. Stand: 31. März 2023

Du magst Dich vielleicht fragen, was Anfang 2015 passiert ist, dass die Aktie in der Folge „so abgeht“. Karsten Rorsted wurde jedenfalls erst am 1. Oktober 2016 zum CEO berufen – und am 22. August wurde bekannt gegeben, dass sich das Unternehmen wieder einvernehmlich von ihm trennt. Diese beiden Ereignisse habe ich über die roten Linien dargestellt.

Solche Überlegungen sind natürlich der Grund, warum man sich überhaupt Aktienkurse anschaut. Heute geht es mir aber nicht um das Thema, also den Einfluss, den Führungskräfte auf die Unternehmensbewertung haben, sondern darum, wie Du diese Fragen sehr einfach selbst stellen und quantitativ bewerten kannst.

Wie entwickelt sich Adidas im Vergleich zum DAX?

Die Daten für den DAX kannst Du Dir analog zu den Code-Zeilen oben beschaffen. Und nun kommt das Problem: Wir möchten beide Kursverläufe gemeinsam darstellen, um zum Beispiel die Frage zu beantworten: schlägt Adidas den Dax? Dafür wird üblicherweise die Entwicklung relativ zu einem gewissen „Einstiegsdatum“ betrachten: Wenn Du am 1. Oktober 2016 Adidas und den DAX für je 100 Euro gekauft hättest, wo würden diese Papiere heute stehen? So wählt der oben zitierte Artikel des Economist dieses Datum, eben das Einstiegsdatum von Karsten Rorsted bei Adidas, für seinen Vergleich zwischen Adidas, Puma und Nike.

Schauen wir uns das einmal an. Ich zeige die Rechnung für Adidas und lasse alle Formatierungsanweisungen wie Farbzuweisungen der Einfachheit halber weg. Da ich die Daten erst in „geom_line“ definiere kann ich die beiden Datensätze in den Plot „hineinaddieren“:

RefDatum <- "2016-10-04"
RefAdidas <- Stock %>% 
             filter(Datum == RefDatum) %>% 
             pull(Adidas)

Stock$Performance <- Stock$Adidas/RefAdidas
ggplot() +
   geom_line(data = Index,
             aes(x = Datum, y = Performance)) +
   geom_line(data = Stock,
             aes(x = Datum, y = Performance))

Vergleich von Adidas (blau) und Dax (grau). Referenzdatum: 4. Oktober 2016.

Adidas hat den Dax also zwischenzeitlich um Längen geschlagen und seinen Wert im Vergleich zum 4. Oktober 2016 im Januar 2020 und im Juli und August 2021 sogar mehr als verdoppelt, ist dann aber deutlich zurückgefallen und steht Ende März 2023 wieder in etwa beim Ausgangspunkt vom Oktober 2016.

Keine Taschenspielertricks!

Wenn Du in der Strategieabteilung eines aktiennotierten Unternehmens sitzt, dann kennst Du vermutlich folgendes Dilemma: „Lasst uns vielleicht nicht den 4. Oktober sondern lieber den 10. November 2016 als Referenzdatum nehmen“. Der 1. Oktober war ein Samstag und der 4. Oktober war der erste Handelstag nach Rorsteds Einstieg. Der Kurs stand an dem Tag bei 157,40 Euro. Am 10. November stand er dagegen bei 131,70 Euro, also ganze 16% tiefer. Die Entwicklung relativ zum 10. November fällt also entsprechend positiver aus…

Ich verwende Aktienanalysen nicht, um meine eigene Rendite bei bestimmten Papieren zu berechnen und wieviel ich gemacht hätte, wenn ich am Tag X stattdessen einen anderen Wert gekauft hätte. Mir geht es eher um „Ursache-Wirkung“. Und dabei kann ich solche „Taschenspielertricks“ nicht gebrauchen und möchte meine Analyse auch nicht der täglichen Schwankung eines Wertes unterwerfen. Deshalb verwendet die oben schon gezeigte App auch nicht nicht ein Referenzdatum sondern einen Referenzzeitraum, über den Du mitteln kannst. Startpunkt und Dauer des Zeitraums kannst Du in der App bequem wählen und auch unter verschiedenen Vergleichsindizes auswählen. So kannst Du überprüfen, wie robust Deine Aussagen gegen die Wahl von diesen Randbedingungen ist.

Ich halte solche Betrachtungen zu Robustheit einer Aussage für unerlässlich, wenn Du Hypothesen zu Ursache-Wirkungsbeziehungen anhand von Aktienkursen betrachten möchtest.

Wie das für Adidas, Puma und Nike aussieht, kannst Du mit der App jedenfalls selbst überprüfen. Den Code, wie Du statt eines Referenzdatums einen Referenzzeitraum verwenden kannst, möchte ich Dir hier noch mitgeben:

# Wir definieren eine "Baseline":
blstart <- as.Date("2016-10-01")
blend <- blstart + 60     # Referenzzeitraum von 60 Tagen

BLAdidas <- Stock %>% 
            filter(Datum >= blstart) %>% 
            filter(Datum <= blend) %>% 
            pull(Adidas) %>% 
            mean()

„Nice to have“?

Jetzt stelle Dir vor, Du sitzt in der Strategieabteilung von Adidas und hast so ein Skript. Jeden Monat kannst Du es laufen lassen und nach wenigen SEKUNDEN hast Du die Übersicht, wo Konkurrenz und „Markt“ stehen. Es ist vielleicht nicht jedes Mal spannend genug, um dafür einen Termin beim Vorstand zu kriegen. Aber vielleicht möchten sie die Graphik irgendwann in den Standardunterlagen des Monatsrückblicks sehen – denn ein Blick auf den Markt und die Konkurrenz schadet ja nicht.

Und dann erstellst Du eine App, die jederzeit auf Knopfdruck genau das tut…

Wäre das vielleicht etwas?
Aber das ist eine andere Geschichte.
Und die musst Du ein andermal selbst erzählen.

Wie tief ist ein Atemzug des Planeten Erde?

Die Frage mag zunächst ungewöhnlich erscheinen: Wieso sollte der Planet Erde „atmen“?

Aus dem Biologieunterricht ist Dir vermutlich noch in Erinnerung, dass Pflanzen über den Prozess der Photosynthese dazu in der Lage sind, CO2 aus der Luft zu binden und Sauerstoff „auszuatmen“. Im Winter werfen Bäume ihre Blätter ab und gönnen sich eine Auszeit. Die Photosynthese kommt zum Erliegen, die heruntergefallenen Blätter verrotten und setzen dadurch CO2 frei, das im Laufe des Frühlings und Sommers wieder aufgenommen wird.

Warum Du diesen Beitrag lesen solltest

Es ist eine weithin bekannte Tatsache, dass die CO2-Konzentration in der Erdatmosphäre kontinuierlich steigt. Neben einigen anderen „Klima-Gasen“ sorgt Kohlendioxid für den „Treibhauseffekt“ unseres Planeten und trägt somit entscheidend zur Klimaerwärmung bei. Weniger bekannt ist, dass neben diesem Trend eine jährliche Oszillation zu beobachten ist. Mit öffentlich verfügbaren Daten kannst Du diese sichtbar machen und in Beziehung zum ansteigenden Trend setzen. – Wer hätte das gedacht?

Unsere heutige Fragestellung

Ein Blick auf die Weltkarte zeigt zudem, dass die Landmasse der Nordhalbkugel deutlich größer ist als die der Südhalbkugel. Der vorherigen Überlegung folgend sollte deshalb im nördlichen Winterhalbjahr die weltweite CO2-Konzentration steigen und im Sommerhalbjahr wieder sinken – der Planet „atmet“. Wenn das System Erde im Gleichgewicht wäre, dann würde die CO2-Konzentration der Atmosphäre um einen gewissen Mittelwert herum im Rhythmus der Jahreszeiten schwanken.

Wir stellen uns deshalb heute folgende Fragen:

Wie tief ist dieser „Atemzug“ des Planeten Erde? Und wie groß sind im Vergleich dazu der mittlere Anstieg der CO2-Konzentration in der Atmosphäre und die menschengemachten CO2-Emissionen?

Wir wollen uns dieser Frage mittels „OSAN“ (englisch: Open Source ANalytics) zuwenden, also öffentlich zugängliche Daten nutzen. Den Begriff scheint es bisher nicht zu geben. Wohl aber wird von „OSINT“ gesprochen (Open Source INTelligene) und so bietet sich OSAN als Beschreibung dessen an, was wir hier betreiben.

Wie wir vorgehen wollen

Wir verwenden die Skript-, Berichts- und Webapplikationssprache R, die speziell für die Handhabung von Daten, Texten und zunehmend auch Bildern entwickelt wurde. Du kannst Sie kostenfrei installieren und hast so auf einen Schlag Zugang zu den neuesten und besten Analysewerkzeugen. Der Vorteil unserer Herangehensweise hier liegt vor allem auch darin, dass Du Deine Analysen ständig aktuell halten kannst: einmal „Run“ gedrückt und schon lädt Dein Skript wieder die neuesten Daten herunter und wertet sie für Dich aus.

Woher unsere Daten kommen

Seit März 1958 misst das Mauna Loa Observatorium auf Hawaii Woche für Woche die CO2-Konzentration der Erdatmosphäre. Damals hat noch niemand vom Klimawandel gesprochen und es bestand vermutlich ein rein wissenschaftliches Interesse an den Messungen. Der Mauna Loa Vulkan wurde deshalb ausgewählt, weil er weit ab von Industriezentren liegt und so eine möglichst unverfälschte Messung erlaubt.

Wir beschaffen die Daten mit den folgenden Zeilen Skript. Eine gewisse Schwierigkeit stellen die Kommentarzeilen in dem Dokument dar. Möglicherweise ändert sich deren Anzahl im Laufe der Zeit – heute sind es 44 Zeilen. Dann musst Du Dir die Daten über den Link anschauen und die skip-Option der read.csv()-Funktion entsprechend anpassen:

# Paket für Handhabung der Daten:
library(tidyverse)

# Datenquelle:
link <- "https://scrippsco2.ucsd.edu/assets/data/
         atmospheric/stations/in_situ_co2/weekly/
         weekly_in_situ_co2_mlo.csv"

# Daten herunterladen:
MaunaLoa <- read.csv(link, 
                     header = FALSE, 
                     skip = 44, 
                     comment.char = "\"")

# Daten formatieren:
colnames(MaunaLoa) <- c("Week", "Conc")
MaunaLoa$Week <- as.Date(as.character(MaunaLoa$Week), 
                         format = "%Y-%m-%d")

# Graphische Darstellung:
ggplot(data = zeitraum) + 
  geom_point(mapping = aes(x = Week, 
                           y = Conc))

Graphische Darstellung der CO2-Daten des Mauna Loa Observatoriums auf Hawaii: Anstieg der CO2-Konzentration und jährliche Schwankungen. Dargestellt ist die Konzentration in „ppm“ (parts per million), also die Anzahl CO2-Moleküle je eine Millionen Moleküle Luft.

Trennung von jahreszeitlichen Schwankungen und langfristigem Trend

Wir sehen, was wir erwartet haben:

Die CO2-Konzentration in der Erdatmosphäre steigt beständig an. Sie durchläuft zudem jährliche Schwankungen.

Bei genauerem Hinsehen erkennst Du einige Besonderheiten: so scheint sich in den frühen 1990er Jahren ein kurzes „Plateau“ gebildet zu haben. Die Gründe dafür werden Experten längst bekannt sein. Wir wollen der Einfachheit halber die Daten ab 1995 verwenden, um Anstieg und Jahresschwankungen besser zu verstehen. Zudem fügen wir noch eine weitere Spalte an („mutate“), in der wir die Tage seit dem ersten Eintrag ablegen:

zeitraum <- MaunaLoa %>% 
    filter(Week >= "1995-01-01") %>%
    mutate(Days = difftime(Week,
                           zeitraum$Week[1], 
                           units = "days") %>% 
    as.numeric())

Heute möchte ich die Daten mit einem Polynom modellieren. Die Hintergründe zu dem Vorgehen hat die FU Berlin ins Netz gestellt. So können wir den langfristigen Trend erfassen. Durch „Spielen“ mit der Ordnung des Polynoms sehen wir auch, dass eine zweite Ordnung ausreichend ist und höhere Ordnungen nicht mehr signifikant sind. Wir interessieren uns zudem für die Zusammenfassung des Modells und die dazugehörigen 95%-Vertrauensintervalle der Parameter. Die Details erspare ich Dir hier. Mit den folgenden Code-Zeilen kannst Du sie Dir leicht selbst beschaffen:

# Modell erstellen:
model <- lm(Conc ~ poly(Days, 2, raw = TRUE), 
            data = zeitraum)

# Güte des Modells und der Parameter:
summary(model)
confint(model, level = 0.95)

# Modell und Residuen anzeigen:
plot(fitted(model), residuals(model))

# Trend und Schwankungen anfügen:
zeitraum$Trend <- model$fitted.values
zeitraum$Oszillation <- model$residuals

Wir erhalten so folgende Aussage (für die wir ein lineares Modell oder ein Polynom erster Ordnung rechnen):

Seit dem Jahr 1995 steigt die CO2-Konzentration der Erdatmosphäre Jahr für Jahr im Mittel um 2,1 ppm an.

Das mag nach wenig klingen. Wie wir sehen, „läppert“ sich das über die Jahre aber durchaus zusammen. Dank unserer Modellierung können wir nun auch die jahreszeitlichen Schwankungen betrachten:

ggplot(data = zeitraum) + 
   geom_line(aes(x = Week, 
                 y = Oszillation))

Ich gehe hier einen Schritt weiter und berechne für alle Jahre den jeweiligen Tag im Jahr, an dem jede Messung stattgefunden hat, um so, gemittelt über 7 Kalendertage, den Mittelwert und die Streuung der Werte zu allen betrachteten Jahren zu berechnen, die ich hier mit den jeweiligen Messwerten gemeinsam darstelle:

Jahreszeitliche Schwankung der CO2-Konzentration. Mittelwert (Linie) und Standardabweichung (Schlauch), zusammen mit den Einzelwerten der betrachteten Jahre.

Diese Graphik wollen wir uns auf der Zunge zergehen lassen: von Mitte Mai bis Anfang Oktober nimmt Jahr für Jahr die CO2-Konzentration der Erde um ca. 6,5 ppm ab (von ca. +3 ppm auf -3,5 ppm), um danach wieder anzusteigen. Die Erde „atmet ein“ und sie atmet wieder aus. Wir halten fest:

Die Erde hat ein Atemvolumen von ca. 6,5 ppm. Das entspricht in etwa dem mittleren Anstieg der CO2-Konzentration innerhalb von drei Jahren.

Anhand der Standardabweichung (der rosa Schlauch um den Mittelwert) erkennst Du zudem, dass der Frühlingsanfang größeren Schwankungen unterworfen zu sein scheint als der Beginn des Herbstes. Das ist interessant und wir fragen uns, ob der Frühling womöglich im Laufe der Zeit immer früher beginnt: Dafür tragen wir über die Jahre hinweg den Zeitpunkt auf, zu dem das Maximum der CO2-Oszillation erreicht wurde, stellen dabei aber kein signifikantes Signal fest. In R ist der Code dafür recht einfach (probiere das einmal in Excel…). Ich habe vorher alle Daten ab 1958 mit einem Polynom dritter Ordnung modelliert und so die Oszillationen für den gesamten Zeitraum berechnet, über die ich mir das jeweilige jährliche Maximum mittels slice_max() beschaffe. Nach einem „Signal“ suche ich mittels IMR-Regelkarte. Mit folgendem Code kannst Du diese Untersuchung selbst durchführen – auch wenn es hier nichts zu sehen gibt:

fruehling <- MaunaLoa %>% 
    group_by(Jahr) %>% 
    slice_max(Oszillation) %>% 
    select(Jahr, TagImJahr)

# IMR-Regelkarte
library(qcc)
imr <- qcc(fruehling$TagImJahr, type = "xbar.one")

Wie sieht es mit den menschengemachten CO2-Emissionen aus?

Dieser Frage nähern wir uns mit folgenden, vermutlich grob vereinfachenden Annahmen:

  • Die auf dem Mauna Loa gemessene CO2-Konzentration ist ein gutes Maß für die mittlere CO2-Konzentration der gesamten Erdatmosphäre
  • Die Masse der Erdatmosphäre ist über die Jahre hinweg konstant. Wir finden dafür auf Wikipedia den Wert von 5,15*10^18 kg.

Über diese Annahmen lässt sich die in ppm gemessene CO2-Konzentration umrechnen in die in der Atmosphäre enthaltenen Masse an CO2. Dafür verwende ich ein Molgewicht von 28,8u für Luft (80% Stickstoff mit 28u und 20% Sauerstoff mit 32u) und von 44u für CO2. Auf Statista.com finde ich zudem einen Wert für die menschengemachten jährlichen CO2-Emissionen in Höhe von 37,1 Milliarden Tonnen (im Jahr 2021). So erzeuge ich folgende Graphik. Den „langfristigen Anstieg“ habe ich dabei über ein lineares Modell berechnet:

Jährliche Oszillation der CO2-Konzentration getrennt von dem überlagerten langfristigen Anstieg und im Vergleich zu den jährlichen weltweiten CO2-Emissionen.

Das Jahr 2023 fängt interessanterweise mit besonders niedrigen Werten an: es lohnt sich vermutlich, diese Entwicklung weiter im Blick behalten. Die wesentlichen Einsichten wollen wir festhalten:

Der jährliche „Atemzug“ der Erde (Maximum zu Minimum) entspricht in etwa 70 Milliarden Tonnen CO2. Das ist etwa doppelt soviel wie die Menschheit Jahr für Jahr emittiert. Jedes Jahr steigt die Masse an CO2 in der Erdatmosphäre um ca. 17 Milliarden Tonnen an.

Du wirst nun fragen:

Und wo bleibt bitteschön der Rest?

Denn die Menschheit emittiert 37 Milliarden Tonnen, von denen – unter den hier gemachten Annahmen und mit den hier verwendeten Zahlen – ca. „nur“ 17 Milliarden Tonnen in der Atmosphäre verbleiben.

Der Planet scheint einen gewissen Anteil der weltweiten Emissionen anderweitig „wegzupacken“.

In Forschung und Wissenschaft ist sicher bekannt, welche Mechanismen dafür verantwortlich sind: hoffentlich möglichst viel natürliches „Carbon Capture and Storage“ (CCS)? Mir fallen hier Muscheln und Krustentiere ein, die ihre Schale mit Kalk (CaCO2) bilden und nach Ableben im Meer zu Boden sinken. Im Laufe der Zeit kommt dabei einiges zusammen – zu besichtigen in den Kalkalpen.

Wie groß ist aber der Anteil des in Ozeanen gelösten CO2? Das würde auch zu einer größeren Versauerung der Ozeane führen. So stellen sich mir folgende Fragen:

Welche Auswirkungen hat das? Wann und unter welchen Bedingungen (beim Erreichen von Kipppunkten zum Beispiel) wird das alles wieder freigesetzt? Schlummern hier vielleicht weitere Risiken als „nur“ der Treibhauseffekt in der Atmosphäre?

Jede Antwort wirft neue Fragen auf

Wir haben öffentlich verfügbare Daten verwendet und zueinander in Beziehung gesetzt (die auf Hawaii gemessene CO2-Konzentration und die weltweiten CO2-Emissionen). Dabei haben wir einen Eindruck erhalten von den Größenordnungen und konnten die – zumindest für mich als Laien – überraschende Frage nach der „CO2-Resilienz“ des Planeten aufwerfen.

Als Abschluss unserer OSAN-Betrachtung halten uns deshalb wieder einmal an Michael Ende und den Schlusssatz vieler Episoden seiner „Unendlichen Geschichte“:

„Aber das ist eine andere Geschichte. Und die soll ein andermal erzählt werden.“

Ich danke meinem Kollegen Thomas Rietdorf vom Europäischen Six Sigma Club Deutschland für seine kritische Durchsicht dieses Beitrags.

Wie steht es um die deutsch-französische Energieeffizienz?

Warum Du diesen Beitrag lesen solltest

Das Thema „Energie“ ist in aller Munde – auch im europäischen Ausland. Dabei werden die Dinge durchaus verschieden gesehen. Wenn Du diese Debatte besser verstehen und vielleicht auch zu ihr beitragen möchtest, dann kommst Du nicht umhin, Dich mit den Entwicklungen auseinanderzusetzen. Dafür kannst Du öffentlich verfügbare Daten nutzen. Das ist einfacher, als Du denken magst.

Heute schwingt Herzblut mit

Wenn Du die Presse jenseits des Rheins verfolgst, dann kannst Du beobachten, wie in Frankreich der Geduldsfaden zu manchen deutschen Vorstellungen in Sachen Energiewende inzwischen recht dünn geworden zu sein scheint. Die gestrige FAZ bietet dazu eine Zusammenfassung. Eine detaillierte Analyse zum Stein des Anstoßes (aus Sicht der deutschen Verhandlungsseite) beziehungsweise zur Komplexität der Lösung (aus französischer Sicht) findet sich im Economist vom 12. Dezember 2022. Einig sind sich beide Seiten – aber bei weitem nicht alle gesellschaftliche Gruppen – dass es mit der Wirtschaft weiter gehen muss und dass das mit so wenig CO2-Emissionen wie möglich geschehen soll. Auf jeden Fall gibt es zum „Wie“ Gesprächs- und Handlungsbedarf.

Persönlich liegt mir sehr viel an diesen Themen. Ich glaube, dass unsere Generation die Energiewende hinkriegen und dafür über Länder und Kontinente hinweg an einem Strang ziehen muss. Ich habe zudem die 1990er-Jahre in Frankreich verbracht. Diese Erinnerungen sind mir sehr teuer. Viele meiner Freunde leben dort. Es schwingt also Herzblut mit.

Das wollen wir außen vor lassen und nehmen uns des Themas anhand von Daten an. Dafür greifen wir auf einen vorherigen Beitrag zurück, in dem wir die Aussage betrachtet haben, Deutschland setze seine Emissionen besonders effizient ein („Klimaweltmeister“). Unter den 10 größten Emittenten stand Deutschland tatsächlich vorn. Unter den 20 größten jedoch Frankreich. Wir wollen deshalb heute, anlässlich des Artikels in der FAZ, die zeitliche Entwicklung für diese beiden Länder genauer betrachten.

In meiner demokratischen Grundüberzeugung teile ich wieder die Code-Zeilen, damit Du die Analyse auch selbst nachvollziehen kannst.

Los geht’s!

Die Weltbank stellt ihre Daten zur Verfügung, damit wir sie nutzen

Wenn Du die Datenbank der Weltbank noch nicht kennst, dann schaue sie Dir unbedingt an. Es gibt zu allem von Wirtschaft über Klima zu Gesundheit und mehr für jedes Land und jedes Jahr Daten – und das seit dem Jahr 1960. Mit den folgenden Zeilen kannst Du sie Dir auf Deinen Rechner holen. Bequemerweise verwenden wir dafür die Skriptsprache R, die speziell für die Handhabung von Daten, Texten und zunehmend auch Bildern entwickelt wurde. Du kannst Sie kostenfrei installieren und hast so auf einen Schlag Zugang zu den neuesten und besten Analysewerkzeugen. Pas mal!

# Verwendete Bibliotheken
library(WDI)
library(tidyverse)

# Wir beschaffen uns die Daten.
# Heute nur zwei, CO2-Emissionen und Bruttosozialprodukt:
ID <- c("EN.ATM.CO2E.KT", "NY.GDP.MKTP.CD")
indicatortable <- WDI(indicator = ID, extra = TRUE)

# Wir filtern nach Deutschland und Frankreich
# und wählen (select) unsere Spalten aus:
data <- indicatortable %>% 
  filter(country %in% c("Germany", "France")) %>% 
  select(country, year, NY.GDP.MKTP.CD, EN.ATM.CO2E.KT)

Drei Befehle. Das war’s.

Zeitliche Entwicklung

Wie hat sich nun die CO2-Effizienz von Frankreich und Deutschland entwickelt? Wir berechnen dafür zunächst die Wirtschaftsleistung in Dollar je eingesetztes Kilogramm an emittiertem CO2. In den Daten vor 1990 fehlen einige Werte und diese Jahre blende ich deshalb aus:

# efficiency in Dollar BSP je kg CO2:
data <- data %>% 
          filter(year >= 1990) %>%
          mutate(efficiency = 
                 NY.GDP.MKTP.CD/EN.ATM.CO2E.KT/1e6) 

# Graphische Darstellung:
ggplot(data = data, 
       aes(x = year,
           y = efficiency,
           colour = country))

CO2-Effizienz der Länder Frankreich und Deutschland seit 1990. Beachte den Anstieg in Frankreich von 2000 bis 2008.

Wir sehen eine beachtliche Entwicklung: seit dem Jahr 1990 hat die deutsche Wirtschaft ihre CO2-Effizienz von zwei Dollar pro Kilogramm emittiertes CO2 auf sechs Dollar etwa verdreifacht. Für Frankreich fällt diese Steigerung zwar etwas geringer aus, dafür aber auf deutlich höherem Niveau. Für das Jahr 2021, dem letzten Jahr, zu dem uns derzeit Daten vorliegen, halten wir fest:

Die französische Wirtschaft hat eine 50% höhere Energieeffizienz als die deutsche: 9 Dollar je Kilogramm CO2 anstatt 6 Dollar.

Zurücklehnen dürfen wir uns in Deutschland sicher nicht

Dass die französische Wirtschaft CO2-effizienter wirtschaftet als die deutsche, das ist auch diesseits des Rheins unbestritten. In unserem vorherigen Beitrag haben wir zudem gesehen, dass solche Kennzahlen mit Vorsicht betrachtet werden müssen, denn der „wahre Klimaweltmeister“ ist die demokratische Republik Kongo. Wenn Dich das überrascht, dann schau es Dir in dem vorherigen Beitrag an. Die Struktur der Wirtschaft (Produktion und Landwirtschaft im Vergleich zu Dienstleistungen), die Art der Energieerzeugung (Öl und Gas im Vergleich zu Wind und Sonne oder Nuklearenergie) und vieles mehr spielt hier eine Rolle.

Erklären soll den oben dargestellten Unterschied zwischen Deutschland und Frankreich jemand anders. Meine Freundin Renate zweifelt diese Art der Bewertung auch grundsätzlich an: wir verwenden hier Kennzahlen einer „alten Wirklichkeit“, die „überholt“ ist, um Ziele für eine „neue Wirklichkeit“ zu formulieren, die es zu erschaffen gilt. In dieser Sichtweise – die Dir vielleicht überraschend vertraut vorkommt, wenn Du Dich mit Transformationen im Unternehmenszusammenhang auseinandersetzt – ist meine gesamte Herangehensweise hier fragwürdig.

Einig sind sich vermutlich alle: zurücklehnen dürfen wir uns in Deutschland nicht. Das will hoffentlich auch niemand. Ich bin zudem sicher nicht der einzige, der ein gutes Verhältnis zwischen Deutschland und Frankreich als entscheidend betrachtet für Europa – und ich meine damit den Kontinent und die Menschen, die dort leben.

Meiner Ansicht nach sollte die obige Darstellung zumindest nachdenklich, vielleicht auch etwas zurückhaltender stimmen. Auf alle Fälle sollten wir alle, so denke ich, versuchen, die jeweils andere Seite zu verstehen. Die eingangs zitierten Artikel bieten dafür eine gute Grundlage. Wer zudem noch die Sprache der anderen Seite spricht kann Brücken bauen. Die Europabrücke steht nicht umsonst zwischen Kehl und Straßburg.

Mir wird wieder einmal klar,

  • wie dankbar wir für eine gute Presselandschaft sein können
  • wie wichtig es ist, die dort formulierten Denkanstöße aufzugreifen
  • und den Fragen selbst mit öffentlich verfügbaren Daten nachzugehen.

Demokratie – quo vadis?

Was ist „Demokratie“?
Wie unterscheidet sie sich von anderen Regierungsformen?
Wie geht es weiter mit ihr?

Diese Fragen werden in der öffentlichen Debatte immer wieder aufgeworfen. Dabei bleibt so manches unklar, denn interessanterweise kommt der Begriff „Demokratie“ nicht einmal im deutschen Grundgesetz vor. Dort ist vielmehr von der „freiheitlich-demokratischen Grundordnung“ die Rede.

Warum Du diesen Beitrag lesen solltest

Wie auch immer Du Dich zum Thema „Demokratie“ positionierst: Du solltest darüber Bescheid wissen. Keine Lust auf dicke Bücher? Auch gut: wie wäre es dann mit Datenkolonnen? Die stehen nämlich öffentlich und in bestechender Qualität zur Verfügung. Und Du kannst sie für Deine Argumente nutzen. Das ist leichter – und inspirierender – als zu zunächst denken magst.

Demokratie – ein Auslaufmodell?

Manche halten die Demokratie für ein Auslaufmodell. Andere betrachten sie als „bedrohte Lebensform“ – so zumindest der Titel eines 2019 erschienenen Buches. Und Arte sieht sie „weltweit unter Druck“ – sehenswert: „Mit offenen Karten“ vom Mai 2022.

Wir wollen uns dem Thema auf Grundlage von Daten nähern. Das erscheint vor allem deshalb lohnend, weil dank der Initiativen von „State of Democracy“ und „Varieties of Democracy“ über Jahrzehnte hinweg umfangreiche Daten zu nahezu allen Ländern vorliegen.

Heute möchte ich

  1. anhand dieser Daten Fragestellungen zu Regierungsformen diskutieren
  2. darstellen, wie wichtig auch die Demokratisierung der Datenanalyse ist
  3. Dir helfen, diesen emotional geführten Debatten faktische Grundlagen zu geben.

Es ist heute auch etwas mehr geworden und Du solltest etwa 15-20 Minuten Zeit für die Lektüre mitbringen. Oder Du hangelst Dich anhand der Überschriften und Bildunterschriften durch. Am Ende fasse ich alles noch einmal zusammen.

Los geht’s!

Hintergrund zu den Daten und zu meinem Anliegen

Wenn Du möchtest, dann kannst Du die Daten von „State of Democracy“ in Excel- oder csv-Format herunterladen. Sie sind hier genau beschrieben. Mein vorheriger Beitrag gibt Dir eine kurze Übersicht.

Wenn Du bisher Daten mit Excel & Co analysiert hast, dann solltest Du das jetzt unbedingt auch versuchen – denn das ist im vorliegenden Fall eine wahre Plackerei und Du wirst nicht weit kommen. Moderne Fertigungs- und Transaktionsdaten sind in der Regel übrigens zumindest ähnlich komplex. Meine Hoffnung ist, dass Dich das motiviert, das Coden mit R oder Python zu erlernen. Wenn Du unabhängig sein und eigene Fragestellungen beantworten möchtest, dann kommst meiner Ansicht nach ohnehin nicht mehr darum herum.

Ich werde deshalb die wesentlichen Skriptzeilen einfügen und erläutern: Coden ist kein Hexenwerk – nicht zuletzt, weil Dir dabei zunehmend freundliche KI-Helferlein wie z.B. ChatGPT zur Seite stehen.

Wie wir die Daten auswerten

Ich verwende die Skriptsprache R, die speziell für die Handhabung von Daten, Texten und zunehmend auch Bildern entwickelt wurde. Du kannst Sie kostenfrei installieren und hast so auf einen Schlag Zugang zu den neuesten und besten Analysewerkzeugen, wie sie zum Teil auch schon in moderner Bezahlsoftware zur Verfügung stehen. So bist Du flexibel, stets eine Nasenlänge voraus, kannst Dich mit einer großen Community austauschen – und Du bezahlst nichts. Der Preis besteht freilich darin, dass Du Skripte schreibst und nicht einfach „klicken“ kannst.

Schauen wir uns an, was das konkret bedeutet.

Wir beschaffen uns die Daten

Es mag sein, dass der folgende Link sich im Laufe der Zeit ändert und Du ihn aktualisieren musst:

link <- "https://www.idea.int/gsod-indices/sites/default/
         files/inline-files/gsodi_v6.1_1975_2021.csv"

t <- vroom(link, 
           delim = ";", 
           locale = locale(decimal_mark = ","))

Das war’s. Wir haben die Daten.

Die Struktur der Daten

Die so erzeugte Tabelle t hat über 9000 Zeilen und mehr als 200 Spalten, eine Zeile je Land und Jahr. In den Spalten werden Daten zu dem Grad von Null bis Eins erfasst, in dem über 140 Attribute, Unterattribute und Indizes erfüllt sind. Auf höchster Ebene geht es um die Erwartungen, die Menschen an ihre Regierung haben:

  • Repräsentative Regierung (CA_1, „representative government“)
  • Fundamentale Rechte (CA_2, „fundamental rights“)
  • Überprüfung der Regierung (CA_3, „checks on the government“)
  • Unvoreingenommene Verwaltung (CA_4, „impartial administration“)
  • Bürgerliche Beteiligung (CA_5, „participatory engagement“).

Menschen wollen gut repräsentiert werden. Sie wollen, dass ihre fundamentalen Rechte geschützt werden, dass die Regierungsarbeit überprüft wird, dass sie es mit einer unvoreingenommen Verwaltung zu tun haben und sich selbst beteiligen können. Das klingt vernünftig.

Nun wirst Du fragen:

„Fundamentale Rechte:
Das ist recht schwammig.
Was heißt das?“

Dazu kannst Du die „Unterattribute“ betrachten, die in diesem Fall sogar aus Unter-Unterattributen bestehen, für die wiederum „Indizes“ gemessen werden: eine zunächst verwirrende aber äußerst reichhaltige Vielfalt.

Erkunde die Daten selbst – mit dem „Democralyser“

Ich habe eine R-Applikation geschrieben, den Democralyser, mit dem Du diese Zusammenhänge selbst erkunden kannst. Dieses (externe) Video gibt Dir dazu eine kurze, englischsprachige Einführung. Bevor Du weiterliest oder weiterarbeitest, empfehle ich Dir, ein wenig mit dem Democralyser zu spielen. Eine Warnung meines Freundes Mehmet: das kann ganz schön süchtig machen …

Wir bereiten die Daten auf

„Aus methodischen Gründen“ wird das Attribut der bürgerlichen Beteiligung (C_A5) nicht auf höchster Ebene aggregiert. Ich nehme mir dennoch die Freiheit, den Mittelwert (rowMeans) der entsprechenden Unterattribute zu bilden. Für alle Indizes und Attribute entferne ich zudem die Spalten für die oberen und unteren Konfidenzintervalle, sortieren die verbleibenden Spalten, formatiere die Regierungsformen als Faktoren und nehme Ländergruppen („groups“, s.u.) wie EU, ASEAN, Afrika usw. heraus, die dankenswerterweise in den letzten Zeilen stehen:

t$C_A5 <- t %>% 
          select(starts_with("C_SD5")) %>% 
          rowMeans(na.rm = TRUE)

t <- t %>% 
          select(-starts_with(c("U", "L"))) %>%  # upper/lower CL
          select(starts_with(c("ID", "C_A", "C_SD", "v_")), 
          everything())

t$regime_status_name <- 
          factor(t$regime_status_name, 
                 levels = c("Authoritarian regime", 
                            "Hybrid regime", 
                            "Democracy"))

t$democratic_performance_name <- 
          factor(t$democratic_performance_name, 
                 levels = c("Authoritarian regime", 
                            "Hybrid regime", 
                            "Weak democracy", 
                            "Mid-range performing democracy",
                            "High performing democracy"))

# TODO: nicht elegant, da hart auf Zeilenbasis codiert:
groups <- unique(t$ID_country_name)[175:203]
t <- t %>% filter(ID_country_name %notin% groups)

Grundsätzliche Eigenschaften der Daten

Die Anzahl demokratischer Länder ist seit über 20 Jahren stabil

Wir wollen uns zunächst anschauen, wie sich die Regierungsformen im Laufe der Zeit entwickeln:

t %>% 
  ggplot(aes(x = ID_year, 
             fill = regime_status_name)) +
  geom_bar(position = "stack")

Regierungsformen im Wandel der Jahre

Unter dem Eindruck der oben zitierten Einschätzungen der Demokratie als „bedrohter Lebensform“, die „weltweit unter Druck“ ist, sind wir überrascht zu sehen, dass sie sich nicht auf dem Rückzug befindet, vielmehr:

In dem Zeitraum von Mitte der 1980er Jahre bis etwa zum Jahr 2000 ist die Anzahl der demokratisch regierten Länder stark angestiegen. Seither ist sie mehr oder weniger stabil.

Die Daten sind für alle Indizes normiert – mit einer Ausnahme

Schauen wir uns nun die Verteilung der Indizes an. Dafür stapele die Daten mit einer eigenen Funktion „my_stack(), um alle Werte in eine Spalte zu bringen und sie so allesamt in einem Histogramm darstellen zu können:

# TODO: ersetze diese Funktion durch eine dplyr-Lösung
t_stacked <- my_stack(t, c(9:154), c(1,3))
ggplot(data = t_stacked, 
       aes(x = values)) + 
  geom_histogram()

Histogramm aller Werte (alle Länder, Jahre und Attribute/Indizes)

Gut, dass wir das getan haben, denn wir erkennen eine nützliche Eigenschaft und erleben eine Überraschung: Die Werte liegen fast alle zwischen Null (Attribut ist abwesend) und Eins (Attribut ist vollständig anwesend). Das ist praktisch, denn so müssen wir später kein „feature scaling“ betreiben. Es gibt jedoch auch einige wenige Werte, die größer als Eins sind. Die schauen wir uns genauer an:

t_stacked %>% filter(values > 1)

Es handelt sich hier ausschließlich um den Index v_52_01 „Electoral participation“ (Wahlbeteiligung) und auch nur zu einigen Ländern und Jahren. Im „Codebook“ findet sich dazu folgende Klarstellung (ich übersetze sinngemäß):

Die Werte für die Bevölkerung im Wahlalter kann Unregelmäßigkeiten wie Probleme mit dem Wählerverzeichnis oder dem Registrierungssystem widerspiegeln. Diese Werte beruhen auf Schätzungen, da sie keine rechtlichen oder systemischen Hindernisse berücksichtigen oder nicht anspruchsberechtigte Mitglieder der Bevölkerung berücksichtigen. Daher kann dieser Index den Wert von 1 überschreiten, was kein Fehler ist, sondern solche Bedingungen widerspiegelt.

Gegebenenfalls müssen wir also Einträge dieses Index gesondert betrachten. Erlaubt sei dieser Hinweis: Daten vor der Analyse zu erkunden und gegebenenfalls zu säubern ist ein wesentlicher und oft zeitraubender Bestandteil der Arbeit. Ohne Skripte ist das gerade bei großen Datensätzen wie dem hier vorliegenden so mühsam, dass es im Zweifel sogar unmöglich wird.

Alles hängt miteinander zusammen

Als nächstes möchte ich verstehen, wie stark die vielen Indizes und Attribute untereinander korrelieren. Dafür wähle ich die Index- und Attributspalten aus, die praktischerweise mit „v_“ und „C_“ beginnen, bereite das Ergebnis als Matrix auf und verwende die Funktion rcorr(), die sowohl den Korrelationskoeffizienten als auch den dazugehörigen P-Wert bereitstellt. Bis auf wenige Ausnahmen sind alle unten dargestellten Korrelationen statistisch signifikant:

# Korrelationsmatrix erstellen:
corr.m <- t %>% 
            select(starts_with(c("v_", "C_"))) %>% 
            as.matrix() %>% 
            Hmisc::rcorr()

# Korrelationsmatrix graphisch aufbereiten:
gplots::heatmap.2(corr.m$r^2,
                  dendrogram = "none",
                  Rowv = FALSE, Colv = FALSE, trace = "none")

Zusammen mit einigen zusätzlichen Formatanweisungen für die heatmap.2 erhalten wir folgende Darstellung:

Korrelationen zwischen Attributen und Indizes, gemessen in R^2. Rechts unten befinden sich die aggregierten Attribute

Ich zeige hier R^2 anstatt des sonst üblichen Korrelationskoeffizienten R und behalte das Vorzeichen bei. Die statistische Größe R^2 hat eine anschauliche Bedeutung: ein R^2 von 90% bedeutet, dass die Variation eines Index zu 90% mit der Variation in eines anderen zusammenfällt („wenn der eine raufgeht, dann geht der andere auch rauf“). Nur 10% der Variation sind unabhängig. Wir erkennen starke Korrelationen auch weitab der Diagonalen: selbst Indizes, die zu anderen Hauptattributen gehören, gehen Hand in Hand. So korreliert zum Beispiel die Meinungsfreiheit (v_22_01 .. 08, Bestandteil der fundamentalen Rechte) mit einem effektiven Parlament (v_31_01 .. 05, Bestandteil der Überprüfung der Regierung).

Solche Einsichten mögen Dich nicht überraschen. Aber Hand auf’s Herz: hättest Du das vorhergesagt? Und alle die Korrelationen anderen auch? Dank der Daten können wir diese Muster nicht nur aufdecken sondern auch quantifizieren.

Um diesen Dingen weiter auf den Grund zu gehen, sortiere ich die so erhaltenen Daten nach R^2. Dabei stoße ich auf eine weitere Überraschung: Die Werte der Indizes v_14_04 (Wahlen) und v_53_02 (Direkte Demokratie) sind identisch (R^2 = 100%). Wir erkennen auch eine hohe Korrelation zwischen v_11_01 (Unabhängigkeit des Wahlleitungsorgans) und v_31_04 (Legislative Oppositionsparteien). Es dürfte schwer sein, in diesem großen Datensatz solche Zusammenhänge mit „Klicksoftware“ zu finden. Sobald sie jedoch gefunden sind, kannst Du sie auch mit Excel darstellen:

Zusammenhang zwischen v_11_01 (Unabhängigkeit des Wahlleitungsorgans) und v_31_04 (Legislative Oppositionsparteien). Dank der Transparenz der Punkte entsprechen Schwärzungen einer Häufung von Wertepaaren.

Unser Datensatz mit 116 gemessenen Merkmalen („Indizes“) hat etwa 15-20 Dimensionen

Bei starken Korrelationen in einem Datensatz sollten wir eine Hauptkomponentenanalyse durchführen: Hier haben wir es mit 116 Indizes v_ij_kl zu tun. Wenn diese unabhängig wären, dann hätte unser Datensatz 116 „Dimensionen“. Über eine Hauptkomponentenanalyse erfahren wir, wie viele „Dimensionen“ der Datensatz tatsächlich hat.

Dafür erstelle ich einen Arbeitsdatensatz der Indizes (die mit „v_“ beginnen), aus dem ich alle Zeilen mit NA-Einträgen herauslösche. Damit berechne ich die Hauptkomponenten PC und deren kumulierte Varianz, die ich graphisch als „Scree Plot“ darstelle:

workdata <- t %>% 
            select(starts_with(c("v_"))) %>% 
            drop_na

pca_obj <- prcomp(workdata)

data.frame(Var = pca_obj$sdev^2) %>% 
  mutate(PC = 1:length(pca_obj$sdev),
         VarExplained = cumsum(Var)/sum(Var)) %>% 
  ggplot() + 
    geom_line(aes(x = PC, 
                  y=VarExplained))

Hauptkomponentenanalyse: Kumulierte Variation gegen Anzahl der berücksichtigten Hauptkomponenten.

Die ersten 15 Hauptkomponenten erklären also etwa 80% (0.8) der beobachteten Variation. In anderen Worten: unser Datensatz mit 116 Spalten hat „im Großen und Ganzen“ 15 Dimensionen. Allein mit den ersten zwei Hauptkomponenten können wir sogar schon etwa 50% der Variation erklären.

Das ist eine nützliche Eigenschaft: Versuchsweise trenne ich meinen Arbeits- in einen Trainings- und einen Validierungsdatensatz und trainiere ein SVM-Modell (Support Vector Machine), mit dem ich die Regierungsformen im Validierungsdatensatz vorherzusage. Das Ergebnis sieht wie folgt aus:

Vorhersage der Regierungsformen auf Grundlage der ersten zwei Hauptkomponenten. Punkte: „tatsächliche“ Regierungsform. Einfärbung: Modell. Grün: Demokratie, Blau: Hybrid. Rot: autoritäres Regime. Bei einem perfekten Modell lägen alle Punkte in dem Bereich der jeweiligen Farbe.

Wir erkennen, dass Demokratien und autoritäre Regime recht gut getrennt werden, hybride Regime sich jedoch auf Grundlage der beiden Hauptkomponenten nicht gut identifizieren lassen.

Entscheidungsbäume: worin unterscheiden sich die Regierungsformen?

Gehen wir ans Eingemachte: Wir haben mehr als hundert verschiedene Attribute und Indizes zu allen Ländern und Jahren, magst Du Dir sagen. Aber worin unterscheiden sich die Regierungsformen nun „wirklich“? 

Unter den Hauptkomponenten können wir uns wenig vorstellen. Auch kann eine Regierung  nicht  einfach auf die ersten 3-5 Hauptkomponenten achten. Mit den Begrifflichkeiten des maschinellen Lernens formuliert: „feature extraction“ hilft uns hier nicht. Wir wollen die wesentlichen Merkmale auswählen können – „feature selection„.

Dieser Frage gehen wir auf Grundlage der „Indizes“ (v_ij_kl) nach und führen sie gemeinsam mit dem Ländernamen und der Regierungsform in einer neuen Arbeitstabelle („workdata“) zusammen. So erhalten wir mehr als 7000 Zeilen und bilden bei dieser Größe aus einem Fünftel einen Trainingsdatensatz („train“). Das Ergebnis validieren wir mit den verbleibenden Zeilen („valid“).

workdata <- t %>% 
            select(ID_country_name, 
                   regime_status_name, 
                   starts_with(c("v_")))

trainsize <- round(nrow(workdata)*0.2, 0)
trainvector <- sample(1:nrow(workdata), trainsize)

train <- workdata[trainvector, ] %>% select(-ID_country_name)
valid <- workdata[-trainvector, ] %>% select(-ID_country_name)

Wir erstellen nun eine Entscheidungsbaum-Klassifikation:

library(rpart)
library(rpart.plot)

classifier <- rpart(formula = regime_status_name ~ .,
                    data = train,
                    control = rpart.control(minsplit=10, 
                                            cp=0.1))

rpart.plot(classifier, type = 1, cex = 0.8)

Entscheidungsbaum für Regierungsformen.

Demokratien können wir also sehr gut daran erkennen, dass es bei Wahlen einen echten Wettbewerb gibt (v_11_06). Wenn wir dieses Kriterium anwenden, dann verfängt sich in den Validerungsdaten nicht ein einziges autoritäres oder hybrides Regime.

Die Unterscheidung zwischen autoritären und hybriden Regimen entscheidet sich anhand von freien und fairen Wahlen (v_11_05). Allerdings ist diese Aufteilung nicht besonders genau: immerhin wird ein Drittel (0.33) der hybriden Regime fälschlicherweise als autoritär klassifiziert. Wir erhalten also ein ähnliches Bild wie bei der SVM-Modellierung über die beiden ersten Hauptkomponenten:

Hybride Regierungsformen scheinen ein schwer greifbares „Zwischending“ zu sein.

Unser Glas ist dennoch deutlich mehr als halbvoll: Insgesamt werden immerhin 94% aller Regierungsformen richtig klassifiziert, wie wir feststellen, indem wir den Entscheidungsbaum verwenden, um die Regierungsform in dem Validierungsdatensatz vorherzusagen, und dieses Ergebnis mit den „echten“ Werten vergleichen.

Wir verstehen 94% von dem was los ist!

Da ich für diese Betrachtungen einen zufälligen und absichtlich kleinen Trainingsdatensatz gezogen habe, wiederhole ich meine Analyse einige Male und stelle fest, dass der Algorithmus für manche Stichproben anstatt v_11_05 < 0.4 den Index v_13_02 < 0.7 („Hürden für Parteien“) heranzieht. Wir halten fest:

Laut unseren Daten zeichnen sich Demokratien vor allem durch freie und faire Wahlen aus, bei denen ein echter Wettbewerb zwischen Parteien stattfindet.

Auch das mag nicht überraschend sein und nach dem Merksatz eines Schulbuchs aus der 11. Klasse klingen. Wir erleben hier etwas, das ich auch bei der Analyse von Unternehmensdaten immer wieder sehe: Zunächst stößt Du auf bekannte oder zumindest wenig überraschende Zusammenhänge, die Leute vom Fach schon kennen. Aber wieder Hand auf’s Herz: Hättest Du die Eingangsfrage auch so beantwortet? Und auch wenn Du es getan hast: ist es nicht gut, hier schwarz auf weiß eine Bestätigung durch Daten vorliegen zu haben?

Zu dieser nicht ungewöhnlichen Situation möchte ich Dir folgendes mitgeben:

  1. Dank einer Datenanalyse braucht es nicht jahrelange Erfahrung, um Einsichten zu gewinnen.
  2. Du kannst mit einer Datenanalyse nicht nur Zusammenhänge und Muster erkennen. Du kannst auch ihre Stärke quantifizieren.
  3. Es besteht ein großer Unterschied zwischen „ja, ja, das ist nichts Neues“ und einer auf Datengrundlage erzeugten Liste von Einsichten.

Ich hoffe, diese drei Punkte helfen Dir bei Deiner Arbeit als Analyst oder Analystin. Denn wenn Du Dein Vorgehen von Anfang an richtig kommunizierst und darauf hinweist, dass Du vermutlich zunächst bekannte Zusammenhänge finden wirst (frage gerne vorher nach, welche Zusammenhänge Dein Publikum erwartet), dann schaffst Du Vertrauen in Deine auf Datenbasis gewonnen Aussagen. Neue und manchmal „schwer verdauliche“ Einsichten kommen später – und für die brauchst Du eben dieses Vertrauen.

Das Ende der Fahnenstange: können wir die Regimeformen überhaupt anhand der vorliegenden Daten unterscheiden?

Nach unseren Erfahrungen mit den Hauptkomponenten und den Entscheidungsbäumen liegt die Frage nahe: lohnen sich weitere Untersuchungen überhaupt – oder hat jemand die zu einem Datensatz gehörige Regimeform „geschätzt“ oder gar „gewürfelt“?

Bevor wir uns allzu sehr plagen, packe ich gleich die ganz große Bazooka aus: Neuronale Netze. Die gibt’s andernorts nur gegen den branchenüblichen Aufpreis der Bezahlsoftware. Mit R und Python hast Du das „für umme“: Mit wenigen Zeilen kannst Du – solange Du eine Internetverbindung hast – neuronale Netze auf fernen Servern rechnen lassen.

Ich verwende h2o und baue ein neuronales Netz aus vier Ebenen mit je 60 Neuronen auf – der Fadenwurm hat 302. Die 60 Neuronen je Ebene entsprechen in etwa der Hälfte der Anzahl an Features v_ij_kl – meine Daumenregel für neuronale Netze. Trainings- und Validierungsdatensätze habe ich dabei wie oben erstellt:

library(h2o)
h2o.init(nthreads = -1) 

classifier <- 
   h2o.deeplearning(y = 'regime_status_name',
                    training_frame = as.h2o(train),
                    activation = 'Rectifier', 
   hidden = c(60, 60, 60, 60), 
   epochs = 100,
   train_samples_per_iteration = -2) 

y_pred <- h2o.predict(classifier, 
                      newdata = as.h2o(valid)) %>% 
          as.data.frame()

Das Ergebnis ist – gelinde gesagt – der Hammer. Falls Du selbst versucht hast, den Regime-Status anhand der Indizes vorherzusagen, dann kannst Du das vermutlich nachvollziehen. Hier ist die „Confusion Matrix“:

Confusion Matrix des mit neuronalen Netzen erhaltenen Modells: nur zwei Ereignisse wurden falsch klassifiziert.

Die Aussage lautet:

„Gib mir einen vollständigen Satz an Indizes v_ij_kl zu einem x-beliebigen Land. Ich kann Dir dann mit 99,9%-iger Sicherheit sagen, um welche Regimeform es sich handelt“.

Wenn Du ein wenig Erfahrung mit Wertungsdaten („judgemental data„) wie diesen hast, dann wirst Du jetzt vermutlich auch tief durchatmen:

„Die Leute von State of Democracy haben wirklich sehr, sehr saubere Arbeit geleistet!“

Um es ganz klar zu sagen: fake data sehen anders aus. Wir haben es mit einem Datensatz von sehr hoher Qualität zu tun.

Der Vollständigkeit halber wiederhole ich diese Analyse mit einem Random Forest und mit allen Attributen, Sub- und Subsub-Attributen und Indizes. So stoße ich auf ein ähnlich gutes Ergebnis: Wir müssen also gar nicht einmal die künstliche neuronale Intelligenz bemühen. Eine Vielzahl von Entscheidungsbäumen, der „Zufallswald“, führt ebenfalls zum Ziel.

Gleichzeitig hilft’s aber auch nichts, denn unsere Frage lautet: welche Indizes („feature selection„) sagen denn die Regierungsform am besten vorher? Wenn Du ein Land regierst, dann hast Du die auch aus dem Unternehmensalltag bekannte Frage:

„Ich kann doch nicht einfach auf 116 Merkmale gleichzeitig achten. Sagt mir bitte, was wir priorisieren sollen!“

Hier sind wir eine Antwort schuldig. Ich tue folgendes – und erspare Dir die Details: Zunächst rechne ich eine ordinal-logistische Regression der Regierungsform gegen alle 116 Indizes und sortiere das Ergebnis algorithmisch nach der Größe der Koeffizienten. Mit den 20 größten starte ich eine neue logistische Regression und entferne Schritt für Schritt die Indizes mit den kleinsten Koeffizienten, wobei ich jeweils die Confusion Matrix im Blick behalte. Das dauert vertretbare 15 Minuten. Vielleicht gibt es auch eine „best-subset“ Lösung in R für die ordinal-logistische Regression. Die habe ich nicht gefunden und musste also zu Fuß ran.

Aber dann, oh Wunder: am Ende stoße ich erneut auf die gleichen drei Indizes wie auch schon beim Entscheidungsbaum. Die Genauigkeit meines so erhaltenen Modells liegt bei 96%, etwas mehr als die 94% vorher, was kein großer Gewinn und vermutlich nicht einmal signifikant ist.

Das Glas ist dennoch mehr als halb voll, denn unsere wesentliche Einsicht besteht  darin, dass wir jetzt auf zwei Wegen die gleiche Aussage gefunden haben:

Demokratien zeichnen sich vor allem durch freie und faire Wahlen aus, bei denen ein echter Wettbewerb zwischen Parteien stattfindet.

Können wir einen Regimewechsel vorhersagen?

Eine durchaus brisante Frage …

Vielleicht ist Dir die bisherige Diskussion recht abstrakt vorgekommen. Denn wir haben versucht, die Regierungsformen über einen Minimalsatz an Indizes zu definieren. Geradezu brisant erscheint jedoch folgende Frage:

Können wir einen Regimewechsel vorhersagen?

Das hätte durchaus praktische Konsequenzen: So könnten wir eine Art „Frühwarnsystem“ einrichten, über das die Vereinten Nationen, die Weltbank oder wer auch immer Länder erkennen, die es zu unterstützen gilt.

… für die wir Muster in einem „Kuddelmuddel“ erkennen müssen

Zunächst einmal wollen wir Regimewechsel überhaupt sichtbar machen. Dafür bilden wir einen neuen Arbeitsdatensatz, fügen eine Spalte ein mit dem Regime-Status des Vorjahres („lag“) und betrachten lediglich die Änderungen:

wd <- t %>% 
      select(ID_country_name, 
             ID_year, 
             regime_status_name, 
             democratic_performance_name)

wd$Lag <- lag(wd$regime_status_name)

# Hier wechselt ein Land. Das wollen wir ausschließen:
wd$Lag[wd$ID_country_name != lag(wd$ID_country_name)] <- NA

wd$change <- ifelse(
               wd$regime_status_name == wd$Lag,
               "Stable",
               paste(wd$Lag, 
                     wd$regime_status_name,
                     sep = " to "))

ggplot(data = wd %>% 
              filter(change != "Stable"), 
       aes(x = ID_year, 
       fill = change)) +
       geom_bar()

Anzahl der Regimeänderungen im Laufe der Zeit.

Solche Graphiken findest Du im Unternehmensalltag häufig. Von „Data Journalists“ – diesen Beruf gibt es – wirst Du das nicht finden und ich zeige dieses Ergebnis hier als abschreckendes Beispiel:

Siehst Du auch, was ich hier sehe?

Nichts! Solche Graphiken gehören nicht gezeigt. Um Aussagen zu treffen, müssen wir die Daten besser aufbereiten.

Regimewechsel häufen sich zu bestimmten Zeiten

Wir fragen deshalb präziser: gibt es Phasen, in denen sich ein bestimmter Regimewechsel häuft? Das können wir sehr gut mit Regelkarten beantworten und bereiten die Daten entsprechend auf:

tab <- table(wd$ID_year, wd$change) %>% 
       as.data.frame() %>% 
       pivot_wider(names_from = Var2, 
                   values_from = Freq) 
tab$Total <- rowSums(tab[, 2:ncol(tab)])
tab <- tab[-1, ]

Aus dieser Tabelle tab können wir nun Spalte für Spalte alle Regime-Änderungen auswählen und darstellen, zum Beispiel die zweite:

library(qcc)
col <- 2 # Wir wählen 2..7 für die Regime-Änderungen
p_chart <- with(tab, 
                qcc(tab[, col] %>% pull(), 
                    tab$Total, 
                    type = "p", 
                    data.name = colnames(tab)[col],
                    labels = tab$Var1))

Regelkarte für die Rate der Änderungen „Autoritäres Regime zu Demokratie“. Anfang der 1990er Jahre sehen wir viele derartige Regimewechsel.

Wenn Du aus meiner Generation kommst, dann verstehst Du diese Graphik sofort: Ende der 1980er Jahre wehten die „Winds of Change“ über die Welt. Ein erstaunlich großer Anteil von autoritären Regimen wurde „über Nacht“ demokratisch.

Indem wir die Spaltenzahl (col = 2) in obigem Skript ändern, finden wir folgende Ergebnisse:

  • Autoritär zu Demokratie: sehr viel 1990/91; sehr wenig 2019/20/21
  • Autoritär zu Hybrid: sehr viel 1992/93 (also leicht zeitversetzt)
  • Demokratie zu autoritär: ohne Befund; stabil bei ca. 0,2% p.a.
  • Demokratie zu hybrid: ohne Befund; stabil bei ca. 0,6% p.a.
  • Hybrid zu autoritär: wenig 1988-1994; viel 2021
  • Hybrid zu Demokratie: wenig vor 1988.

Vorhersage von Regimewechseln

Für diese Aufgabe gehen wir „all in“ und setzen alle Indizes und Attribute ein, über die wir verfügen. Aus der Spalte für den Regimewechsel berechnen wir eine neue Spalte „ChangeType“ für die Regimeform im folgenden Jahr:

  • „Up“ für einen Wechsel von autoritär zu hybrid bzw. zu demokratisch und von hybrid zu demokratisch
  • „Down“ für die umgekehrte Richtung, also hybrid zu autoritär und demokratisch zu hybrid bzw. autoritär
  • „Stable“ für keine Änderung.

Über alle Länder und Jahre hinweg finden wir so bei 7107 stabilen Situationen 116 „Down“ und 193 „Up“ Änderungen, mit denen wir wieder ein Modell trainieren, um die Situation „Up“, „Down“ oder „Stable“ des Folgejahres zu berechnen. Dafür haben wir einen Arbeitsdatensatz erstellt aus allen „Up“ und „Down“ Änderungen und eine Stichprobe im Umfang von 154 (Mittelwert aus 116 und 193) der „Stable“-Situationen – denn sonst würden wir das Modell vor allem für stabile Situationen trainieren, wo wir uns jedoch für die Änderungen interessieren. So trainieren wir mit 370 Datensätzen und validieren mit 93 Datensätzen. Beide Datensätze haben 148 „feature„-Spalten.

Confusion Matrix für die Vorhersage einer Regimeänderung. Klassifizierung mit einem neuronalen Netz.

„Down“-Änderungen wurden also in 13 Fällen richtig erkannt, in 6 Fällen fälschlicherweise als „stabil“ und 3 mal sogar als „up“ vorhergesagt. „Down“ Änderungen werden demnach in ca. 60% der Fälle richtig erkannt. Ähnlich sieht es bei den stabilen Situationen aus (64%). „Up“ wurde in immerhin 86% der Fälle richtig erkannt, was statistisch mit einem P-Wert von 3% auch signifikant besser ist.

In dem Versuch, das Ergebnis zu verbessern, führt auch ein Random Forest nicht weiter: da in den Prädiktoren keine NA-Werte erlaubt sind, haben wir somit nur eine kleine Datenbasis. Ich habe auch folgendes (rechenintensive) Experiment angestellt: vielleicht spielt ja nicht nur der Status im Vorjahr eine Rolle sondern die Entwicklung über mehrere Jahre hinweg von Indizes und Attributen? Also habe ich Spalten berechnet für die Trends der jeweils letzten fünf Jahre und dabei nur statistisch signifikante Trends vermerkt. Das neuronale Netz wird dadurch unwesentlich besser: Aufwand und Nutzen stehen in keinem vertretbaren Verhältnis.

Was sagt das Modell für 2022 voraus?

Auch wenn ich über die Güte des Modells nicht glücklich bin, so können wir es dennoch verwenden, um aus dem letzten verfügbaren Stand des Jahres 2021 Vorhersagen für das Jahr 2022 zu treffen:

y2021 <- wd %>% filter(ID_year == 2021)
pred_2022 <- h2o.predict(classifier, newdata = as.h2o(y2021))

So finden wir 20 Bewegungen „up“ und 36 „down“. Die Ergebnisse möchte ich hier nicht teilen, weil ich meine Klassifikation nicht für gut genug halte, um zu zeigen, was zum Beispiel für Indien, Russland, Singapur oder die Ukraine vorhergesagt wird. Natürlich: wenn ich die Ergebnisse anschaue, dann sage ich: „Klar, das ist tatsächlich auch so gekommen“. Diese Lektion haben wir aber oben schon gelernt: Wenn wir hinterher so schlau sein wollen, dann müssen wir vorher unsere eigene Vorhersage aufschreiben

Könnten wir das Modell nicht noch verbessern?

Ja, das könnten wir bestimmt. Ich habe mir einige Regimewechsel im Democralyser angeschaut. Es scheint bestimmte Muster zu geben, die Fachleute vermutlich längst kennen. Deren Verständnis, zu Trends oder Wechselwirkungen zum Beispiel, könnte man in zusätzlichen Spalten festhalten. Oder aber man verzichtet auf gewisse Spalten und versucht es so – auch mit anderen Ansätzen, denn neuronale Netze sind auch nicht immer der Weisheit letzter Schluss. Hier fängt eben die „echte“ Arbeit an. Wie heißt es so schön bei Michael Ende:

Aber das ist eine andere Geschichte.
Und die soll ein andermal erzählt werden.

Was Du mitnehmen kannst

Am wichtigsten ist mir, dass Du einen Eindruck davon mitnimmst, wie vielfältig verschiedene Länder ihre Regierungsform gestalten und auf was es Menschen dabei ankommt. Wenn Du die fünf Hauptattribute jetzt aufzählen kannst, dann habe ich viel erreicht. Du weißt jetzt auch, dass Dir sehr gute Daten vorliegen, die Du mit dem Democralyser selbst erkunden kannst.

Mir liegt auch die Datenanalyse am Herzen und ich glaube, auch Du solltest Dich damit auseinandersetzen. Dabei geht es mir zum einen um das Coden. Zum anderen aber auch um die Verwendung von statistischen Werkzeugen und die gebotene Sorgfalt bei der graphischen Darstellung. Wie wir hier gesehen haben sind Regelkarten nicht nur im Qualitätsmanagement oder bei der Steuerung von Produktionsprozessen sinnvoll.

Du hast auch anhand eines praktischen Beispiels gesehen, dass eine hohe Modellgüte zwar wünschenswert ist – ein neuronales Netz erreicht 99,9% für die Klassifikation der Regierungsform anhand der Indizes. Wir ihm aber nicht über die Schulter schauen. Auch „feature extraction“ ist wenig anschaulich. So kommt „best subset“-Analysen eine wichtige Rolle zu.

Ich bin mir auch sicher, dass echte Experten und Expertinnen hier noch mehr herausgeholt hätten und vielleicht auch Nachlässigkeiten oder gar Fehler finden werden. In dem Fall bitte ich um Hinweise – und mache jetzt Frühstück für die Familie.

Das Ziel, möglichst CO2-effizient zu wirtschaften

„Deutschland holt viel aus seinem CO2-Ausstoß“

So lautet die Überschrift eines Artikels in der FAZ vom 26. Januar 2023. Zitiert wird eine Auswertung des Instituts für angewandte Arbeitswissenschaften (ifaa). Die Aussagen des Artikels erscheinen so wichtig, dass ich mir das selbst anschauen möchte. Dank der umfangreichen und öffentlich zugänglichen Daten der Weltbank ist das auch Dir leicht möglich. Was mir am Herzen liegt:

Lerne, öffentlich verfügbare Daten „anzuzapfen“
und zu nutzen.

Wenn Du bei Fridays for Future bist, dann werden Leute Deine Aussagen in Frage stellen. Und Du kannst anderleuts Behauptungen überprüfen.

Und wenn Du in der Planungsabteilung Deines Unternehmens sitzt, dann kannst Du, gerade über die Daten der Weltbank, spannende und wichtige Einsichten gewinnen.

Es lohnt sich also. Aber genug gepredigt. Los geht’s.

Wir beschaffen uns die Daten

Es gibt die Möglichkeit, die Weltbank-Daten zu sehr vielen Kennzahlen jeweils einzeln als csv- oder Excel-Datei herunterzuladen und dann „zusammenzukopieren“. Dazu gehst Du auf den jeweiligen Index. Wenn Du allerdings mehrere Indizes miteinander in Beziehung setzen willst, dann ist das mühsam und nicht zuletzt auch fehleranfällig. Wir schreiben uns deshalb eine Routine in R:

# Zugang zu allen Daten der Weltbank
library(WDI)

# Indizes, die uns hier interessieren:
indicators <-  
    c("EN.ATM.CO2E.PC", 
      "EN.ATM.CO2E.KT", 
      "NY.GDP.MKTP.CD",
      "NY.GDP.PCAP.PP.CD", 
      "NY.GDP.MKTP.PP.CD", 
      "SP.POP.TOTL")

# Indizes laden:
indicatortable <- WDI(indicator = indicators,
                      extra = TRUE)

Das war’s!

Wenn Du Deine Daten bequem herunterladen möchtest, dann brauchst Du nur diese wenigen Zeilen soweit zu verstehen, dass Du sie für Deine Zwecke anpassen kannst. Die Daten der Tabelle indicatortable kannst Du auch in eine csv-Datei schreiben und von dort aus mit der Software Deiner Wahl weiter arbeiten. Wir halten fest:

Mit drei Befehlen hast Du Zugriff auf sämtliche Weltbankdaten.

Die Datensind je Land und Jahr abgelegt. Das vorhergehende Skript lädt folgende Indizes herunter (hier mit der Original-Bezeichnungen der Weltbank):

  • CO2 emissions (metric tons per capita)
  • CO2 emissions (kt)
  • GDP (current US$)
  • GDP per capita, PPP (current international $)
  • GDP, PPP (current international $)
  • Population, total.

Datenaufbereitung

Mit meiner Abfrage erhalte ich eine indicatortable im Umfang von 16492 Zeilen und 18 Spalten für Daten der Jahre von 1960 bis 2021. Diese gilt es nun zu „säubern“, denn es fehlen einige Einträge. Ich zähle diese „missing values“ und stelle fest, dass für die Jahre 2020 und 2021 die Daten mancher Länder noch nicht vorliegen. Auch im Jahr 2019 liegen manche Einträge von Ländern mit insgesamt ca. 2% der Weltbevölkerung ebenfalls nur unvollständig vor. Die Details erspare ich Dir hier. Diese Länder nehme ich jedenfalls aus meinen weiteren Betrachtungen heraus. Letztlich läuft meine Datenaufbereitung also auf folgende Zeilen hinaus. Ich füge dabei auch die „CO2-Effizienz“ der Volkswirtschaften als neue Spalten an:

y2019 <- indicatortable %>% 
         filter(year == 2019)
y2019 <- y2019[complete.cases(y2019), ]

# Wir berechnen die Wirtschaftsleistung je Tonne CO2.
# In Kaufkraftparität (PPP) und in aktuellem Dollar (CD):
y2019 <- y2019 %>% 
  mutate(GDP.PP.per.CO2E.T = 
           y2019$NY.GDP.MKTP.PP.CD/y2019$EN.ATM.CO2E.KT/1000,  # PPP
         GDP.CD.per.CO2E.T = 
           y2019$NY.GDP.MKTP.CD/y2019$EN.ATM.CO2E.KT/1000)     # CD

Anders als der Artikel in der FAZ möchte ich die Wirtschaftsleistung (gemessen über das Bruttosozialprodukt) auch kaufkraftparitätisch betrachten können. Das erlaubt die Frage, wie gut eine Volkswirtschaft ihre CO2-Emissionen mit Blick auf die Kaufkraft der eigenen Bevölkerung einsetzt.

Die größten CO2-Emittenten im Jahr 2019

Wir sortieren nun die Tabelle y2019 nun nach den CO2-Emissionen, wählen die ersten 10 Länder aus und fügen eine Zeile an mit der Summe aller anderen Länder. So entsteht folgende Graphik:

Im Vergleich zu der im FAZ-Artikel weist diese Graphik kleine Unterschiede auf – vermutlich, weil dem ifaa aktuellere und deshalb andere Daten vorliegen. Die Aussagen des Artikels kann ich jedoch reproduzieren:

  • Allein China ist für ca. 30% der weltweiten CO2-Emissionen verantwortlich
  • Die zehn größten Emittenten weltweit tragen über 70% bei
  • Die deutschen Emissionen schlagen mit ca. 2% zu Buche.

Größte Emittenten, nach CO2-Emissionen pro Kopf

Nun wirst Du zurecht sagen, dass in China viele Menschen leben. Kein Wunder sozusagen, das Monaco in dieser Liste nicht auftaucht. So gesehen stößt Du tatsächlich auf Länder mit sehr hohen pro-Kopf-Emissionen. Die entsprechende Übersicht kannst Du Dir bei Interesse leicht selbst erstellen. Ich möchte meine Untersuchung auf die größten 30 Emittenten beschränken. Dafür verwende ich folgenden Code:

plotdat <- y2019 %>% 
   arrange(desc(EN.ATM.CO2E.KT)) %>% 
   slice(1:30) %>% 
   arrange(desc(EN.ATM.CO2E.PC))

ggplot(data = plotdat, 
       aes(x = EN.ATM.CO2E.PC, y = country)) +
  geom_bar(stat = "identity")

In diesem „Snippet“ siehst Du lediglich die wesentlichen Zeilen: wir sortieren zunächst absteigend nach den CO2-Emissionen, entnehmen dann die ersten 30 Einträge und sortieren diese nach den CO2-Emissionen pro Kopf. Diese Ergebnisse werden in einem Balkendiagramm zusammengetragen. Zur „Verschönerung“ habe ich noch einige Formatierungsanweisungen hinzugefügt. Ein aussagekräftige Graphik erhältst Du aber auch schon mit den obigen Zeilen.

Wir sehen große Diskrepanzen zwischen den Ländern. So emittiert zum Beispiel Indien, das immerhin auf Platz drei der weltweiten Emissionen liegt, pro Kopf der Bevölkerung 1,8 Tonnen CO2. Für die Vereinigten Arabischen Emirate hingegen liegt der Wert mehr als zehn mal so hoch.

„Klimaeffizienz“ der Wirtschaft

Es liegt deshalb nahe, die CO2-Emissionen nicht nur auf die Bevölkerungszahl sondern auch auf die Wirtschaftsleistung zu beziehen. Der Ansatz des ifaa besteht nun darin, das Bruttosozialprodukt durch die CO2-Emissionen zu teilen. Das ermöglicht eine Aussage darüber, welche Wirtschaftsleistung je eingesetzte Tonne CO2 erbracht wurde.

Wir sortieren dafür zunächst alle Länder nach dieser „Klimaeffizienz“ und greifen die ersten 30 Einträge heraus. Die Skriptzeilen sehen analog zu denen oben aus und ich lasse sie deshalb hier weg. So erhalten wir folgende Graphik:

Das Ergebnis ist bedrückend: die Demokratische Republik Kongo hat sich bestimmt nicht „absichtlich“ so aufgestellt, dass wenig CO2 eingesetzt wird, um ihr Bruttosozialprodukt zu erwirtschaften. In Anlehnung an den Artikel aus der FAZ wiederhole ich deshalb diese Betrachtung für die 10 größten Emittenten (siehe oben). Hierfür passe ich die oben gezeigten Skriptzeilen an und erhalten folgende Graphik:

Wir finden hier eine Kernaussage aus dem FAZ-Artikel (die Rangfolge und die Werte hier unterscheiden sich dabei aus genannten Gründen leicht von denen des FAZ-Artikels):

Unter den zehn größten CO2-Emittenten produziert die deutsche Wirtschaft das höchste Bruttosozialprodukt je eingesetzte Tonne CO2.

Diese Aussage hängt allerdings auch davon ab, wie viele der größten Emittenten ausgewählt werden. Solange wir die größten 16 oder weniger wählen steht Deutschland tatsächlich an der Spitze. Das Bild sieht jedoch anders aus, wenn man die ersten 20 betrachtet:

Nun rückt Frankreich auf Platz 1, dank des Einsatzes von Atomkraft, und Deutschland liegt abgeschlagen auf Platz 4 hinter dem Vereinigten Königreich und Italien.

Du erkennst eine Tatsache, die im Unternehmensalltag hinreichend bekannt ist – und hoffentlich entsprechend berücksichtigt wird:

Beim Vergleich von Ländern, Geschäftseinheiten und vor allem von Menschen anhand von Kennzahlen ist große Vorsicht geboten.

Kaufkraftparitätische Klimaeffizienz

So vorsichtig geworden könntest Du nun auch sagen:

„Warte mal: Man darf doch nicht all diese Wirtschaften über den gleichen Kamm scheren!“

Und das ist richtig: Ein Dollar in Indien hat eine andere Kaufkraft als ein Dollar in den USA. Wir wiederholen also die vorherige Auswertung für die 10 größten Emittenten mit Blick auf das kaufkraftparitätische Bruttosozialprodukt:

Deutschland bleibt hier auf Platz 1, gefolgt nun allerdings von Indonesien. Japan und die USA rücken jeweils um einen Platz nach hinten und Indien schließt um drei Plätze nach vorne auf.

Meine Botschaft für Dich

  1. „Daten sind das neue Öl“ heißt es. Das stimmt nicht ganz, denn Öl gibt es nicht umsonst. Daten dagegen sind häufig frei verfügbar oder zumindest „günstig zu haben“: Im Internet oder in Deinem Unternehmen. Diese „freie Ressource“ nicht zu nutzen ist zunehmend nicht nur schade sondern, je nach Deiner Rolle, fast schon „sträflich“.
  2. Bekannt ist auch der Spruch: „Glaube keiner Statistik, die du nicht selbst gefälscht hast“. Das ist sarkastisch und letztlich schädlich, denn Du würdest Deine Augen vor wichtigen Erkenntnissen verschließen. Entscheidend ist vielmehr, dass Du selbst mit den Daten „spielen“ und die „Stabilität“ von Aussagen überprüfen kannst. So wie die Auswahl der 10 oder 20 größten CO2-Emittenten oben.
  3. Du hast hier auch ein Beispiel gesehen, welchen Einfluss Du mit Daten gewinnen kannst. Mit Graphiken kannst Du Deinen Daten Einsichten entlocken und so wichtige und manchmal überraschende Botschaften vermitteln. Du kannst auch anderleuts Botschaften relativieren oder in einen größeren Zusammenhang stellen.
  4. Die Zeiten von „Excel & Co“ sind meiner Ansicht nach vorbei. Für die Datengewinnung, -aufbereitung und -darstellung brauchst Du, behaupte ich, zunehmend Skripte. Sonst kommst Du einfach nicht mehr hinterher. Deine Produktivität bleibt niedrig, da Du alles „per Hand“ manchen musst. Das macht Deine Auswertungen fehleranfälliger. An manche Daten kommst Du zudem ohne Skript auch nur schwer heran. Daten kommen auch in vielen Strukturen daher. Skripte sind flexibel. Lerne also R oder Python.
  5. Das ist kein Hexenwerk. Siehe die Beispiele oben. Natürlich steckt der Teufel im Detail. Aber für das Debugging gibt es zunehmend richtig gute Hilfe. Ich verwende inzwischen fast ausschließlich ChatGPT. Stackoverflow tritt in den Hintergrund. Und das ist nur der Anfang einer langen, vermutlich wirklich langen Geschichte…

Ich habe übrigens versucht, mein R-Skript in die „Medienbibliothek“ einzubinden, sodass ich es Dir hier zur Verfügung stellen kann. Aus Sicherheitsgründen verhindert WordPress das jedoch: kennen die die Extension .R nicht? Wie auch immer: wenn Du das Skript haben möchtest, dann schreibe mich einfach über LinkedIn an. Meinen Kontakt findest Du auch mit einer einfache Internetsuche. Da ich meinen Spamfilter nicht ständig neu trainieren möchte, will ich hier meine Emailadresse nicht den neugierigen Augen der Crawler preisgeben.

Den tägliche Verbrauch an Gas und Strom visualisieren

In dem vorherigen Blog hatten wir Daten gesammelt, die in jedem Haushalt, der über einen Gas- und Stromanschluss verfügt, vorhanden sind: Datum, Uhrzeit, Stand Gaszähler, Stand Stromzähler. Der dazugehörige Zettel hängt bei uns am Kühlschrank und wer auch immer daran denkt und Zeit hat, fügt eine neue Zeile ein.

Nun sollen diese Zahlenkolonnen umgerechnet werden in den täglichen Verbrauch und der soll wiederum verglichen werden mit dem langjährigen Verbrauchsmittel, den uns die Energieversorger mit der Abrechnung zur Verfügung stellen.

Die Datenerfassung soll zumutbar bleiben

Dabei ergibt sich nun folgendes Problem: eigentlich sollte man täglich immer zur gleichen Uhrzeit ablesen, um so aus den Unterschieden der Zählerstände den jeweiligen Verbrauch ermitteln zu können. Das ist jedoch einer, zumindest unserer, Familie, nicht zumutbar.

Ein Algorithmus muss her

Dafür definieren wir eine Funktion die erlaubt, die Daten über eine gewisse Anzahl von Tagen, zum Beispiel über eine Woche also sieben Tage, zu glätten. Für eine Zeitspanne von einer Woche und den heutigen 13. November um 18:30 würde diese Funktion also alle Werte auswählen, die nach dem 6. November, ebenfalls um 18:30, erhoben wurden. Mithilfe dieser Daten führen wir eine Regressionsanalyse durch.

In R ist diese Funktion schnell erstellt. Andere mögen sie eleganter und ohne Schleife erstellen. Hinter den #-Zeichen füge ich Kommentare ein:

Verbrauch <- function(tab, days) {
  
  #tab[1, ]: Datum und Uhrzeit
  #tab[2, ]: Werte
  
  res <- tab
  res$Per24h <- NA
  res$R2 <- NA
  res$N <- NA
  
  for (i in 3:nrow(res)) {
    
    von <- tab[i, 1]$DatumUhrzeit - days*24*3600
    subset <- tab[1:i, ] %>% filter(DatumUhrzeit > von)
    colnames(subset)[2] <- "Werte"
    
    # Wir fangen noch einen Fehler ab:
    if(nrow(subset) > 2) {
      model <- lm(Werte ~ DatumUhrzeit, data = subset)
      res$Per24h[i] <- summary(model)$coefficients[2,1]*24*3600
      res$R2[i] <- summary(model)$r.squared
      res$N[i] <- nrow(subset)
    }
    
  }
  
  return(res)
  
  #res[1, ]: Datum und Uhrzeit
  #res[2, ]: Werte
  #res[3, ]: Verbrauch je 24h
  #res[4, ]: Regressionskoeffizient R^2
  #res[5, ]. Für die jeweilige Regression verwendete Anzahl von Werten
  
}

Dank dieser Funktion lässt sich das über eine Woche gemittelte Ergebnis für den Gasverbrauch wie folgt aus den Rohdaten der Tabelle t ermitteln:

days <- 7
tab <- t %>% select(DatumUhrzeit, StromverbrauchkWh)
res <- Verbrauch(tab, days)

So ergibt sich folgende Übersicht:

Wir sehen also, dass für den berechneten (über sieben Tage gemittelten) Durchschnittsverbrauch je 24 Stunden (oben) jeweils zumindest vier Datenpunkte zur Verfügung gestanden sind (unten). Bis auf den Anfang unserer Datenerhebung haben wir auch eine Güte R^2 der Regressionsanalyse von über 90% (Mitte). Diese Übersicht erzeugen wir ab jetzt zur Datenkontrolle. Solange dort keine Auffälligkeiten entstehen, werden die folgenden Graphiken im Familienrat betrachtet:

Bis ca. zum 20 Oktober sind die Gaswerte nicht zuverlässig (geringe Güte R^2). Wir haben da die Heizung auf Herbstbetrieb um- und dann für einige Tage bei schönem Wetter vollständig ausgestellt.

Wir können ab jetzt – fleißige Datenerhebung und -übertragung in ein Excelblatt vorausgesetzt – „per Knopfdruck“ (in R) unseren Verbrauch visualisieren. Unser derzeitige Schluss lautet: gar nicht so schlecht! Wir verbrauchen jeweils ca. 7 kWh Strom und Gas pro Tag.

 

 

Energie sparen heißt zunächst einmal, den Energieverbrauch zu messen

Sparen ist angesagt

Seit Monaten wird darüber gesprochen, dass im jetzt kommenden Winter ein Energieproblem auf Deutschland zukommen wird oder kann – je nach dem, was man als „Problem“ betrachtet und wem man zuhört. Es scheint eine relativ einhellige Meinung darüber zu bestehen, dass wir unseren Energieverbrauch um ca. 20% reduzieren müssen, um das Risiko eines Blackouts zu reduzieren.

Wo steht mein Haushalt eigentlich?

Ein Blick in unsere Strom- und Gasabrechnungen der letzten Jahre zeigt, dass unser drei-Personen-Haushalt im Mittel der letzten Jahre pro Jahr

  • ca. 10.000 kWh Gas und
  • ca. 2.500 kWh Strom

verbraucht hat. Laut unserem Anbieter scheinen wir damit deutlich unter dem Durchschnitt zu liegen.

Messen einfach gemacht: Strom- und Gaszähler

Gerade für Strom gibt es allerhand Messgeräte, die man direkt vor den Verbraucher, z.B. den Fernseher, schalten und so die vom Gerät entnommene Leistung messen kann. Aber wie machen wir das für die Mikrowelle oder den E-Herd (den wir kaum benutzen)? Lohnt es sich also, so ein Gerät anschaffen? Und warum für Strom, wenn es für Gas nichts vergleichbares zu geben scheint (für den individuellen Verbrauch von Gasherd, -heizung und für Warmwasser)?

Wir haben deshalb beschlossen, einfach direkt an Strom- und Gaszähler abzulesen. Der Nachteil liegt auf der Hand: Rückschlüsse auf einzelne Verbraucher sind nicht ohne weiteres zu haben. Wieviel verbraucht zum Beispiel mein Computer im Laufe von 24 Stunden, wenn ich ihn nachts nicht ausschalte? Gleichzeitig können wir beliebig lange – und auch beliebig genaue Zeitreihen erfassen. Die sehen dann wie folgt aus:

Wir erfassen also

  • das Datum
  • die Uhrzeit
  • den Zählerstand Strom in Kilowatt-Stunden
  • den Zählerstand Gas in Kubikmeter und
  • „Bemerkungen“.

Dank der „Bemerkungen“ können wir – zumindest im Prinzip und falls wir „fleißig genug“ sind – zum Beispiel den Verbrauch der Waschmaschine erfassen, indem wir jeweils vor- und einem Waschgang den Strom ablesen.

Der Gaszähler zeigt Kubikmeter an – wir bezahlen aber Kilowattstunden!

Wenn man einmal anfängt, den Dingen auf den Grund zu gehen, dann erlebt man Überraschung: ablesen können wir am Gaszähler die Kubikmeter, wir bezahlen aber Kilowattstunden. Was die Umrechnung angeht, da vertrauen wir also dem Gaslieferanten (und dem zuständigen Eichamt).

In unserer Gasrechnung findet sich dazu eine sparsame Erklärung: der „Brennwert“, also wieviel Energie das Gas je Kubikmeter enthält, hängt von der Zusammensetzung des Gases ab. Im Internet erfahre ich, dass es auch eine „Zustandszahl“ gibt, die Temperatur und Druck berücksichtigt. Nun wird die Temperatur im Winter vermutlich geringer sein als im Sommer und der Kubikmeter Gas enthält dann auch mehr Energie. Welche Werte für welchen Zeitraum unserer Abrechnung zugrunde gelegt werden, darüber schweigt sich unsere Abrechnung aus. Im Internet finden sich einige interessante Referenzen, zum Beispiel auch diese hier. Man könne, so heißt es dort, den Abrechnungsbrennwert „regelmäßig“ beim Gaslieferanten erfragen.

Ein Anruf dort stößt tatsächlich auf Verständnis: „Ich finde gut, dass Sie nachfragen.“ Für unseren Wohnort wird uns ein Brennwert von 10,5 – 10,6 genannt und eine Zustandszahl von 0,976. Also rechne ich wie folgt um:

Verbrauchte Energie [kWh] = 10,6 * 0,976 * Verbrauchtes Gas [m^3]

Wir wollen unsere Freiheiten bei der Datenerfassung und -auswertung

Der Teufel steckt bekanntlich im Detail.
Das wird nach den ersten Tagen schon  klar.

Ich habe unsere Daten in ein Excelblatt übertragen und möchte sie auswerten. Zur Analyse würde man sich wünschen, dass die Werte regelmäßig, zum Beispiel täglich um 08:00 Uhr, erfasst werden. So könnte man dann den Verbrauch innerhalb von 24 Stunden bestimmen und vergleichen. Diese Disziplin bringen wir als Familie jedoch nicht auf. Bei uns liegt vielmehr der oben abgebildete Zettel in der Küche und wer auch immer möchte kann kurz in den Hauswirtschaftsraum herübergehen und eine neue Zeile eintragen.

Ich habe deshalb beschlossen, die Daten stattdessen mit einem R-Skript auszuwerten. Da ich noch nicht genau weiß, welche Auswertungen ich im Laufe der Zeit erstellen möchte, bleibe ich so flexibel. Das Skript kann zudem im Laufe der Zeit in einen Markdown-Report übertragen werden und so würden dann alle Auswertungen „per Knopfdruck“ zur Verfügung stehen. Das Excel-Blatt dient dabei lediglich als „Datenbank“. Das Programm Power-BI wäre dazu eine mögliche Alternative.

Erste Auswertung: einfacher Zeitverlauf

Mein Skript liest zunächst die Rohdaten aus dem Excelblatt ein und ich überführe die Daten in eine „aufgeräumte Struktur“, sodass jeweils eine Spalte entsteht für:

  • Datum und Uhrzeit
  • Energieverbrauch in kWh
  • Energieform (Gas oder Strom).

Dafür werden die Spalten jeweils „gestapelt“. Unter Verwendung des ggplot-Pakets in R lässt sich so mit folgenden Befehlszeilen (Formatierungsanweisungen habe ich der Einfachheit halber herausgenommen)

ggplot(data = plotdat, 
       aes(x = Datum, 
           y = kWh, 
           colour = Energie)) + 
geom_line()

diese Graphik erstellen:

Im betrachteten Zeitraum erkennen wir zunächst einen ziemlich gleichmäßigen Verbrauch. Im Jahr 2022 war der Oktober sehr warm und wir haben bis Ende Oktober nicht (mit Gas) geheizt: tagsüber scheint die Sonne herein, abends ziehen wir die Vorhänge zu, um die Wärme im Haus zu behalten. Dank guter Isolierung hat das bisher gereicht. Ein Vergleich zu später wird also interessant werden.

Ganz zu Beginn unserer Messungen steht ein Experiment: wir haben für einige Tage das Gas vollständig aus- und nur dann kurz wieder eingeschaltet, wenn das Duschwasser zu kalt geworden ist. Das Ergebnis ist anhand des bis zum 18. Oktober deutlich flacheren Verlaufs des Gasverbrauchs zu erkennen.

Der durchschnittliche Verbrauch lässt sich nun über eine Regressionsanalyse ermitteln:

model <- lm(StromverbrauchkWh ~ DatumUhrzeit, data = t)
summary(model)

So ergibt sich, dass (R-Quadrat) 99,9% der beobachteten Variation im Stromverbrauch mit dem Fortschreiten der Zeit zusammenhängen und nur 0,1% mit „Spezialeffekten“, wenn wir die Waschmaschine, einen Laubpuster oder den Trockner (kurz) laufen lassen. Der durchschnittliche tägliche Verbrauch lässt sich anhand der Steigung ermitteln. Wir erhalten:

  • Gas: 4,9 kWh/24h (R^2 = 99,1%)
  • Strom: 6,9 kWh/24h (R^2 = 99,9%)

Mit Blick auf das nun angekündigte kühlere Wetter – und wir haben heute die Heizung von „Schutzbetrieb“ auf „Eco“ umgeschaltet – liegt jedoch folgender Wunsch nahe: Wir wollen diese Regressionsanalyse nicht einfach nur über den gesamten Betrachtungszeitraum durchführen. Das wäre ohne weiteres auch in Excel möglich. Vielmehr möchten wir in der Lage sein, über ein wählbares Zeitfenster, zum Beispiel über 7 Tage hinweg, solch eine Regression durchzuführen, um die dadurch entstehende Zeitreihe untersuchen zu können. Schwankungen im durchschnittlichen Verbrauch sollten so erkennbar sein.

Bei diesem – relativ einfachen – Wunsch steigen meinem Kenntnisstand nach jedoch Excel, Power-BI und jegliche „Klick-Software“ aus – es sei denn, man erstellt ein Skript. Genau das tun wir von Anfang an in R.

Das Ergebnis wollen wir uns beim nächsten Mal anschauen.