Explorative Datenanalyse (EDA) - Teil 2

Andreas Warntjen

28.02.2021

Inhalt

Einleitung

In dem ersten Teil hatten wir den Datensatz des World Happiness Reports

In der Variable Democratic Quality gibt es für das Jahr 2018 fehlende Werte.

Außerdem hatten wir nur die Daten für West- und Osteuropa ausgewählt sowie den Datensatz auf einige Variablen eingeschränkt. Das Ergebnis hatten wir in einer CSV-Datei gespeichert.

In diesem Teil arbeiten wir mit den Daten für Europa weiter und betrachten einige (teilweise aggregierte) deskriptive Statistiken. Am Ende rechnen wir eine einfache OLS-Regression.

Bibliotheken laden und allgemeine Einstellungen

Neben den Bibliotheken aus Teil 1 laden wir noch matplotlib und seaborn zur Datenvisualisierung.

Daten einlesen und Überblick gewinnen

Der neue Datensatz liegt in einer CSV-Datei, die wir mit read_csv lesen können. Da die Datei aus einem Pandas-Dataframe geschrieben wurde, befindet sich in der ersten Spalte (ohne Spaltenname) der Index. Mit der Einstellung ìndex_col=0 lesen wir die erste Spalte als Index aus.

Die Anzahl "Non-Null Count" der Variablen Democratic Quality (326) ist niedriger als die Zahl der Einträge ("355 entries"). Es gibt also fehlende Werte für diese Variable. Aus dem ersten Teil wissen wir bereits, dass es sich um die Einträge für das Jahr 2018 handelt.

Die Werte der Variable Democratic Quality im Jahr 2018 fehlen alle.

Um die Struktur eines Datensatzes zu verstehen ist es - zumindest bei relativ übersichtlichen Datensätzen - hilfreich sich die ersten Zeilen anzeigen zu lassen. Die Methode head() zeigt einige Zeilen an (standardmäßig die ersten fünf). Die Zeilennummer (Index) setzen bei 71 an, weil sie von dem ursprünglichen Datensatz (mit Ländern aus aller Welt) übernommen wurden.

Wir sehen, dass es pro Land mehrere Jahre gibt. Wir können uns dies an einem Beispiel genauer angucken.

Für Österreich fehlen zwei Jahre im Datensatz (2005, 2007).

Die Methode describe() gibt standardmäßig nur für die numerischen Variablen eine Zusammenfassung. Mit der Parametereinstellung include="all" werden alle Variablen angezeigt. Für nicht-numerische Variablen wird dann die Anzahl der verschiedenen Ausprägungen (unique) und die häufigste Ausprägung (top) angegeben.

Mit value_counts() können wir die Häufigkeitsverteilung kategorischer Variablen betrachten.

Es gibt mehr Beobachtungen für Western Europe als für Eastern Europe. Wie viele Länder gibt es pro Gruppe? Mit einem Filter (boolean mask) kombiniert mit unique() können wir uns die Ländername pro Country group ausgeben lassen. Das Ergebnis ist ein Numpy array. Die Dimensionen des arrays ermittelt wir mit dem Attribut shape.

Für alle Länder gibt es mehrere Jahre und damit mehrere Beobachtungen für Subjective Wellbeing. Außerdem haben wir alle Länder einer Ländergruppe zugeordnet. Mit einem Boxplot können wir die Verteilung der Werte für Subjective Wellbeing zwischen den Ländergruppen (über alle Jahre hinweg) vergleichen.

Osteuropäische Länder haben niedrigere Werte als Länder in Westeuropa.

Auswertung pro Land (Durchschnittswerte)

Der Datensatz enthält Daten für die Jahre 2005 bis 2018 für mehrere Länder. Wenn der Vergleich zwischen den Ländern im Vordergrund steht, dann kann man die Daten auf der Ebene der Länder aggregieren. Mit der Methode groupby wird ein Datensatz gruppiert. Für einen gruppierten Datensatz können verschiedene Statistiken berechnet werden. Wie wir bereits für das Beispiel Österreich gesehen haben, sind die Daten nicht für alle Länder vollständig von 2005 bis 2018 vorhanden. Mit Hilfe von groupby und der Methode count() können wir zählen, wie viele Einträge es in der Spalte Year pro Land gibt. Um die Liste nach der Anzahl der Jahre zu sortieren nutzen wir anschließend noch sort_values(). Der Parameter ascending=False sorgt dafür, dass die Liste absteigend sortiert wird.

