Zwischen #AfDErfolg und Medienberichten gibt es einen kausalen Effekt - und der lässt sich berechnen
BuzzFeed Deutschland hat Daten
zusammengetragen, mit denen sich der Einfluss der Medien auf die
Umfragewerte der AfD berechnen lässt. Wir zeigen, dass es einen
statistischen Kausalzusammenhang zwischen der Häufigkeit der
Berichte über die AfD und ihren Umfragewerten gibt. Hierfür
verwenden wir Granger-Causality-Analyse. Das Ergebnis ist, dass vier
bis fünf Wochen, nachdem vermehrt über die AfD berichtet wurde auch
die Umfragewerte signifikant steigen.
Was ist in den Daten
Die Daten enthalten
vor allem eine Zeitreihe mit wöchentlichen Aktivitäten zur Suche „AfD“
bei Google News (über Google Trends bezogen) und die Umfrageergebnisse der Afd in den Umfragen der
Institute EMNID, Forschungsgruppe Wahlen, GMS, Infratest dimap,
Forsa, INSA/YouGov und Allensbach.
Aus diesen Werten
haben wir einen wöchentlichen Durchschnitt gebildet.
AfD-Umfragen/Google News, absolut |
Die absoluten Werte
geben erst einmal keinen Aufschluss über einen Zusammenhang.
Die Analyse
Zeitreihen haben
häufig einen Trend. Würde man einfach zwei Zeitreihen vergleichen,
die zufällig beide steigen oder fallen, würde der Eindruck eines
Zusammenhangs entstehen. Daher wird der Trend aus den Daten entfernt.
Dafür wird die Differenz von Woche zu Woche berechnet. Würde dies
nicht reichen, dann würde die Differenz der Differenz genommen, usw.
In unserem Fall lässt sich aber für beide Zeitreihen zeigen, dass
die Differenz trendfrei ist.
AfD-Umfragen/Google News, Differenz |
Die Differenz (also
um wie viel die Berichterstattung oder die Umfragewerte pro Woche zu
oder abgenommen haben) folgt sichtbar keinen Trend. Da die Ausschläge
aber sehr unterschiedlich stark sind, kann man im Plot nicht viel
erkennen. Für die folgenden Berechnungen ist das zwar egal, aber zur
besseren Visualisierung haben wir die Daten auf eine einheitliche
Skala gebracht.
AfD-Umfragen/Google News, Differenz, skalliert |
Die Granger-Analyse
fragt nun Folgendes: Lässt sich die eine Zeitreihe (Umfragen) besser
durch ihre eigenen vorherigen Werte vorhersagen, oder durch ein
Modell, das zusätzlich die vergangenen Werte einer zweiten Zeitreihe
(Google News) enthält. Ist letzteres der Fall, dann ist die zweite
Zeitreihe offenbar verantwortlich für einen Teil der Veränderungen
der ersten. Der Kerngedanke dabei ist, dass die Ursache der Wirkung
immer zeitlich vorausgeht. Findet man also einen Zusammenhang in
Daten, der diese Chronologie aufweist, kann man daher von einem
Kausalzusammenhang (Granger-Kausalität) ausgehen.
Mathematisch stellt
sich das so dar:
Das erste Modell (Ω)
ist eine multiple lineare Regression
Ω
= yt = β0 + β1yt-1 +…+
βkyt-k + ewobei
yt die Werte der ersten Zeitreihe sind und yt-k
die vorrausgehender Werte bezeichnen. k gibt an, um wie viele
Schritte man in die Vergangenheit geht. β bezeichnet die jeweiligen
Regressionsparameter und e den verbleibenden Fehler des Modells.Das
zweite Modell (π )ist sehr ähnlich: π = yt = β0 +
β1yt-1 +…+ βkyt-k +
α1xt-1 +…+ αkxt-k + e.Hier
werden einfach zusätzlich die vergangenen Werte der zweiten
Zeitreihe (Lags) integriert. Wären in der zweiten Formel alle
α-Werte Null, dann wären die beiden Modelle identisch. Und genau
das ist die Nullhypothese, die getestet wird:H0:
αi = 0 für alle i [1,k]H1:
αi ≠ 0 für wenigstens ein i [1,k]
Statistisch wird
dies mit dem „Wald-Test“
überprüft.
Um sicher zu gehen,
dass nicht eine unbekannte dritte Variable beiden Zeitreihen
beeinflusst, wiederholt man die Granger-Analyse zweimal und prüft
einmal die Abhängigkeit der ersten von der zweiten Variable mit
unterschiedlichen Lags und einmal umgekehrt die zweite gegen die
erste Variable.
Für die
AfD-Medien-Daten ist das Ergebnis eindeutig:
Die Umfragewerte
haben keinen signifikanten Granger-Effekt (auf den 5%-Niveau) auf die
Google-News-Daten mit Lags von 1-6.
Die
Google-News-Daten beeinflussen aber die Umfragewerte signifikant mit
den Lags 4, 5 und 6, wobei der Effekt bei Lag 5 am deutlichsten ist.
Der p-Wert liegt hier bei unter 1%.
Was bedeutet dieses Ergebnis in normaler Sprache?
Die Analyse zeigt,
dass die Zu- oder Abnahme in der Medienberichterstattung
(Google-News) sich nach vier bis sechs Wochen auf die
Umfrageergebnisse der AfD auswirken. Die Wahrscheinlichkeit, dass
dieser Effekt bloß zufällig auftritt, ist (wenn man den
Grundannahmen des Modells folgt) kleiner als 1%. D. h., würde man
die Analyse 100 Mal wiederholen, dann wäre zu erwarten, dass eine
dieser Analysen einen solchen Effekt finden würde, obwohl es ihn gar
nicht gibt.
Das Modell lässt
sich veranschaulichen, wenn wir die Daten erneut plotten, diesmal
aber so, dass die Google-News-Veränderungen von vor fünf Wochen
über den aktuellen Umfragewerten liegen.
AfD-Umfragen/Google News, Differenz, skalliert, Lag 5 |
Man kann sehen, dass
die Zeitreihen jetzt „besser“ zueinander passen und die Richtung
der Veränderungen häufiger identisch ist.
Da es sich bei den
Modelle im Prinzip um klassische Regressionsmodelle handelt, können
wir mit der Analyse noch einen Schritt weitergehen. Der beigefügte
R-Code zeigt, wie die Modelle nachgebaut wurden. Vergleicht man die
Auswertungen, werden die Ergebnisse weiter untermauert. Dass Modell
mit den Google-News ist insgesamt signifikant, die Effektrichtung ist
positiv (wenn mehr über die AfD berichtet wird, steigen die
Umfragewerte) und das Modell erklärt etwa 8% der Varianz (im
Durchschnitt sind die Google-News also kausal für 8% der
Veränderungen der Umfragen verantwortlich).
Da wir das Modell
nun spezifiziert haben, können wir auch graphisch darstellen, welche
Werte das Modell vorhergesagt hat und welche Unsicherheit im Modell
ist. Die orange Linie zeigt die Prognose und die schwarzen Kurven
geben die Werte an, die laut Modell mit 95-prozentiger
Wahrscheinlichkeit erwartet würden.
AfD-Umfragen/Modell |
Klar, die blaue
Linie mit den wirklichen Umfrageergebnissen bewegt sich (zu-) häufig
außerhalb des Konfidenzintervalls, aber das Modell erklärt ja auch
nur 8% des Zusammenhangs.
Zum Abschluss können
wir jetzt noch die Differenz, die ja das Modell vorhersagt, in
absolute Werte zurückrechnen und eine kleine Simulation durchführen.
Was wäre passiert, wenn die Medien in den letzten Wochen gar nicht über die AfD berichtet hätten?
AdF-Umfragen/Simulation, absolut |
Hätten die Medien
nicht mehr über die AfD berichtet, die Umfragewerte wären
vermutlich auf 6% zurückgegangen anstatt auf 11% zu steigen. Die
schwarze Linie zeigt, ab welchen Zeitpunkt die Google-News-Werte für
die Simulation auf Null gesetzt wurden. Man sieht aber auch, dass die
absoluten Werte insgesamt deutlicher vom Modell abweichen, weil sich
die Unterschiede in den Differenzen hier aufaddieren.
Bewertung
Viel über die AfD
berichten führt zu steigenden Umfragewerten. Ob zu viel über die
AfD berichtet wurde, ist eine ganz andere Frage. Aufgabe der Medien
ist es sicher nicht, die AfD künstlich klein zu halten. Hätten die
Medien einfach nicht mehr über die AfD berichtet, wären sie ihrem
Auftrag sicherlich nicht nachgekommen. Die Gefahr, die AfD mit der
Berichterstattung groß zu machen, ist – laut unserer Analyse –
aber tatsächlich gegeben. Insofern ist es wichtig, dass
Journalistinnen und Journalisten sich ihrer Verantwortung bei der
Berichterstattung bewusst sind.
Diskussion: Granger-Kausalität versus Kausalität
In der Statistik hat
man es häufig mit Korrelationen zu tun. D. h. wir finden
ungerichtete Zusammenhänge. Wir wissen, zwei Ereignisse treten mit
einer gewissen Wahrscheinlichkeit gemeinsam auf und schließen daher
auf einen Zusammenhang. Wir wissen aber nicht, was was bedingt. Die
Granger-Analyse geht hier einen wichtigen Schritt weiter: Sie zeigt
einen gerichteten Zusammenhang auf: A beeinflusst B und nicht
umgekehrt. Dennoch ist dieses statistische Verfahren nicht mit dem
philosophischen Konzept der Kausalität zu verwechseln. Wenn wir
normalerweise über Ursache und Wirkung sprechen, dann haben wir
Gesetze gefunden, die diese Effekte erklären. Diesen Schritt liefert
die Granger-Analyse nicht. Wir wissen nicht, warum die Umfragen fünf
Wochen nach der Berichterstattung steigen. Solange die Wirklichen
Zusammenhänge nicht klar sind, sondern „nur“ die zeitliche
Abfolge von Ursache und Wirkung untersucht wurde, lässt sich das
Verhältnis von Medienberichterstattung und AfD-Erfolg auch nicht
abschließend bestimmen. Dass es aber einen Effekt gibt, haben wir
ziemlich sicher nachgewiesen.
PS: Die Datenlage könnte besser sein
Die Daten von Google-Trends sind mit Vorsicht zu genießen und spiegeln nicht direkt die Häufigkeit der Medienberichterstattung wider. Wir haben allerdings auch die Erwähnung in der Zeit herangezogen und kommen zu ähnlichen Ergebnissen. Eine Wiederholung dieser Analyse mit Umfangreichen Mediendaten wäre aber angebracht.
Simon Hegelich und Orestis Papakyriakopoulos, September 2017
R-Code
library(forecast)
library(zoo)
library(zoo)
##
## Attaching package: 'zoo'
## Attaching package: 'zoo'
##
The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
## as.Date, as.Date.numeric
df
<-
read.csv("./Data/AfDMedien.csv",
dec
=
",")
colnames(df)
colnames(df)
##
[1] "KW" "Google.Suche"
## [3] "Google.News" "ZEIT"
## [5] "EMNID" "FG.Wahlen"
## [7] "GMS" "Infratest"
## [9] "Forsa" "INSA...YouGov"
## [11] "Allensbach" "X"
## [13] "Google..kombiniert." "ZEIT.1"
## [15] "Durchschnitt.Prognosen" "Durchschnitt.Prognosen.Faktor5"
## [3] "Google.News" "ZEIT"
## [5] "EMNID" "FG.Wahlen"
## [7] "GMS" "Infratest"
## [9] "Forsa" "INSA...YouGov"
## [11] "Allensbach" "X"
## [13] "Google..kombiniert." "ZEIT.1"
## [15] "Durchschnitt.Prognosen" "Durchschnitt.Prognosen.Faktor5"
df$Google.News
##
[1] 24 20 22 23 21 17 22 14 13 13 13 14 15 13 12 17
16
## [18] 18 26 33 33 26 20 18 18 27 55 32 25 19 16 15 15 17
## [35] 20 22 21 25 28 36 36 56 39 41 42 47 40 44 41 40 31
## [52] 40 52 50 62 80 106 72 92 75 63 107 121 75 68 37 43 51
## [69] 62 75 59 52 63 78 89 57 46 36 60 53 50 57 42 42 55
## [86] 57 74 81 66 70 49 50 44 40 42 33 44 36 50 35 33 37
## [103] 65 42 44 43 64 66 53 42 49 39 42 43 38 41 50 39 44
## [120] 75 63 45 42 44 37 32 26 30 32 26 22 22 25 30 29 22
## [137] 34 37 40 83 82 NA NA
## [18] 18 26 33 33 26 20 18 18 27 55 32 25 19 16 15 15 17
## [35] 20 22 21 25 28 36 36 56 39 41 42 47 40 44 41 40 31
## [52] 40 52 50 62 80 106 72 92 75 63 107 121 75 68 37 43 51
## [69] 62 75 59 52 63 78 89 57 46 36 60 53 50 57 42 42 55
## [86] 57 74 81 66 70 49 50 44 40 42 33 44 36 50 35 33 37
## [103] 65 42 44 43 64 66 53 42 49 39 42 43 38 41 50 39 44
## [120] 75 63 45 42 44 37 32 26 30 32 26 22 22 25 30 29 22
## [137] 34 37 40 83 82 NA NA
df$Durchschnitt.Prognosen
##
[1] 5.00 6.38 6.50 6.25 6.20 5.75 6.63 6.00 6.50 6.88
6.30
## [12] 6.38 5.70 5.75 5.83 5.75 6.13 5.33 5.50 5.25 5.08 4.83
## [23] 5.00 4.50 4.70 4.38 4.50 3.67 3.90 3.60 3.25 3.33 3.50
## [34] 3.50 3.63 3.88 4.20 4.40 5.25 5.50 6.00 6.83 7.08 7.50
## [45] 8.00 8.25 8.42 8.50 8.63 8.60 8.80 8.83 8.00 8.70 10.10
## [56] 10.83 9.40 11.63 11.33 10.83 10.88 10.63 10.83 12.25 12.50 12.00
## [67] 12.20 11.17 12.00 12.17 12.88 12.75 13.30 13.67 13.00 11.67 12.50
## [78] 12.00 11.67 11.30 10.30 10.42 11.00 11.25 11.00 11.38 9.00 13.13
## [89] 13.33 13.75 13.92 13.83 13.50 13.20 13.00 12.50 12.20 12.13 12.00
## [100] 12.50 12.17 12.40 12.25 12.10 13.75 13.40 13.00 12.17 12.33 11.75
## [111] 10.75 10.00 9.50 10.00 9.40 9.83 9.90 8.25 8.75 9.50 9.25
## [122] 8.60 8.75 8.75 8.20 7.75 8.00 8.00 8.00 7.50 7.50 7.67
## [133] 8.50 8.00 8.50 8.50 8.20 8.00 8.83 9.20 9.21 8.80 10.00
## [12] 6.38 5.70 5.75 5.83 5.75 6.13 5.33 5.50 5.25 5.08 4.83
## [23] 5.00 4.50 4.70 4.38 4.50 3.67 3.90 3.60 3.25 3.33 3.50
## [34] 3.50 3.63 3.88 4.20 4.40 5.25 5.50 6.00 6.83 7.08 7.50
## [45] 8.00 8.25 8.42 8.50 8.63 8.60 8.80 8.83 8.00 8.70 10.10
## [56] 10.83 9.40 11.63 11.33 10.83 10.88 10.63 10.83 12.25 12.50 12.00
## [67] 12.20 11.17 12.00 12.17 12.88 12.75 13.30 13.67 13.00 11.67 12.50
## [78] 12.00 11.67 11.30 10.30 10.42 11.00 11.25 11.00 11.38 9.00 13.13
## [89] 13.33 13.75 13.92 13.83 13.50 13.20 13.00 12.50 12.20 12.13 12.00
## [100] 12.50 12.17 12.40 12.25 12.10 13.75 13.40 13.00 12.17 12.33 11.75
## [111] 10.75 10.00 9.50 10.00 9.40 9.83 9.90 8.25 8.75 9.50 9.25
## [122] 8.60 8.75 8.75 8.20 7.75 8.00 8.00 8.00 7.50 7.50 7.67
## [133] 8.50 8.00 8.50 8.50 8.20 8.00 8.83 9.20 9.21 8.80 10.00
#
png("Absolut.png", type = "cairo", width = 16,
height = 10, res = 600, units = "cm")
plot.ts(df$Google.News, col="orange", ylim=c(0,125), xlab = "Weeks", ylab = "")
points(df$Durchschnitt.Prognosen, type = "l", col="darkblue")
legend("topleft", c("Google News", "Mean Polls"), lty=c(1,1), col= c("orange", "darkblue"))
plot.ts(df$Google.News, col="orange", ylim=c(0,125), xlab = "Weeks", ylab = "")
points(df$Durchschnitt.Prognosen, type = "l", col="darkblue")
legend("topleft", c("Google News", "Mean Polls"), lty=c(1,1), col= c("orange", "darkblue"))
#
dev.off()
Polls <- zoo(df$Durchschnitt.Prognosen)
GN <- zoo(df$Google.News)
ndiffs(Polls, alpha=0.05, test=c("kpss"))
Polls <- zoo(df$Durchschnitt.Prognosen)
GN <- zoo(df$Google.News)
ndiffs(Polls, alpha=0.05, test=c("kpss"))
##
[1] 1
ndiffs(GN,
alpha=0.05,
test=c("kpss"))
##
[1] 1
#
differenced time series
GNDiff <- diff(GN)
PollsDiff <- diff(Polls)
# png("Differenz.png", type = "cairo", width = 16, height = 10, res = 600, units = "cm")
plot.ts(GNDiff, col="orange", xlab = "Weeks", ylab = "")
points(PollsDiff, type = "l", col="darkblue")
legend("topleft", c("Google News", "Mean Polls"), lty=c(1,1), col= c("orange", "darkblue"))
GNDiff <- diff(GN)
PollsDiff <- diff(Polls)
# png("Differenz.png", type = "cairo", width = 16, height = 10, res = 600, units = "cm")
plot.ts(GNDiff, col="orange", xlab = "Weeks", ylab = "")
points(PollsDiff, type = "l", col="darkblue")
legend("topleft", c("Google News", "Mean Polls"), lty=c(1,1), col= c("orange", "darkblue"))
#
dev.off()
# png("DifferenzScaled.png", type = "cairo", width = 16, height = 10, res = 600, units = "cm")
plot.ts(scale(GNDiff), col="orange", xlab = "Weeks", ylab = "", ylim = c(-4,6))
points(scale(PollsDiff), type = "l", col="darkblue")
legend("topleft", c("Google News", "Mean Polls"), lty=c(1,1), col= c("orange", "darkblue"))
# png("DifferenzScaled.png", type = "cairo", width = 16, height = 10, res = 600, units = "cm")
plot.ts(scale(GNDiff), col="orange", xlab = "Weeks", ylab = "", ylim = c(-4,6))
points(scale(PollsDiff), type = "l", col="darkblue")
legend("topleft", c("Google News", "Mean Polls"), lty=c(1,1), col= c("orange", "darkblue"))
#
dev.off()
library(lmtest)
grangertest(GNDiff ~ PollsDiff, order=1)
library(lmtest)
grangertest(GNDiff ~ PollsDiff, order=1)
##
Granger causality test
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:1) + Lags(PollsDiff, 1:1)
## Model 2: GNDiff ~ Lags(GNDiff, 1:1)
## Res.Df Df F Pr(>F)
## 1 135
## 2 136 -1 0.0268 0.8701
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:1) + Lags(PollsDiff, 1:1)
## Model 2: GNDiff ~ Lags(GNDiff, 1:1)
## Res.Df Df F Pr(>F)
## 1 135
## 2 136 -1 0.0268 0.8701
grangertest(GNDiff
~
PollsDiff,
order=2)
##
Granger causality test
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:2) + Lags(PollsDiff, 1:2)
## Model 2: GNDiff ~ Lags(GNDiff, 1:2)
## Res.Df Df F Pr(>F)
## 1 132
## 2 134 -2 0.7111 0.493
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:2) + Lags(PollsDiff, 1:2)
## Model 2: GNDiff ~ Lags(GNDiff, 1:2)
## Res.Df Df F Pr(>F)
## 1 132
## 2 134 -2 0.7111 0.493
grangertest(GNDiff
~
PollsDiff,
order=3)
##
Granger causality test
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:3) + Lags(PollsDiff, 1:3)
## Model 2: GNDiff ~ Lags(GNDiff, 1:3)
## Res.Df Df F Pr(>F)
## 1 129
## 2 132 -3 0.9118 0.4373
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:3) + Lags(PollsDiff, 1:3)
## Model 2: GNDiff ~ Lags(GNDiff, 1:3)
## Res.Df Df F Pr(>F)
## 1 129
## 2 132 -3 0.9118 0.4373
grangertest(GNDiff
~
PollsDiff,
order=4)
##
Granger causality test
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:4) + Lags(PollsDiff, 1:4)
## Model 2: GNDiff ~ Lags(GNDiff, 1:4)
## Res.Df Df F Pr(>F)
## 1 126
## 2 130 -4 1.7909 0.1347
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:4) + Lags(PollsDiff, 1:4)
## Model 2: GNDiff ~ Lags(GNDiff, 1:4)
## Res.Df Df F Pr(>F)
## 1 126
## 2 130 -4 1.7909 0.1347
grangertest(GNDiff
~
PollsDiff,
order=5)
##
Granger causality test
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:5) + Lags(PollsDiff, 1:5)
## Model 2: GNDiff ~ Lags(GNDiff, 1:5)
## Res.Df Df F Pr(>F)
## 1 123
## 2 128 -5 1.9173 0.09615 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:5) + Lags(PollsDiff, 1:5)
## Model 2: GNDiff ~ Lags(GNDiff, 1:5)
## Res.Df Df F Pr(>F)
## 1 123
## 2 128 -5 1.9173 0.09615 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
grangertest(GNDiff
~
PollsDiff,
order=6)
##
Granger causality test
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:6) + Lags(PollsDiff, 1:6)
## Model 2: GNDiff ~ Lags(GNDiff, 1:6)
## Res.Df Df F Pr(>F)
## 1 120
## 2 126 -6 1.5983 0.1534
##
## Model 1: GNDiff ~ Lags(GNDiff, 1:6) + Lags(PollsDiff, 1:6)
## Model 2: GNDiff ~ Lags(GNDiff, 1:6)
## Res.Df Df F Pr(>F)
## 1 120
## 2 126 -6 1.5983 0.1534
grangertest(PollsDiff
~
GNDiff,
order=1)
##
Granger causality test
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:1) + Lags(GNDiff, 1:1)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:1)
## Res.Df Df F Pr(>F)
## 1 135
## 2 136 -1 0.0029 0.9574
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:1) + Lags(GNDiff, 1:1)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:1)
## Res.Df Df F Pr(>F)
## 1 135
## 2 136 -1 0.0029 0.9574
grangertest(PollsDiff
~
GNDiff,
order=2)
##
Granger causality test
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:2) + Lags(GNDiff, 1:2)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:2)
## Res.Df Df F Pr(>F)
## 1 132
## 2 134 -2 0.0205 0.9797
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:2) + Lags(GNDiff, 1:2)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:2)
## Res.Df Df F Pr(>F)
## 1 132
## 2 134 -2 0.0205 0.9797
grangertest(PollsDiff
~
GNDiff,
order=3)
##
Granger causality test
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:3) + Lags(GNDiff, 1:3)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:3)
## Res.Df Df F Pr(>F)
## 1 129
## 2 132 -3 1.5141 0.214
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:3) + Lags(GNDiff, 1:3)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:3)
## Res.Df Df F Pr(>F)
## 1 129
## 2 132 -3 1.5141 0.214
grangertest(PollsDiff
~
GNDiff,
order=4)
##
Granger causality test
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:4) + Lags(GNDiff, 1:4)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:4)
## Res.Df Df F Pr(>F)
## 1 126
## 2 130 -4 2.8434 0.02685 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:4) + Lags(GNDiff, 1:4)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:4)
## Res.Df Df F Pr(>F)
## 1 126
## 2 130 -4 2.8434 0.02685 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
grangertest(PollsDiff
~
GNDiff,
order=5)
##
Granger causality test
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:5) + Lags(GNDiff, 1:5)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:5)
## Res.Df Df F Pr(>F)
## 1 123
## 2 128 -5 3.401 0.006512 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:5) + Lags(GNDiff, 1:5)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:5)
## Res.Df Df F Pr(>F)
## 1 123
## 2 128 -5 3.401 0.006512 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
grangertest(PollsDiff
~
GNDiff,
order=6)
##
Granger causality test
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:6) + Lags(GNDiff, 1:6)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:6)
## Res.Df Df F Pr(>F)
## 1 120
## 2 126 -6 2.8628 0.01215 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Model 1: PollsDiff ~ Lags(PollsDiff, 1:6) + Lags(GNDiff, 1:6)
## Model 2: PollsDiff ~ Lags(PollsDiff, 1:6)
## Res.Df Df F Pr(>F)
## 1 120
## 2 126 -6 2.8628 0.01215 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#
png("DifferenzScaledLag5.png", type = "cairo",
width = 16, height = 10, res = 600, units =
"cm")
plot.ts(scale(GNDiff), type="n", ylim=c(-4,6), xlab = "Weeks", ylab = "")
points(scale(lag(GNDiff,5)), type= "l", col ="orange")
points(scale(PollsDiff), type = "l", col ="darkblue")
legend("topleft", c("Google News", "Mean Polls"), lty=c(1,1), col= c("orange", "darkblue"))
plot.ts(scale(GNDiff), type="n", ylim=c(-4,6), xlab = "Weeks", ylab = "")
points(scale(lag(GNDiff,5)), type= "l", col ="orange")
points(scale(PollsDiff), type = "l", col ="darkblue")
legend("topleft", c("Google News", "Mean Polls"), lty=c(1,1), col= c("orange", "darkblue"))
#
dev.off()
dfLaged <- cbind.data.frame(PollsDiff[6:142], PollsDiff[5:141], PollsDiff[4:140],
PollsDiff[3:139], PollsDiff[2:138], PollsDiff[1:137],
GNDiff[6:142], GNDiff[5:141], GNDiff[4:140],
GNDiff[3:139], GNDiff[2:138], GNDiff[1:137])
colnames(dfLaged) <- c("Polls", "P1","P2", "P3", "P4","P5", "N", "N1", "N2", "N3", "N4","N5")
dfLaged <- dfLaged[-137,]
fit <- lm(Polls ~ P1+P2+P3+P4+P5+N1+N2+N3+N4+N5, data = dfLaged)
fit2 <- lm(Polls ~P1+P2+P3+P4+P5, data = dfLaged)
summary(fit)
dfLaged <- cbind.data.frame(PollsDiff[6:142], PollsDiff[5:141], PollsDiff[4:140],
PollsDiff[3:139], PollsDiff[2:138], PollsDiff[1:137],
GNDiff[6:142], GNDiff[5:141], GNDiff[4:140],
GNDiff[3:139], GNDiff[2:138], GNDiff[1:137])
colnames(dfLaged) <- c("Polls", "P1","P2", "P3", "P4","P5", "N", "N1", "N2", "N3", "N4","N5")
dfLaged <- dfLaged[-137,]
fit <- lm(Polls ~ P1+P2+P3+P4+P5+N1+N2+N3+N4+N5, data = dfLaged)
fit2 <- lm(Polls ~P1+P2+P3+P4+P5, data = dfLaged)
summary(fit)
##
## Call:
## lm(formula = Polls ~ P1 + P2 + P3 + P4 + P5 + N1 + N2 + N3 +
## N4 + N5, data = dfLaged)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.37554 -0.34122 -0.01428 0.37251 3.04921
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.017111 0.057831 0.296 0.76782
## P1 -0.305120 0.090293 -3.379 0.00097 ***
## P2 -0.056746 0.094282 -0.602 0.54834
## P3 0.052301 0.090344 0.579 0.56369
## P4 0.088117 0.088150 1.000 0.31942
## P5 0.056641 0.085772 0.660 0.51024
## N1 0.004969 0.004787 1.038 0.30123
## N2 0.011644 0.004793 2.429 0.01656 *
## N3 0.013095 0.005136 2.550 0.01199 *
## N4 0.008919 0.005255 1.697 0.09216 .
## N5 -0.002617 0.005195 -0.504 0.61530
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6717 on 125 degrees of freedom
## Multiple R-squared: 0.1515, Adjusted R-squared: 0.0836
## F-statistic: 2.231 on 10 and 125 DF, p-value: 0.0199
## Call:
## lm(formula = Polls ~ P1 + P2 + P3 + P4 + P5 + N1 + N2 + N3 +
## N4 + N5, data = dfLaged)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.37554 -0.34122 -0.01428 0.37251 3.04921
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.017111 0.057831 0.296 0.76782
## P1 -0.305120 0.090293 -3.379 0.00097 ***
## P2 -0.056746 0.094282 -0.602 0.54834
## P3 0.052301 0.090344 0.579 0.56369
## P4 0.088117 0.088150 1.000 0.31942
## P5 0.056641 0.085772 0.660 0.51024
## N1 0.004969 0.004787 1.038 0.30123
## N2 0.011644 0.004793 2.429 0.01656 *
## N3 0.013095 0.005136 2.550 0.01199 *
## N4 0.008919 0.005255 1.697 0.09216 .
## N5 -0.002617 0.005195 -0.504 0.61530
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6717 on 125 degrees of freedom
## Multiple R-squared: 0.1515, Adjusted R-squared: 0.0836
## F-statistic: 2.231 on 10 and 125 DF, p-value: 0.0199
summary(fit2)
##
## Call:
## lm(formula = Polls ~ P1 + P2 + P3 + P4 + P5, data = dfLaged)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.3828 -0.3601 0.0155 0.3702 3.5233
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.024634 0.059639 0.413 0.68026
## P1 -0.233168 0.087540 -2.664 0.00871 **
## P2 -0.005796 0.089650 -0.065 0.94855
## P3 0.064443 0.089634 0.719 0.47346
## P4 0.075378 0.090277 0.835 0.40527
## P5 0.045785 0.086785 0.528 0.59870
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6937 on 130 degrees of freedom
## Multiple R-squared: 0.05887, Adjusted R-squared: 0.02268
## F-statistic: 1.626 on 5 and 130 DF, p-value: 0.1574
## Call:
## lm(formula = Polls ~ P1 + P2 + P3 + P4 + P5, data = dfLaged)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.3828 -0.3601 0.0155 0.3702 3.5233
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.024634 0.059639 0.413 0.68026
## P1 -0.233168 0.087540 -2.664 0.00871 **
## P2 -0.005796 0.089650 -0.065 0.94855
## P3 0.064443 0.089634 0.719 0.47346
## P4 0.075378 0.090277 0.835 0.40527
## P5 0.045785 0.086785 0.528 0.59870
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6937 on 130 degrees of freedom
## Multiple R-squared: 0.05887, Adjusted R-squared: 0.02268
## F-statistic: 1.626 on 5 and 130 DF, p-value: 0.1574
waldtest(fit,
fit2)
##
Wald test
##
## Model 1: Polls ~ P1 + P2 + P3 + P4 + P5 + N1 + N2 + N3 + N4 + N5
## Model 2: Polls ~ P1 + P2 + P3 + P4 + P5
## Res.Df Df F Pr(>F)
## 1 125
## 2 130 -5 2.7284 0.02245 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Model 1: Polls ~ P1 + P2 + P3 + P4 + P5 + N1 + N2 + N3 + N4 + N5
## Model 2: Polls ~ P1 + P2 + P3 + P4 + P5
## Res.Df Df F Pr(>F)
## 1 125
## 2 130 -5 2.7284 0.02245 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
GNnew
<-
GN
GNnew[134:143] <- 0
GNDiffN <- diff(GNnew)
dfLagedN <- cbind.data.frame(PollsDiff[6:142], PollsDiff[5:141], PollsDiff[4:140],
PollsDiff[3:139], PollsDiff[2:138], PollsDiff[1:137],
GNDiffN[6:142], GNDiffN[5:141], GNDiffN[4:140],
GNDiffN[3:139], GNDiffN[2:138], GNDiffN[1:137])
colnames(dfLagedN) <- c("Polls", "P1","P2", "P3", "P4","P5", "N", "N1", "N2", "N3", "N4","N5")
reDiff <- function(x,s){
a <- c(as.numeric(s[1]))
for (i in 2:length(x)){
a <- c(a, a[i-1]+as.numeric(x[i-1]))
}
return(a)
}
sim <- predict(fit, newdata = dfLagedN, interval = "confidence")
# png("DifferenzScaledConf.png", type = "cairo", width = 16, height = 10, res = 600, units = "cm")
plot(as.numeric(PollsDiff[-c(1:5)]), type="l", col = "darkblue", xlab = "Weeks", ylab = "")
points(sim[,1], type = "l", col="orange")
points(sim[,2], type = "l", col="black")
points(sim[,3], type = "l", col="black")
GNnew[134:143] <- 0
GNDiffN <- diff(GNnew)
dfLagedN <- cbind.data.frame(PollsDiff[6:142], PollsDiff[5:141], PollsDiff[4:140],
PollsDiff[3:139], PollsDiff[2:138], PollsDiff[1:137],
GNDiffN[6:142], GNDiffN[5:141], GNDiffN[4:140],
GNDiffN[3:139], GNDiffN[2:138], GNDiffN[1:137])
colnames(dfLagedN) <- c("Polls", "P1","P2", "P3", "P4","P5", "N", "N1", "N2", "N3", "N4","N5")
reDiff <- function(x,s){
a <- c(as.numeric(s[1]))
for (i in 2:length(x)){
a <- c(a, a[i-1]+as.numeric(x[i-1]))
}
return(a)
}
sim <- predict(fit, newdata = dfLagedN, interval = "confidence")
# png("DifferenzScaledConf.png", type = "cairo", width = 16, height = 10, res = 600, units = "cm")
plot(as.numeric(PollsDiff[-c(1:5)]), type="l", col = "darkblue", xlab = "Weeks", ylab = "")
points(sim[,1], type = "l", col="orange")
points(sim[,2], type = "l", col="black")
points(sim[,3], type = "l", col="black")
#
dev.off()
simM <- reDiff(sim[,1], Polls[1])
# png("Sim.png", type = "cairo", width = 16, height = 10, res = 600, units = "cm")
plot(as.numeric(Polls[-c(1:5)]), type="l", col = "darkblue", xlab = "Weeks", ylab = "")
points(simM, type = "l", col="lightblue")
legend("topleft", c("Simulation", "Mean Polls"), lty=c(1,1), col= c("lightblue", "darkblue"))
abline(v=128)
simM <- reDiff(sim[,1], Polls[1])
# png("Sim.png", type = "cairo", width = 16, height = 10, res = 600, units = "cm")
plot(as.numeric(Polls[-c(1:5)]), type="l", col = "darkblue", xlab = "Weeks", ylab = "")
points(simM, type = "l", col="lightblue")
legend("topleft", c("Simulation", "Mean Polls"), lty=c(1,1), col= c("lightblue", "darkblue"))
abline(v=128)
#
dev.off()
par(mfrow=c(2,2))
plot(fit)
par(mfrow=c(2,2))
plot(fit)
Sehr schön erklärt, schön auch, den Code zu veröffentlichen.
AntwortenLöschenVielen Dank für die Analyse! Ich habe es als Bürger besorgt mitverfolgt, wie die AfD und ihr Kernthema Flüchtlinge insbesondere die Talkshows total dominiert haben, obwohl wir uns als Gesellschaft viel stärker mit Wirtschaftsproblemen und vor allem dem Klimawandel beschäftigen sollten. Ich bin mir sicher, dass die Berichterstattung über die AfD die Einstellungen der Bürger beeinflusst.
AntwortenLöschenWie wollen sie aber ausschließen, dass externe Ereignisse (vor allem in Bezug auf Flüchtlinge) oder Äußerungen von (AfD-)Politikern sowohl Erwähnung in den Nachrichten wie auch die Einstellung der Bevölkerung zur AfD beeinflussen? Sie schreiben, dass sie dies "überprüfen", indem sie einmal Erwähnungen auf Umfragen und dann Umfragen auf Erwähnungen mit verschiedenen lags regredieren. Das erscheint mir unsinnig; Regressionen sind genauso wie Korrelationen symmetrisch. Wenn Y auf X einen positiven Koeffizienten hat, wird X auf Y ebenfalls einen positiven Koeffizienten haben, etc. (der Beweis ist einfach). Wenn ihr Vorgehen korrekt wäre, hieße das schließlich, dass alle Probleme der kausalen Inferenz gelöst werden könnten, wenn man nur Variablen-Messungen über Zeit hätte. Das ist absurd! In diesem Zusammenhang kann ich ihnen die Bücher von Judea Pearl zu kausaler Inferenz (vor allem den "Primer") ans Herz legen, die zeigen, dass Kausalität keinesweges ein (rein) "philosophisches" Problem ist.
Ihre Analyse impliziert auch, dass jegliche Berichterstattung über die AfD deren Umfragewerte nach oben treibt. Das erscheint mir auch zweifelhaft; warum sollte negative Berichterstattung zu höheren Umfragewerten führen?
Insofern würde ich mir eine vorsichtigere Interpretation der Ergebnisse wünschen.
Liebe Grüße, Julian
Nein, die Granger-Kausalität ist gerade nicht symetrisch. Es ist ja nicht möglich, dass Umfragen, die erst in fünf Wochen stattfinden, heute einen Effekt haben. Deshalb haben wir keine Korrelationen berechnet.
AntwortenLöschen