Spatio-Temporal(Nonparametric Dynamic Trend)

Spatial Statistics

Summary Nonparametric Dynamic Trend of Spatio-Temporal Model including Risk Factors

Yeongeun Jeon
01-26-2021

INLA는 잠재 가우스 모형 (latent gaussian model)에 특화된 방법이며 복잡한 사후 분포를 단순화된 라플라스 근사치를 이용하고 적분을 유한개의 가중 합으로 계산하기 때문에 MCMC에 비해 비교적 짧은 계산시간에 정확한 결과를 제공한다는 이점이 있다. 이러한 장점을 이용하여 2017년 ~ 2019년에 서울에서 발생한 5대강력범죄를 분석하기 위해 R-INLA (Integrated Nested Laplace Approximations)를 적용해보았다. 데이터는 서울 열린데이터광장에서 수집하였다. 게다가 범죄발생은 공간과 밀접한 관련이 있다는 것은 잘 알려진 것이며, 공간의 가변적 특성을 고려한다면 시공간 모형(Spatio-Temporal Model)을 적용하여 분석하는 것이 적절하다. 공간 모형으로는 BYM Model, 시간 모형으로는 "Nonparametric Dynamic Trend"을 이용하였다. 게다가 서울 5대 강력범죄에 영향을 미칠 수 있는 요인으로 치안시설 수, 안심귀가스카우트 이용수, 여성인구비를 고려해보았다.


Nonparametric Dynamic Trend

서울 강간강제추행범죄는 count data이기 때문에 Poisson regression이 사용된다. \(i\)번째 자치구의 \(t\)시간에서 발생한 5대 강력범죄 건수를 \(y_{it}\)라고 할 때, \[\begin{align*} y_{it} &\thicksim Poisson(\lambda_{it}), \;\; \lambda_{it} = E_{it}\rho_{it}\\ \eta_{it} &= \log{\rho_{it}} = b_{0} + u_{i} + v_{i} + \gamma_{t} + \phi_{t} + \sum_{j} \beta_{j}x_{jit} \end{align*}\]

Nonparametric Dynamic Trend는 선형성 조건을 완하하기 위하여 Dynamic nonparametric 형태를 취한다.


Spatial Effect

BYM Model은 공간적으로 구조화된 요소(\(u_{i}\))와 비구조화된 요소(\(v_{i}\)) 두 가지를 모두 고려한다.

구조화된 공간 효과(\(u_{i}\))

