Ich habe 17 Jahre (1995 bis 2011) Sterbeurkunde-Daten in Bezug auf Selbstmord-Todesfälle für einen Staat in den USA. Es gibt viele Mythen über Selbstmorde und die Monate / Jahreszeiten. Nachdem ich überprüft habe, bekomme ich kein klares Gefühl für die angewandten Methoden oder das Vertrauen in die Ergebnisse.
Daher habe ich mich vorgenommen, um zu ermitteln, ob es in einem bestimmten Monat innerhalb meines Datensatzes mehr oder weniger wahrscheinlich ist, dass Selbstmorde auftreten. Alle meine Analysen werden in R durchgeführt.
Die Gesamtzahl der Selbstmorde in den Daten beträgt 13.909.
Betrachtet man das Jahr mit den wenigsten Selbstmorden, so treten sie an 309/365 Tagen auf (85%). Betrachtet man das Jahr mit den meisten Selbstmorden, so treten sie an 339/365 Tagen (93%) auf.
Es gibt also eine ganze Reihe von Tagen im Jahr ohne Selbstmorde. In der Summe aller 17 Jahre gibt es jedoch an jedem Tag des Jahres, einschließlich dem 29. Februar, Selbstmorde (obwohl nur 5, wenn der Durchschnitt 38 beträgt).
Allein die Anzahl der Selbstmorde an jedem Tag des Jahres zu addieren, bedeutet für mich keine eindeutige Saisonalität.
Auf monatlicher Ebene gerechnet reichen die durchschnittlichen Selbstmorde pro Monat von:
(m = 65, sd = 7,4 bis m = 72, sd = 11,1)
Mein erster Ansatz bestand darin, den Datensatz für alle Jahre nach Monaten zu aggregieren und einen Chi-Quadrat-Test durchzuführen, nachdem die erwarteten Wahrscheinlichkeiten für die Nullhypothese berechnet worden waren, dass es keine systematische Varianz der Selbstmordzahlen nach Monaten gab. Ich habe die Wahrscheinlichkeiten für jeden Monat unter Berücksichtigung der Anzahl der Tage berechnet (und den Februar für Schaltjahre angepasst).
Die Chi-Quadrat-Ergebnisse zeigten keine signifikante Variation nach Monat:
# So does the sample match expected values?
chisq.test(monthDat$suicideCounts, p=monthlyProb)
# Yes, X-squared = 12.7048, df = 11, p-value = 0.3131
Das Bild unten zeigt die Gesamtzahl pro Monat. Die horizontalen roten Linien werden mit den erwarteten Werten für Februar, 30-Tage-Monate bzw. 31-Tage-Monate positioniert. In Übereinstimmung mit dem Chi-Quadrat-Test liegt kein Monat außerhalb des 95% -Konfidenzintervalls für erwartete Zählungen.
Ich dachte, ich wäre fertig, bis ich anfing, Zeitreihendaten zu untersuchen. Wie ich mir viele Leute vorstelle, habe ich mit der nicht-parametrischen Methode der saisonalen Zerlegung mithilfe der stl
Funktion im Statistikpaket begonnen.
Um die Zeitreihendaten zu erstellen, habe ich mit den aggregierten Monatsdaten begonnen:
suicideByMonthTs <- ts(suicideByMonth$monthlySuicideCount, start=c(1995, 1), end=c(2011, 12), frequency=12)
# Plot the monthly suicide count, note the trend, but seasonality?
plot(suicideByMonthTs, xlab="Year",
ylab="Annual monthly suicides")
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1995 62 47 55 74 71 70 67 69 61 76 68 68
1996 64 69 68 53 72 73 62 63 64 72 55 61
1997 71 61 64 63 60 64 67 50 48 49 59 72
1998 67 54 72 69 78 45 59 53 48 65 64 44
1999 69 64 65 58 73 83 70 73 58 75 71 58
2000 60 54 67 59 54 69 62 60 58 61 68 56
2001 67 60 54 57 51 61 67 63 55 70 54 55
2002 65 68 65 72 79 72 64 70 59 66 63 66
2003 69 50 59 67 73 77 64 66 71 68 59 69
2004 68 61 66 62 69 84 73 62 71 64 59 70
2005 67 53 76 65 77 68 65 60 68 71 60 79
2006 65 54 65 68 69 68 81 64 69 71 67 67
2007 77 63 61 78 73 69 92 68 72 61 65 77
2008 67 73 81 73 66 63 96 71 75 74 81 63
2009 80 68 76 65 82 69 74 88 80 86 78 76
2010 80 77 82 80 77 70 81 89 91 82 71 73
2011 93 64 87 75 101 89 87 78 106 84 64 71
Und dann die stl()
Zersetzung durchgeführt
# Seasonal decomposition
suicideByMonthFit <- stl(suicideByMonthTs, s.window="periodic")
plot(suicideByMonthFit)
An diesem Punkt wurde ich besorgt, weil es für mich sowohl eine saisonale Komponente als auch einen Trend gibt. Nach intensiven Recherchen im Internet habe ich mich entschlossen, die Anweisungen von Rob Hyndman und George Athanasopoulos zu befolgen, die in ihrem Online-Text "Forecasting: Principles and Practice" (Prognose: Grundsätze und Praxis) dargelegt sind, insbesondere um ein saisonales ARIMA-Modell anzuwenden.
Ich habe adf.test()
und kpss.test()
für die Stationarität zu bewerten und bekam widersprüchliche Ergebnisse. Sie lehnten beide die Nullhypothese ab (und stellten fest, dass sie die entgegengesetzte Hypothese prüfen).
adfResults <- adf.test(suicideByMonthTs, alternative = "stationary") # The p < .05 value
adfResults
Augmented Dickey-Fuller Test
data: suicideByMonthTs
Dickey-Fuller = -4.5033, Lag order = 5, p-value = 0.01
alternative hypothesis: stationary
kpssResults <- kpss.test(suicideByMonthTs)
kpssResults
KPSS Test for Level Stationarity
data: suicideByMonthTs
KPSS Level = 2.9954, Truncation lag parameter = 3, p-value = 0.01
Ich habe dann den Algorithmus aus dem Buch verwendet, um festzustellen, wie viel Differenzierung sowohl für den Trend als auch für die Jahreszeit erforderlich ist. Ich endete mit nd = 1, ns = 0.
Ich lief dann auto.arima
, die ein Modell wählte, das einen Trend und eine saisonale Komponente zusammen mit einer Typkonstante "Drift" hatte.
# Extract the best model, it takes time as I've turned off the shortcuts (results differ with it on)
bestFit <- auto.arima(suicideByMonthTs, stepwise=FALSE, approximation=FALSE)
plot(theForecast <- forecast(bestFit, h=12))
theForecast
> summary(bestFit)
Series: suicideByMonthFromMonthTs
ARIMA(0,1,1)(1,0,1)[12] with drift
Coefficients:
ma1 sar1 sma1 drift
-0.9299 0.8930 -0.7728 0.0921
s.e. 0.0278 0.1123 0.1621 0.0700
sigma^2 estimated as 64.95: log likelihood=-709.55
AIC=1429.1 AICc=1429.4 BIC=1445.67
Training set error measures:
ME RMSE MAE MPE MAPE MASE ACF1
Training set 0.2753657 8.01942 6.32144 -1.045278 9.512259 0.707026 0.03813434
Schließlich habe ich mir die Residuen der Anpassung angesehen. Wenn ich das richtig verstehe, verhalten sich alle Werte innerhalb der Schwellenwerte wie weißes Rauschen und daher ist das Modell ziemlich vernünftig. Ich habe einen Portmanteau-Test wie im Text beschrieben durchgeführt, dessen ap-Wert deutlich über 0,05 lag, bin mir jedoch nicht sicher, ob die Parameter korrekt sind.
Acf(residuals(bestFit))
Box.test(residuals(bestFit), lag=12, fitdf=4, type="Ljung")
Box-Ljung test
data: residuals(bestFit)
X-squared = 7.5201, df = 8, p-value = 0.4817
Nachdem ich zurückgegangen bin und das Kapitel über Arima-Modellierung noch einmal gelesen habe, wurde mir klar, dass ich auto.arima
mich entschieden habe, Trend und Saison zu modellieren. Und mir ist auch klar, dass Prognosen nicht genau die Analyse sind, die ich wahrscheinlich machen sollte. Ich möchte wissen, ob ein bestimmter Monat (oder allgemeiner die Jahreszeit) als risikoreicher Monat gekennzeichnet werden soll. Es scheint, dass die Werkzeuge in der Vorhersageliteratur sehr relevant sind, aber vielleicht nicht das Beste für meine Frage. Jeder Input wird sehr geschätzt.
Ich poste einen Link zu einer CSV-Datei, die die täglichen Zählerstände enthält. Die Datei sieht folgendermaßen aus:
head(suicideByDay)
date year month day_of_month t count
1 1995-01-01 1995 01 01 1 2
2 1995-01-03 1995 01 03 2 1
3 1995-01-04 1995 01 04 3 3
4 1995-01-05 1995 01 05 4 2
5 1995-01-06 1995 01 06 5 3
6 1995-01-07 1995 01 07 6 2
Anzahl ist die Anzahl der Selbstmorde, die an diesem Tag passiert sind. "t" ist eine numerische Folge von 1 bis zur Gesamtzahl der Tage in der Tabelle (5533).
Ich habe die folgenden Kommentare zur Kenntnis genommen und über zwei Dinge nachgedacht, die mit dem Modellieren von Selbstmord und Jahreszeiten zusammenhängen. Erstens, in Bezug auf meine Frage sind Monate lediglich Stellvertreter für den Wechsel der Jahreszeit. Es interessiert mich nicht, ob sich ein bestimmter Monat von anderen unterscheidet oder nicht (das ist natürlich eine interessante Frage, aber es ist nicht das, was ich mir vorgenommen habe untersuchen). Daher halte ich es für sinnvoll, die Monate durch die Verwendung der ersten 28 Tage aller Monate auszugleichen . Wenn Sie dies tun, bekommen Sie eine etwas schlechtere Passform, was ich als Beweis für einen Mangel an Saisonalität interpretiere. In der folgenden Ausgabe ist die erste Anpassung eine Reproduktion einer Antwort unter Verwendung von Monaten mit der tatsächlichen Anzahl von Tagen, gefolgt von einem Datensatz suicideByShortMonthin denen Selbstmordzahlen von den ersten 28 Tagen aller Monate berechnet wurden. Mich interessiert, was die Leute darüber denken, ob diese Anpassung eine gute Idee ist, nicht notwendig oder schädlich?
> summary(seasonFit)
Call:
glm(formula = count ~ t + days_in_month + cos(2 * pi * t/12) +
sin(2 * pi * t/12), family = "poisson", data = suicideByMonth)
Deviance Residuals:
Min 1Q Median 3Q Max
-2.4782 -0.7095 -0.0544 0.6471 3.2236
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 2.8662459 0.3382020 8.475 < 2e-16 ***
t 0.0013711 0.0001444 9.493 < 2e-16 ***
days_in_month 0.0397990 0.0110877 3.589 0.000331 ***
cos(2 * pi * t/12) -0.0299170 0.0120295 -2.487 0.012884 *
sin(2 * pi * t/12) 0.0026999 0.0123930 0.218 0.827541
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for poisson family taken to be 1)
Null deviance: 302.67 on 203 degrees of freedom
Residual deviance: 190.37 on 199 degrees of freedom
AIC: 1434.9
Number of Fisher Scoring iterations: 4
> summary(shortSeasonFit)
Call:
glm(formula = shortMonthCount ~ t + cos(2 * pi * t/12) + sin(2 *
pi * t/12), family = "poisson", data = suicideByShortMonth)
Deviance Residuals:
Min 1Q Median 3Q Max
-3.2414 -0.7588 -0.0710 0.7170 3.3074
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 4.0022084 0.0182211 219.647 <2e-16 ***
t 0.0013738 0.0001501 9.153 <2e-16 ***
cos(2 * pi * t/12) -0.0281767 0.0124693 -2.260 0.0238 *
sin(2 * pi * t/12) 0.0143912 0.0124712 1.154 0.2485
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for poisson family taken to be 1)
Null deviance: 295.41 on 203 degrees of freedom
Residual deviance: 205.30 on 200 degrees of freedom
AIC: 1432
Number of Fisher Scoring iterations: 4
Das zweite, worauf ich näher eingegangen bin, ist die Frage, wie man den Monat als Proxy für die Saison verwendet. Vielleicht ist ein besserer Indikator für die Jahreszeit die Anzahl der Tageslichtstunden, die ein Gebiet erhält. Diese Daten stammen aus einem nördlichen Bundesstaat mit erheblichen Schwankungen des Tageslichts. Unten sehen Sie eine Grafik des Tageslichts aus dem Jahr 2002.
Wenn ich diese Daten anstelle des Monats des Jahres verwende, ist der Effekt immer noch signifikant, aber der Effekt ist sehr, sehr gering. Die verbleibende Abweichung ist viel größer als bei den obigen Modellen. Wenn die Tageslichtstunden ein besseres Modell für die Jahreszeiten sind und die Passform nicht so gut ist, ist dies ein weiterer Beweis für einen sehr geringen saisonalen Effekt?
> summary(daylightFit)
Call:
glm(formula = aggregatedDailyCount ~ t + daylightMinutes, family = "poisson",
data = aggregatedDailyNoLeap)
Deviance Residuals:
Min 1Q Median 3Q Max
-3.0003 -0.6684 -0.0407 0.5930 3.8269
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 3.545e+00 4.759e-02 74.493 <2e-16 ***
t -5.230e-05 8.216e-05 -0.637 0.5244
daylightMinutes 1.418e-04 5.720e-05 2.479 0.0132 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for poisson family taken to be 1)
Null deviance: 380.22 on 364 degrees of freedom
Residual deviance: 373.01 on 362 degrees of freedom
AIC: 2375
Number of Fisher Scoring iterations: 4
Ich poste die Tagesstunden, falls jemand damit herumspielen möchte. Beachten Sie, dass dies kein Schaltjahr ist. Wenn Sie also die Minuten für die Schaltjahre eingeben möchten, können Sie die Daten entweder extrapolieren oder abrufen.
[ Bearbeiten , um einen Plot aus einer gelöschten Antwort hinzuzufügen (es macht mir hoffentlich nichts aus, wenn ich den Plot in der gelöschten Antwort hier oben auf die Frage verschiebe. Svannoy, wenn du das nicht möchtest, kannst du es zurücksetzen)]