У мене 17 років (з 1995 по 2011 рік) даних свідоцтва про смерть, пов’язаних із смертю від самогубства для штату в США. Існує багато міфологій про самогубства та місяці / пори року, багато чого суперечливе, а також про літературу, яку я ' Подивившись, я не розумію використаних методів або впевненості в результатах.
Тож я вирішив визначити, чи можу я визначити, чи є більш суттєвими випадки самогубств у будь-який місяць у моєму наборі даних. Всі мої аналізи робляться в Р.
Загальна кількість самогубств у даних - 13 909.
Якщо дивитися на рік з найменшою кількістю самогубств, вони трапляються на 309/365 днів (85%). Якщо дивитися на рік із найбільшою кількістю самогубств, вони трапляються на 339/365 днів (93%).
Тож щорічно існує безліч самогубств. Однак, коли їх збирають протягом усіх 17 років, є самогубства кожного дня року, включаючи 29 лютого (хоча лише 5, коли середній показник становить 38).
Просто додавання кількості самогубств у кожен день року не означає чіткої сезонності (на мій погляд).
У середньому на місячному рівні середні самогубства на місяць коливаються від:
(m = 65, sd = 7,4, до m = 72, sd = 11,1)
Мій перший підхід полягав у тому, щоб зібрати дані, встановлені за місяцями за всі роки, і зробити тест-квадрат-тест після обчислення очікуваної ймовірності для нульової гіпотези, що систематичної розбіжності в кількості самогубств по місяцях не було. Я обчислював ймовірності кожного місяця, враховуючи кількість днів (і коригуючи лютий на високосні роки).
Результати чі-квадрата не показали суттєвих змін по місяцях:
# So does the sample match expected values?
chisq.test(monthDat$suicideCounts, p=monthlyProb)
# Yes, X-squared = 12.7048, df = 11, p-value = 0.3131
На зображенні нижче вказується загальна кількість за місяць. Горизонтальні червоні лінії розміщуються за очікуваними значеннями відповідно для лютого, 30 днів місяця та 31 дня місяця відповідно. Відповідно до тесту чи-квадрата, жоден місяць не перевищує 95% довірчий інтервал для очікуваних підрахунків.
Я думав, що я закінчив, поки не почав досліджувати дані часових рядів. Як я собі уявляю, багато людей, я почав із непараметричного сезонного методу декомпозиції, використовуючи stl
функцію в пакеті статистики.
Щоб створити дані часового ряду, я розпочав з агрегованих щомісячних даних:
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
А потім виконували stl()
розкладання
# Seasonal decomposition
suicideByMonthFit <- stl(suicideByMonthTs, s.window="periodic")
plot(suicideByMonthFit)
У цей момент я заклопотався, бо мені здається, що є і сезонний компонент, і тенденція. Після довгих інтернет-досліджень я вирішив виконувати вказівки Роб Хайндмана та Джорджа Атанасопулоса, викладені в їхньому он-лайн тексті "Прогнозування: принципи та практика", спеціально застосувати сезонну модель ARIMA.
Я використовував adf.test()
і kpss.test()
для оцінки стаціонарності, і отримував суперечливі результати. Вони обоє відкинули нульову гіпотезу (зазначивши, що вони перевіряють протилежну гіпотезу).
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
Потім я використав алгоритм у книзі, щоб побачити, чи можу я визначити кількість диференціації, яку потрібно зробити як для тренда, так і для сезону. Я закінчився з nd = 1, ns = 0.
Потім я побіг auto.arima
, який обрав модель, яка мала як тенденцію, так і сезонну складову, а також константу типу "дрейф".
# 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
Нарешті, я подивився на залишки, що підходять, і якщо я це правильно зрозумів, оскільки всі значення знаходяться в порогових межах, вони поводяться як білий шум, і тому модель є досить розумною. Я провів тест на портманто, як описано в тексті, який мав значення ap значно вище 0,05, але я не впевнений, що в мене параметри правильні.
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
Повернувшись і прочитавши розділ про моделювання аріма, я знову зрозумів, що auto.arima
вирішив моделювати тенденцію та сезон. І я також розумію, що прогнозування - це не конкретний аналіз, який я, мабуть, повинен робити. Хочеться знати, чи повинен бути визначений конкретний місяць (або більш загальний час року) як місяць з високим рівнем ризику. Здається, інструменти в літературі з прогнозування дуже доречні, але, можливо, не найкращі для мого питання. Будь-який вклад дуже цінується.
Я публікую посилання на файл csv, який містить щоденні підрахунки. Файл виглядає приблизно так:
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
Підрахунок - це кількість самогубств, що відбулися в той день. "t" - числова послідовність від 1 до загальної кількості днів у таблиці (5533).
Я взяв до відома коментарі нижче і подумав про дві речі, пов'язані з моделюванням самогубств та сезонами. По-перше, що стосується мого питання, місяці - це просто проксі для позначення зміни сезону, я не зацікавлений у тому, чи є конкретний місяць, чим він відрізняється від інших (це, звичайно, цікаве питання, але це не те, що я поставив перед собою досліджувати). Отже, я думаю, що є сенс зрівняти місяці, просто використовуючи перші 28 днів усіх місяців. Коли ви це робите, ви отримуєте трохи гірший вигляд, що я трактую як більше доказів щодо відсутності сезонності. У висновку нижче, перша відповідь - це відтворення відповіді нижче з використанням місяців із їх справжньою кількістю днів з подальшим набором даних самогубстваByShortMonthв яких підраховували кількість самогубств за перші 28 днів усіх місяців. Мене цікавить, що люди думають про мокріше чи ні ця корекція - це гарна ідея, не потрібна чи шкідлива?
> 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
Друге, що я розглядав більше, це питання використання місяця як проксі для сезону. Можливо, кращим показником сезону є кількість денного світлового часу, який отримує область. Ці дані походять з північного штату, який значно змінюється в денному світлі. Нижче наведено графік денного світла 2002 року.
Коли я використовую ці дані, а не місяць року, ефект все ще значний, але ефект дуже-дуже малий. Залишковий відхилення набагато більше, ніж у моделей, наведених вище. Якщо світловий день є кращою моделлю для сезонів, а придатність не настільки хороша, чи це більше свідчить про дуже маленький сезонний ефект?
> 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
Я розміщую світловий день на випадок, якщо хтось захоче пограти з цим. Зауважте, що це не високосний рік, тому, якщо ви хочете скласти протокол за високосні роки, або екстраполюйте, або отримайте дані.
[ Редагувати, щоб додати сюжет із видаленої відповіді (сподіваємось, rnso не проти мені перемістити сюжет у видаленій відповіді сюди на питання. Svannoy, якщо ви все-таки не хочете, щоб це було додано, ви можете відновити його]]