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.

Wie steht es eigentlich um die Demokratie in der Welt?

Dieser Blog ist seit fast zwei Jahren verwaist – was schade ist. Seit dem letzten Eintrag ist viel geschehen. Einen Wendepunkt stellt der 24. Februar 2022 dar. Auch in meinem Leben haben sich so neue Schwerpunkte ergeben.

Wir haben nicht aufgepasst

„Als Menschheit“ haben wir manches verschlafen. Viele Länder haben die Erfahrung gemacht, was passiert, wenn ein Volk über Jahre hinweg einer Propaganda ausgesetzt wird und unabhängige Stimmen eine nach der anderen mundtot gemacht werden.

Nun ist die freie Meinungsäußerung sicher nur ein Aspekt unter vielen, auf die es zu achten gilt. Bei meiner Suche bin ich auf die hervorragende Webseite State of Democracy und auf eine über sie veröffentlichte Datenbank bei The Global State of Democracy | International IDEA gestoßen (siehe dort: Data & Tools):

„Diese Daten müssen allen Menschen zur Verfügung stehen!“

Zu 160+ Ländern liegen dort Daten von den Jahren 1975 bis heute vor und dies zu 116 „Indizes“, die z.T. in 8 „sub-sub-Attribute“, in 16 „sub-Attribute“ und 5 „Hauptattribute“ aggregiert werden. „Nichts für mich“, werden Sie sich vielleicht sagen, „da muss eine Statistikerin ran“. So bleibt dann dieser Fundus an Daten den wenigen Statistikern vorbehalten, die ihnen Einsichten entlocken können. Es entsteht ein Flaschenhals – und etwas fundamental undemokratisches. Denn der größte Teil der Menschheit bleibt somit ausgeschlossen.

Alle Länder sollten „unter Beobachtung“ stehen

Das ist ein großer Verlust. Denn zum einen sollten wir alle auf unser eigenes Land, auf Nachbarländer und überhaupt „auf die Welt“ aufpassen. Und das ist nur möglich, wenn wir eine Art „Dashboard“ haben, das uns hilft, Entwicklungen schnell zu erkennen.

Zum anderen: wenn wir über „Demokratie“ sprechen, dann tun wir das häufig im Sinne der „Mechanik“: Wahlen, Gewaltenteilung usw. „State of Democracy“ betrachtet Demokratie stattdessen aus „Kundensicht“: was erwarten sich Menschen von ihrem Staat und was können sie erwarten?

Es geht um 5 Aspekte:

  • Fundamentale Rechte
  • Überprüfung der Regierung
  • Eine unparteiische Verwaltung
  • Einbindung der Bevölkerung und
  • Eine repräsentative Regierung.

Nun fragen Sie völlig zu recht, was mit dem Attribut „fundamentale Rechten“ gemeint sein könnte. Hier geht es wieder um drei wesentliche sub-Attribute:

  • Zugang zur Justiz
  • Bürgerliche Freiheiten
  • Soziale Rechte und Gleichheit.

Auch hier werden Sie fragen, was „bürgerliche Freiheiten“ wohl sind. Laut „State of Democracy“ bestehen diese aus den folgenden „sub-sub-Attributen“:

  • Die freie Meinungsäußerung
  • Die Vereinigungs- und Versammlungsfreiheit
  • Die Freiheit der Religion
  • Die Bewegungsfreiheit und um
  • Persönliche Integrität und Sicherheit.

Allein die freie Meinungsäußerung wird über 8 Indizes gemessen.

Wir können selbstverständlich unterschiedlicher Ansicht sein, ob die freie Meinungsäußerung wohl uneingeschränkt gelten sollte. Bei uns in Deutschland ist zum Beispiel die Leugnung des Holocaust strafbewehrt. Auch gibt es verschiedene Ansichten zum Attribute der Einbindung der Bevölkerung, die neben drei anderen auch über das sub-Attribut „direkte Demokratie“ beschrieben wird: birgt die direkte Demokratie nicht auch populistische und andere Gefahren?

Was „gut“ oder „richtig“ ist wird also kontrovers diskutiert und die demokratische Republik Kongo mag andere Antworten finden als Andorra. Die vorliegenden Daten, erstellt mit einer mir ansonsten unbekannten Sorgfalt (siehe das „Codebook„), können für diese Gespräche eine wichtige Grundlage liefern.

Daraus ergibt sich für mich die nahezu zwingende Vision:

Diese Daten müssen so einfach aufbereitet werden,
dass jedes Schulkind sie verstehen kann!

In den letzten Wochen habe ich damit angefangen.
Die ersten Ergebnisse sind in den folgenden Berichten zusammengefasst:

Es fehlen noch einige Werkzeuge wie Weltkarten, die mithilfe eines Attributs oder eines Index eingefärbt werden. Das ist „Standard“ und kann bei Gelegenheit entstehen. Wie aber kann man 145 „Key Performance Indicators“ und die Zusammenhänge zwischen ihnen so darstellen, dass „jedes Kind“ sie erfassen kann?

Hier hilft das „Blumen-Diagramm“, eine Entwicklung der letzten Tage:

Wenn alles ausgereift ist, dann werden diese Werkzeuge in einer interaktiven „App“ zusammengebaut, die jetzt schon als „halbfunktionaler“ Prototyp verfügbar ist:

Der Democratizer