\[\begin{align*} &u_{i} \vert u_{-i} \thicksim N(m_{i}, s^2_{i}),\\ &m_{i} = \frac{\sum_{j \in \mathcal{N}_{i}} u_{j}}{{\# \mathcal{N}_{i}}} ,\;\; s^2_{i} = \frac{\sigma^2_{u}}{\# \mathcal{N}_{i}}, \end{align*}\]

비구조화된 공간 효과(\(v_{i}\))

\[\begin{align*} v_{i} \thicksim N(0, \sigma^2_{v}) \end{align*}\]



Time Effect

Nonparametric Dynamic Trend는 시간적으로 구조화된 요소(\(\gamma_{t}\))와 비구조화된 요소(\(\phi_{t}\)) 두 가지를 모두 고려한다.

구조화된 시간 효과(\(\gamma_{i}\))

Nonparametric Dynamic Trend에서 구조화된 시간 효과(\(\gamma_{t}\))는 Random Walk(RW)를 사용하여 모형화한다.

\[\begin{align*} \gamma_{t} \vert \gamma_{t-1} \thicksim N(\gamma_{t-1}, \sigma^2_{\gamma}), \text{RW of order 1},\\ \gamma_{t} \vert \gamma_{t-1}, \gamma_{t-2} \thicksim N(2\gamma_{t-1} + \gamma_{t-2}, \sigma^2_{\gamma}), \text{RW of order 2} \\ \end{align*}\]

비구조화된 시간 효과(\(\phi_{t}\))

\[\begin{align*} \phi_{t} \thicksim N(0, \sigma^2_{\pi}) \end{align*}\]



Real Data

2017년 ~ 2019년에 서울에서 발생한 5대강력범죄를 분석하기 위해 R-INLA (Integrated Nested Laplace Approximations)를 이용하여 시공간모형을 적용해보았다. 데이터는 서울 열린데이터광장에서 수집하였다.

Loading Data

pacman::p_load("maptools",     # For readShapePoly
               "spdep",        # For poly2nb
               "dplyr", 
               "RColorBrewer", # For brewer.pal
               "ggplot2",
               "INLA")



dat.2017   <- read.csv("2017_crime.csv",header=T) 
dat.2018   <- read.csv("2018_crime.csv",header=T) 
dat.2019   <- read.csv("2019_crime.csv",header=T) 

# Convert rows in the order of ESPI_PK
dat.2017 <- dat.2017[order(dat.2017$ESRI_PK),]
dat.2018 <- dat.2018[order(dat.2018$ESRI_PK),]
dat.2019 <- dat.2019[order(dat.2019$ESRI_PK),]


# Change for year
dat.2017 <- dat.2017 %>%
  mutate(year = 1)

dat.2018 <- dat.2018 %>%
  mutate(year = 2)

dat.2019 <- dat.2019 %>%
  mutate(year = 3)

# Combining for data
dat        <- rbind(dat.2017, dat.2018, dat.2019)

Loading .shp

seoul.map   <- maptools::readShapePoly("./TL_SCCO_SIG_W_SHP/TL_SCCO_SIG_W.shp")   # Call .shp file
seoul.nb    <- poly2nb(seoul.map)      # Builds a neighbours list based on regions with contiguous boundaries
seoul.listw <- nb2listw(seoul.nb)      # Supplements a neighbours list with spatial weights for the chosen coding scheme
seoul.mat   <- nb2mat(seoul.nb)        # Generates a weights matrix for a neighbours list with spatial weights for the chosen coding scheme
                                       # Object of class "nb"

Expected Case

흔하게 사용하는 예상되는 수 (\(E_{it}\))는 \[\begin{align*} E_{it} = n_{it}\frac{\sum_{t}\sum_{i} y_{it}}{\sum_{t}\sum_{i} n_{it}}, \end{align*}\]

(참고 : Bayesian Disease Mapping: Hierarchical Modeling in Spatial Epidemiology p.293)

dat$E <- sum(dat$crime)/sum(dat$pop_total)*dat$pop_total

Adjacency Matrix

INLA에서는 근접행렬을 이용하여 그래프로 나타낼 수 있다.

nb2INLA("Seoul.graph", seoul.nb)   # nb2INLA(저장할 파일 위치, Object of class "nb")NAseoul.adj <- paste(getwd(),"/Seoul.graph",sep="")
H         <- inla.read.graph(filename="Seoul.graph")
image(inla.graph2matrix(H),xlab="",ylab="")


Generate Variables

dat <- dat %>%
    mutate(pop_female_rate = pop_femal/pop_total)
var <- c("pop_female_rate", "sec_fac", "safe_return_use")

summarise_at(dat, var, c("mean", "sd"))
  pop_female_rate_mean sec_fac_mean safe_return_use_mean
1             0.511025     17.97333             13530.95
  pop_female_rate_sd sec_fac_sd safe_return_use_sd
1         0.00903732   4.194505            7629.22

➤ 치안시설 수, 안심귀가스카우트 이용수의 표준편차가 큰 것을 알 수 있다. 이를 줄이기 위하여 자연로그 변환을 실시하였다.

dat <- dat %>%
  mutate(ln_sec_fac = log(sec_fac)) %>%                                 
  mutate(ln_safe_return_use = log(safe_return_use))          

Modeling with Ecological regression

dat$ID.area  <- 1:25         # The Identifiers For The Boroughs 
dat$year1    <- dat$year
formula <- crime ~ 1 + f(ID.area, model="bym", graph = seoul.adj) +
                       f(year, model="rw1") +   # RW of order1
                       f(year1, model="iid") +  # phi_t
                       ln_sec_fac + ln_safe_return_use + pop_female_rate

lcs       <- inla.make.lincombs(year = diag(3), year1 = diag(3))  # Linear Combination gamma_{t} + phi_{t}


model.nd     <- inla(formula,family = "poisson", data = dat, E = E, # E = E or offset = log(E)
                     lincomb = lcs, 
                     control.predictor=list(compute=TRUE), # Compute the marginals of the model parameters
                     control.compute = list(dic = TRUE))   # Compute some model choice criteria

summary(model.nd)

Call:
   c("inla(formula = formula, family = \"poisson\", data = dat, E 
   = E, ", " lincomb = lcs, control.compute = list(dic = TRUE), 
   control.predictor = list(compute = TRUE))" ) 
Time used:
    Pre = 0.559, Running = 0.511, Post = 0.0938, Total = 1.16 
Fixed effects:
                      mean    sd 0.025quant 0.5quant 0.975quant
(Intercept)          8.731 1.519      5.764    8.725     11.727
ln_sec_fac          -0.145 0.073     -0.288   -0.145     -0.002
ln_safe_return_use   0.001 0.009     -0.017    0.001      0.019
pop_female_rate    -16.244 3.021    -22.207  -16.233    -10.346
                      mode kld
(Intercept)          8.714   0
ln_sec_fac          -0.145   0
ln_safe_return_use   0.001   0
pop_female_rate    -16.211   0

Linear combinations (derived):
    ID   mean    sd 0.025quant 0.5quant 0.975quant   mode kld
lc1  1  0.010 0.012     -0.014    0.010      0.035  0.010   0
lc2  2 -0.025 0.011     -0.049   -0.025     -0.002 -0.025   0
lc3  3  0.015 0.012     -0.009    0.015      0.040  0.015   0

Random effects:
  Name    Model
    ID.area BYM model
   year RW1 model
   year1 IID model

Model hyperparameters:
                                              mean       sd
Precision for ID.area (iid component)         6.99     1.98
Precision for ID.area (spatial component)  1827.54  1821.23
Precision for year                        18040.85 18367.45
Precision for year1                        4267.13  3564.47
                                          0.025quant 0.5quant
Precision for ID.area (iid component)           3.77     6.78
Precision for ID.area (spatial component)     121.43  1287.28
Precision for year                           1036.50 12491.68
Precision for year1                           628.50  3305.02
                                          0.975quant    mode
Precision for ID.area (iid component)          11.49    6.37
Precision for ID.area (spatial component)    6653.30  329.23
Precision for year                          66875.70 2696.20
Precision for year1                         13598.00 1719.33

Expected number of effective parameters(stdev): 30.77(0.088)
Number of equivalent replicates : 2.44 

Deviance Information Criterion (DIC) ...............: 1276.30
Deviance Information Criterion (DIC, saturated) ....: 515.92
Effective number of parameters .....................: 30.86

Marginal log-Likelihood:  -744.26 
Posterior marginals for the linear predictor and
 the fitted values are computed

Significance for Variables

회귀계수 (\(\beta\))가 0과 다른지 즉, 예측변수가 강간강제추행에 영향을 미치는 지 알아보기 위해서 Posterior Probability를 이용하였다. 왜냐하면 Posterior probability는 Bayesian에서 \(p\)-value에 대응되는 것으로 고려되기 때문이다.

marginal <- inla.smarginal(model.nd$marginals.fixed$ln_sec_fac)
marginal <- data.frame(marginal)
ggplot(marginal, aes(x = x, y = y)) +
  labs(x = expression(beta[log(sec_fac)]), y = "Density") +
  geom_vline(xintercept = 0, col = "red") +
  geom_hline(yintercept = 0, col = "grey") +
  geom_line() +
  theme_classic()

[1] 0.9771737

➤ 치안시설 수에 대한 회귀계수의 Posterior probability가 80%이상이므로 치안시설 수는 5대강력범죄에 유의하다. 즉, 치안시설수가 감소할수록 5대강력범죄의 위험은 증가한다.

marginal <- inla.smarginal(model.nd$marginals.fixed$ln_safe_return_use)
marginal <- data.frame(marginal)
ggplot(marginal, aes(x = x, y = y)) +
  labs(x = expression(beta[log(safe_return_use)]), y = "Density") +
  geom_vline(xintercept = 0, col = "red") +
  geom_hline(yintercept = 0, col = "grey") +
  geom_line() +
  theme_classic()

[1] 0.538036

➤ 안심귀가스카우트 이용수에 대한 회귀계수의 Posterior probability가 80%이하이므로 안심귀가스카우트 이용수는 5대강력범죄에 유의하지 않다.

marginal <- inla.smarginal(model.nd$marginals.fixed$pop_female_rate)
marginal <- data.frame(marginal)
ggplot(marginal, aes(x = x, y = y)) +
  labs(x = expression(beta[pop_female_rate]), y = "Density") +
  geom_vline(xintercept = 0, col = "red") +
  geom_hline(yintercept = 0, col = "grey") +
  geom_line() +
  theme_classic()

[1] 1

➤ 여성인구비에 대한 회귀계수의 Posterior probability가 80%이상이므로 여성인구비는 5대강력범죄에 유의하다. 즉, 여성인구비가 감소할수록 5대강력범죄의 위험은 증가한다. 이것은 5대강력범죄의 피해자는 강간강제범죄를 제외하고 남성의 비율이 높은 것으로부터 유추할 수 있다.


Mapping

Spatial Effect

Spatio-Temporal Model에서 전체 연구기간에 걸친 전반적인 공간 패턴을 보여주기 위하여 공간 효과에 대한 Map을 그려보았다. 이 때, 공간 패턴은 시간에 영향을 받지 않기 때문에 모든 시간에 대해 일정하며, 가까운 지역들끼리 비슷한 색깔을 가진다면 공간 의존성이 있다고 판단한다.

# Random Effect for spatial structure (ui+vi)
csi  <- model.nd$marginals.random$ID.area[1:25]        # Extract the marginal posterior distribution for each element of the random effects
zeta <- lapply(csi,function(x) inla.emarginal(exp,x))  # The exponential transformation and calculate the posterior mean for each of them

# Define the cutoff for zeta
zeta.cutoff <- c(0.5, 0.9, 1.3, 1.9, 2.3, 2.7, 3.0)

# Transform in categorical variable
cat.zeta <- cut(unlist(zeta),breaks=zeta.cutoff,
                include.lowest=TRUE)

➤ BYM Model은 \(\xi_{i}=u_{i}+v_{i}\)\(u_{i}\)를 모수화기 때문에 marginals.random$ID.area의 총 2K개가 존재한다.

➤ 우리가 관심있는 것은 \(\xi_{i}=u_{i}+v_{i}\)이므로 marginals.random$ID.area[1:25]를 추출한다.


Exceedance probabilities

단순히 공간효과만 비교하는 것보다 초과 확률(Exceedance probabilities)을 비교하는 것도 용이하다. 왜냐하면 초과 확률은 불확실성(Uncertainty)을 고려하기 때문이다. 또한, 단순히 점추정이 1이 넘는 지역이라도 불확실성을 고려한 posterior probability를 보면 cutoff value를 넘지 못할 수 있으며, 그 지역이 위험한 지역이라 선언하기 충분한 신뢰성이 없을 수 있다.

a        <- 0
prob.csi <- lapply(csi, function(x) {1 - inla.pmarginal(a, x)})   # inla.pmarginal : P(x<a)

# Define the cutoff for zeta
prob.cutoff <-  c(0.0, 0.2, 0.4, 0.6, 0.8, 1.0)

cat.prob <- cut(unlist(prob.csi),breaks=prob.cutoff,
                include.lowest=TRUE)

\(P(\exp(\xi_{i}>1)\vert Y) = P(\xi_{i}>0\vert Y)\).


maps.cat.zeta <- data.frame(ESRI_PK=dat.2019$ESRI_PK, cat.zeta=cat.zeta, cat.prob=cat.prob)

#Add the categorized zeta to the spatial polygon
data.boroughs           <- attr(seoul.map, "data")
attr(seoul.map, "data") <- merge(data.boroughs, maps.cat.zeta,
                                 by="ESRI_PK")
# For adding name of Seoul
lbls <- as.character(seoul.map$SIG_ENG_NM)             # 자치구명
spl  <- list('sp.text', coordinates(seoul.map), lbls, cex=.7)

# Map zeta
spplot(obj=seoul.map, zcol= "cat.zeta", sp.layout = spl,
       col.regions=brewer.pal(6,"Blues"), asp=1) 

\(\exp(\xi_{i})\)가 1 보다 크면 전체 연구기간에 걸쳐서 \(i\)번째 지역의 평균 위험(risk)는 전체 지역보다 높은 위험을 가진다.

# Map prob
spplot(obj=seoul.map, zcol= "cat.prob",sp.layout = spl,
       col.regions=brewer.pal(5,"Blues"), asp=1) 


Time Effect

Spatio-Temporal Model에서 모든 지역에 걸친 전반적인 시간 패턴을 보여주기 위하여 시간 효과에 대한 그래프를 그려보았다. 이 때, 시간 패턴은 공간에 영향을 받지 않기 때문에 모든 공간에 대해 일정하다.

# Temporally structured effect (exp(r[t]))
temporal.CAR <- lapply(model.nd$marginals.random$year,
                       function(X){
                         marg <- inla.tmarginal(function(x) exp(x), X)
                         inla.emarginal(mean, marg)
                       })

# Temporally unstructured effect (exp(pi[t]))
temporal.IID <- lapply(model.nd$marginals.random$year1,
                       function(X){
                         marg <- inla.tmarginal(function(x) exp(x), X)
                         inla.emarginal(mean, marg)
                       })


plot(x=c(1,2,3), y=temporal.CAR, type="l",
     ylim=c(0.8,1.2),
     lty=1, col = "red", xaxt="n",
     xlab="t", ylab=expression(paste("exp(", gamma[t],"and", phi[t], ")")))
lines(unlist(temporal.IID), type="l", lty=1, col = "blue")
axis(1, at=1:3)
abline(h=1, lty=2)

# exp(r[t]+pi[t])
temporal.trend <- sapply(model.nd$marginals.lincomb.derived,  
                         function(X){
                           marg <- inla.tmarginal(function(x) exp(x), X)
                           inla.emarginal(mean, marg)
                           # exp(model.intI$summary.lincomb.derived$mean)
                           
                         })

# 95% CI Lower
temporal.lower <- sapply(model.nd$marginals.lincomb.derived,  
                         function(X){
                           marg <- inla.tmarginal(function(x) exp(x), X)
                           inla.qmarginal(0.025, marg)
                         })

# 95% CI Upper
temporal.upper <- sapply(model.nd$marginals.lincomb.derived,  
                         function(X){
                           marg <- inla.tmarginal(function(x) exp(x), X)
                           inla.qmarginal(0.975, marg)
                         })

tm <- data.frame(t=2017:2019, temporal.lower, temporal.trend, temporal.upper)

ggplot(tm, aes(x = t, y = temporal.trend)) +
  geom_line(col="#0000FF") + 
  geom_ribbon(aes(ymin = temporal.lower, ymax = temporal.upper), fill = "#66CCFF", alpha=0.4) +
  scale_y_continuous(limits = c(0.7, 1.3)) +
  geom_hline(yintercept = 1, linetype = 2) +
  scale_x_continuous(breaks = c(2017, 2018, 2019)) +
  labs(y=expression(paste("exp(", gamma[t],"+", phi[t], ")"))) +
  theme_bw()


Estimated Relative Risk

공간효과와 시간효과를 고려하여 추정된 상대적 위험(Relative Risk)summary.fitted.values을 이용하여 확인할 수 있다.

# Estimated Relative risk
est.rr      <- model.nd$summary.fitted.values$mean          

rr.cutoff   <- c(0.5, 0.9, 1.3, 1.9, 2.3, 2.7, 3.0, 3.3)

cat.rr      <- cut(unlist(est.rr),breaks = rr.cutoff,
                   include.lowest = TRUE)

# Posterior probability p(Relative risk > a1|y)
mar.rr  <- model.nd$marginals.fitted.values
a1      <- 1
prob.rr <- lapply(mar.rr, function(x) {1 - inla.pmarginal(a1, x)})

cat.rr.prob <- cut(unlist(prob.rr),breaks = prob.cutoff,
                   include.lowest = TRUE)


maps.cat.rr <- data.frame(ESRI_PK=dat.2019$ESRI_PK, 
                          rr.2017=cat.rr[1:25], rr.2018=cat.rr[26:50], rr.2019=cat.rr[51:75],
                          rr.prob.2017=cat.rr.prob[1:25], rr.prob.2018=cat.rr.prob[26:50], rr.prob.2019=cat.rr.prob[51:75])

#Add the categorized zeta to the spatial polygon
data.boroughs           <- attr(seoul.map, "data")
attr(seoul.map, "data") <- merge(data.boroughs, maps.cat.rr,
                                 by="ESRI_PK")


# Map 
spplot(obj=seoul.map, zcol= c("rr.2017", "rr.2018", "rr.2019"),
       names.attr = c("2017", "2018", "2019"),       # Changes Names
       sp.layout = spl,
       col.regions=brewer.pal(7,"Blues"), as.table=TRUE)

\(\rho_{it}\)가 1 보다 크면, 공간효과와 시간효과를 고려했을 때, \(t\)년도의 \(i\)번째 지역은 전체 지역의 평균(전체 연구기간에 걸쳐서)보다 높은 위험 (risk) 을 가진다.

# Map prob
spplot(obj=seoul.map, zcol= c("rr.prob.2017", "rr.prob.2018", "rr.prob.2019"),
       names.attr = c("2017", "2018", "2019"),       # Changes Names,sp.layout = spl,
       sp.layout = spl,
       col.regions=brewer.pal(5,"Blues"), as.table=TRUE) 

0.8 이상인 지역을 위험이 높은 hot-spot 지역, 0.2 이하인 지역을 위험이 낮은 cool-spot 지역이라 한다.

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".