Die Anzahl der Jahre, für die Daten vorliegen, unterscheidet sich zwischen den Ländern. Manche haben nur Daten für 8 Jahre, andere für 13.

Um eine Analyse auf Länderebene durchzuführen, müssen wir die Werte aggregieren. Mit der Methode agg() können verschiedene Aggregationsfunktionen (min, max, mean, std) auf einen gruppierten Datensatz angewendet werden.

Wir können den Spalten mit den aggregierten Werten auch eigene Spaltennamen geben. Dazu übergeben wir agg() eine Liste mit Tuples von Spaltennamen und Funktionsnamen. Wenn anschließend über eine Spalte sortiert werden soll, dann muss der neue Spaltenname sort_values() übergeben werden.

Das Ergebnis von groupby() und einer Aggregationsfunktion ist ein DataFrame. Standardmäßig wird das Gruppierungsmerkmal (hier: Country name) genutzt, um einen Index für den neuen DataFrame zu bilden. Wenn bei der Definition der Gruppierung as_index=False gesetzt wird, ist das Gruppierungsmerkmal in dem neuen Datensatz eine Spalte.

Bi-Variate Zusammenhänge: Datenvisualisierung

pandas enthält ein paar nützliche Funktionen zur Datenvisualisierung. Wir können uns sehr einfach beispielsweise ein Streudiagramm erstellen. Wir sehen hier den Zusammenhang zwischen GDP per Capita (log) und Subjective Wellbeing.

Mit der Seaborn-Bibliothek können wir schnell einen pairplot generieren, der für alle numerischen Variablen sowohl die uni-variate Verteilung als auch den bi-variaten Zusammenhang mit allen anderen (numerischen) Variablen anzeigt.

Standardmäßig wird die uni-variate Verteilung mit Hilfe eines Histogramms dargestellt. Wir können dies jedoch ändern und etwa mit diag_kind = 'kde' eine geglättetere Darstellung wählen.

Es scheint einen linearen positiven Zusammenhang zwischen dem Bruttoinlandsprodukt pro Kopf (GDP per capita (log)) sowie der Qualität der Demokratie und dem subjektiven Wohlbefinden zu geben (Subjective Wellbeing). Außerdem scheinen die Qualität der Demokratie und das Bruttoinlandsprodukt korreliert zu sein.

Regressionsanalyse

Ein Streudiagramm mit der Regressionsgeraden verdeutlicht den Zusammenhang zwischen demokratischer Qualität und subjektiven Wohlbefinden. Wir nutzen dafür die regplot() aus seaborn.

Um mögliche Unterschiede zwischen west- und osteuropäischen Ländern zu berücksichtigen, können wir die beiden Gruppen farblich getrennt darstellen.

Die Werte für subjektives Wohlbefinden sind im Schnitt in westeuropäischen Ländern höher als in osteuropäischen Ländern. Außerdem weisen West- und Osteuropa unterschiedliche Wertebereiche für die Qualität der Demokratie auf.

Bevor wir eine Regressionsanalyse rechnen, müssen wir die Spaltennamen (die Leerzeichen enthalten) anpassen. Dazu nutzen wir die pandas Funktion rename().

Die Bibliothek statsmodels stellt eine Reihe statistische/ökonemtrischer Verfahren zur Verfügung. Für dieses einfache Beispiel belassen wir es bei einer simplen OLS-Regression mit ols() und nutzen die Eingabe per Formel. Die Ergebnisse werden per summary() ausgegeben. Im Hintergrund berücksichtigt ols(), dass es sich bei Region um eine kategoriale Variable handelt und zeigt uns den Wert für eine Dummy-Kodierung mit einer der beiden Ausprägungen.