Falls meine Freunde aus USA dies lesen: wenn es Euch lieber ist, dann könnt Ihr diese App auch gerne als „Republicanizer“ interpretieren. Es geht nicht um die eine oder um die andere Partei. Und falls Sie diesen Beitrag in Cuba oder Venezuela lesen: es geht darum, den Zugang zu diesen Daten zu „sozialisieren“, sie also allen zugänglich zu machen. „Das Volk“ (griechisch Demos) soll die Verfügungsgewalt (griechisch kratein = herrschen) über die aus diesen Daten gewonnenen Einsichten haben.

Um was es hier geht

Natürlich ist es für einen Datenwissenschaftler spannend, große Datensätze wie den vorliegenden visuell aufzubereiten und ihnen Einsichten zu entlocken. Der „Democratizer“ stellt jedoch lediglich eine Produktinnovation dar. Wichtiger sind die Prozesse und Dienstleistungen, die sich mit dieser oder mit vergleichbaren, Transparenz schaffenden Apps denken lassen.

Soviel jetzt schon: ich bin überzeugt, dass es sich hier um Aufgaben einer Generation handelt, die auf einer Stufe stehen mit Aufgaben wie der Umstellung auf erneuerbare Energien oder der Säuberung der Ozeane. Wir müssen es angehen. Viel ist schon unterwegs. Es geht mir darum, „den richtigen Aschluss“ zu finden. Mehr dazu dann später.

Does Corona have an impact on climate?

In 2017 (data from Wikipedia) humanity emitted about 37 giga-tons of fossil CO2, much of it linked to economic activity. Corona has significantly slowed things down. How big of an impact does that have on the atmosphere?

The answer to this question helps gage the measures necessary to tackle climate change. I am certainly not the right guy for that discussion but towards the end of this contribution, you find a few thoughts.

Since 1958, the Mauna Loa Observatory measures the atmospheric CO2 concentration on a weekly basis and makes the data publicly available. The overall trend is well-known:

Interestingly, as the plot shows, the CO2-concentration undergoes seasonal oscillations: The Northern land-mass is larger than the Southern which is why, during Siberian spring and summer, CO2 is absorbed from the atmosphere and emitted again during autumn and winter.

The tricky part in our question consists in finding the „Corona-signal“ amongst this variation. The basic idea is to model the above signal for the before-Corona times, predict its further evolution and compare the outcome to what really happened.

We start with a polynomial approximation and find that for times after 1995 a second-order polynom will do. We are then left with modelling the annual cycles:

To a climate newby like myself, these cycles are impressive: at a weight of the atmosphere of 5×1018 kg, a variation of 6ppm summer to winter corresponds to about 100 Gigatons CO2 that planet Earth „breathes in and out“. That is about 3x what humanity emits in fossil CO2 per year.

The challenge we are left with is understanding the „Corona-signal“ in these oscillations:

To that purpose, we use the Fast Fourier Transformation (FFT, see betterexplained.com) and get inspiration from Joao Neto’s tutorial on how to do that in R. Here we are not only interested in finding the amplitude of the oscillation but also need the phase-information. Just in case you plan to do that, here are a few tips:

  • Interpolate missing values before the analysis
  • To reduce artifacts, use time-windows of entire years for the FFT
  • Refine your algorithm with a known signal, then approach unknown signals.

What turns out to be hard to model in the annual CO2 cycles is the phase-information. Taking longer periods in time leads to significant phase-shifts on the edges. That is a pity because it is the upper edge we are interested in. Here I use the data between Jan 30 2010, and Jan 30 2020 by when the WHO declared COVID-19 a „public health emergency of international concern“.

In blue we see what happened, in green the model and in red the long-term trend based on a polynomial approximation. For the oscillation, I have used only the two frequencies with the strongest amplitudes. Overall the result looks promising but the devil sits in the details:

With the 2019-cycle we see the overall difficulty to model the phase shift. And yes, many blue dots (what happened) in 2020 are below the green curve (expected behavior without „Corona-effect“). Well,…

…we need to investigate better the residuals (differences between blue and green):

The average of -0.116 ppm is not significantly different from zero („Corona times are no different from what is expected without Corona“), given the overall variation in the residuals. One could argue that it took the world economy some time to settle into „Corona operations“ and that it equally took the planet some time to stirr the atmosphere enough for a lower CO2 concentration to reach remote Hawaii. When we take out of the analysis the two data points from February 1 and 8 (shown in italic), we get an average for the remaining residuals of -0.22 ppm, but this still with a likelihood („P-value“) of 10% that the true average is zero.

In other words:
With our somewhat crude analysis and for a relatively short time of observation, we only find a 90% chance for anything like a „Corona effect“ on the global CO2 concentration.  

Most people would wish to be at least 95% certain – and more is definitely better here and elsewhere. We knew things were going to be tricky. For my own business as a consultant, I am still happy to now have algorithms that help me study seasonality in my clients‘ demand data, for example. But that is not the point here.

For climate it pretty much looks like if we were in for a longer race: as the cartoonist from The Economist observed: Corona is only the preliminary round for the world to learn to fight together. After this „warm-up“, climate change then is the real thing. Taking quick shots at CO2 , even as big as a world-wide Corona shut-down, has limited impact.

With that said: the Mauna Loa data earn more thorough investigation than done here – and as quoted above, there are people doing just that. If you have an idea how to better model the data, and to tackle the phase-shift problem better than I do, maybe we can reduce the residuals between model and reality (measured when „learning“ the model with the data from before Corona). In my analysis, they stand at a standard deviation of 0.6 ppm. Lower residuals („noise“) will allow detecting smaller signals…

Ping me, if you have an idea.