我有 17 年(1995 年到 2011 年)与美国一个州的自杀死亡相关的死亡证明数据。关于自杀和月份/季节有很多神话,其中大部分是矛盾的,而我的文献复习过,我对所使用的方法或对结果的信心没有清晰的认识。
因此,我开始着手查看我是否可以确定在我的数据集中的任何给定月份中自杀的可能性是否更大。我所有的分析都是在 R 中完成的。
数据中的自杀总数为 13,909 人。
如果您查看自杀次数最少的一年,它们发生在 309/365 天 (85%)。如果您查看自杀最多的一年,它们发生在 339/365 天 (93%)。
所以每年有相当多的日子没有自杀。然而,将所有 17 年汇总起来,一年中的每一天都会发生自杀事件,包括 2 月 29 日(虽然平均为 38 岁时只有 5 起)。
简单地将一年中每一天的自杀人数相加并不能表明明显的季节性(在我看来)。
按月汇总,每月平均自杀人数为:
(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
下图显示了每月的总计数。水平红线分别位于 2 月、30 天月和 31 天月的预期值。与卡方检验一致,没有月份超出预期计数的 95% 置信区间。
我以为我已经完成了,直到我开始研究时间序列数据。stl
正如我想象的许多人所做的那样,我从使用stats 包中的函数的非参数季节性分解方法开始。
为了创建时间序列数据,我从汇总的每月数据开始:
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)
在这一点上,我开始担心,因为在我看来,既有季节性因素又有趋势。经过大量互联网研究后,我决定按照 Rob Hyndman 和 George Athanasopoulos 的在线文本“预测:原则和实践”中的说明进行操作,特别是应用季节性 ARIMA 模型。
我使用adf.test()
andkpss.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
最后,我查看了拟合的残差,如果我理解正确,因为所有值都在阈值范围内,它们的行为就像白噪声,因此模型相当合理。我按照文中的描述运行了一个portmanteau 测试,它的 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,如果您毕竟不想添加此内容,则可以还原它)]