贝叶斯时空模型-INLA-4

贝叶斯地理统计模型R-INLA-4 贝叶斯时空模型

在前述的内容中,我们介绍了,如何处理空间的数据,利用海拔高度预测降雨量的例子。但是该例子仅仅涉及到的是涉及到回归方程中,考虑影响因素及空间效应。
那么如果我们的数据有时间信息,如何加入到贝叶斯时空分析呢。譬如每年对某一个地区进行疾病的发病率调查,10年数据整合在一起,就可以从时间上或空间上看疾病的变化规律,也就会用到贝叶斯时空模型。

下面我们将介绍贝叶斯时空模型。该文章中,会简化数学计算的过程,主要是针对,在有数据的基础上,如何应用贝叶斯时空模型,找出影响因素,绘制时间变化的空间分布预测图。

1.数据集

我们模拟一个房屋与面积的地理位置数据,从2010年到2015年的房地产数据。因为是模拟数据,不具有任何实际意义,仅仅作为展示。

通过简单的回归方程,发现,房屋价格与面积及年份成正相关,具有统计学意义。说明随时间推迟,房子越值钱,且面积越大价格也越高。符合实际

library(inlabru)
library(INLA)
library(AmesHousing)
rm(list = ls())
library(INLA)
data("PRborder")
data(PRprec)
coords <- as.matrix(PRprec[sample(1:nrow(PRprec)), 1:2])

set.seed(1)
df=as.data.frame(coords)
df1= df %>% mutate(area=rnorm(nrow(coords),120,25),
                  price=area*5+rnorm(nrow(coords),10,5),
                  year=2010)%>% as.tbl()

df=as.data.frame(coords)
df2= df %>% mutate(area=rnorm(nrow(coords),120,25),
                   price=area*4+rnorm(nrow(coords),10,5),
                   year=2011) %>% as.tbl()

df=as.data.frame(coords)
df3= df %>% mutate(area=rnorm(nrow(coords),120,25),
                   price=area*3+rnorm(nrow(coords),16,5),
                   year=2012) %>% as.tbl()

df=as.data.frame(coords)
df4= df %>% mutate(area=rnorm(nrow(coords),120,25),
                   price=area*8+rnorm(nrow(coords),13,5),
                   year=2013) %>% as.tbl()

df=as.data.frame(coords)
df5= df %>% mutate(area=rnorm(nrow(coords),120,25),
                   price=area*7+rnorm(nrow(coords),11,5),
                   year=2014) %>% as.tbl()

df6= df %>% mutate(area=rnorm(nrow(coords),121,15),
                   price=area*5+rnorm(nrow(coords),12,5),
                   year=2015)%>% as.tbl()

df=rbind(df1,df2,df3,df4,df5,df6)

# plot
ggplot(df, aes(x=Latitude,y=Longitude)) + 
  geom_point(aes(color = price)) + 
  facet_wrap(~year)

# glm
fit_glm=glm(price~area+year,data = df)
summary(fit_glm)

glm(formula = price ~ area + year, data = df)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-398.46  -158.55   -12.16   122.23   493.73  

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -96809.399   3697.070  -26.18   <2e-16 ***
area             5.019      0.131   38.32   <2e-16 ***
year            48.128      1.837   26.20   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for gaussian family taken to be 36378.97)

    Null deviance: 212678269  on 3695  degrees of freedom
Residual deviance: 134347545  on 3693  degrees of freedom
AIC: 49308

Number of Fisher Scoring iterations: 2

image.png

2.INLA

INLA 的步骤包括产生Mesh,建立A project,将空间位置与三角形网格点对应,计算spde的空间效应。然后整合data到stack里面。这是建立INLA的关键,最后,写INLA的公式,带入INLA模型。

2.1 Mesh

下面我们利用时空模型来分析,看看房屋价格随时间变化,在空间的分布规律。
首先,根据空间位置,计算Matern空间位置效应,产生一个mesh,为降低运行时间
这里的Mesh设定值为10,20。得到1020个三角形单元。
在绘制Mesh时候,我们用到library(inlabru)包,可以将mesh结合到ggplot里面,inlabru也包含了模型结果的输出,可自行探索。

# Location matrix
coords = df %>% dplyr:::select(Latitude,Longitude) %>% 
  as.matrix

mesh = inla.mesh.2d(coords, max.edge = c(10, 20))
summary(mesh)

# plot mesh
ggplot()+
  gg(mesh)+
  geom_point(data=df,aes(x=Latitude,y=Longitude))

image.png

2.2 spde

上述中关键一步与前几期介绍的不一样的地方是,我们加入了n.group参数,用来指定年份,先看一下Year有多少年的,然后封装在s.index里面。

# spde
Year=length(table(df$year))
spde = inla.spde2.matern(mesh, alpha = 2)
s.index = inla.spde.make.index("w", n.spde = spde$n.spde, n.group = Year)
table(s.index$w.group)

A.price = inla.spde.make.A(mesh = mesh, loc =coords,
                           group = as.numeric(as.factor(df$year)),
                           n.group = Year)

2.3 stack

首先将我们的数据变成matrix,提取出Covariates,将year转换成factor因子。在matrix后的变量,会出现从2010-2014的变量,我们以2010为参照,所以X=data.frame(Xm[,-2]),来去除2010年这一列。

# matrix
df=df %>% mutate(year=as.factor(year))
Xm <- model.matrix(~ -1 + area+year, data = df)
X=data.frame(Xm[,-2])
head(X)
N=nrow(df)

# satck
stack = inla.stack(tag="est",data=list(y=df$price),
                   A = list(1,1,A.price),
                   effects= list(
                     Intercept = rep(1, N),
                     X=X,
                     w = s.index))

dim(inla.stack.A(stack))

2.4 Model fit

建立好数据及mesh以后,我们现在写INLA公式,如果不考虑残差项,那就是固定效应,现在我们增加残差项,及空间与时间效应。直接写在放f()里面。运行时间有点长,耐心等待。关于更多Spatial latent effects,可以参见inla.list.models
这里我们使用AR1,时间自相关函数。

image.png

# inla
formula = as.formula(paste0("y ~ -1 + Intercept + ", paste0(colnames(X), collapse = " + "), 
                            "+ f(w, model = spde,group = w.group,
                            control.group = list(model = 'ar1'))"))
formula

fit_inla = inla(formula,
                data = inla.stack.data(stack), # Don't forget to change the stack!
                control.compute = list(dic = TRUE),
                control.predictor = list(A = inla.stack.A(stack)))

summary(fit_inla)

Call:
   c("inla(formula = formula, data = inla.stack.data(stack), control.compute = 
   list(dic = TRUE), ", " control.predictor = list(A = inla.stack.A(stack)))") 
Time used:
    Pre = 3.05, Running = 162, Post = 2.21, Total = 167 
Fixed effects:
              mean    sd 0.025quant 0.5quant 0.975quant     mode kld
Intercept  -22.645 4.180    -30.852  -22.645    -14.444  -22.645   0
area         5.283 0.029      5.225    5.283      5.340    5.283   0
year2011  -122.201 3.617   -129.308 -122.200   -115.109 -122.196   0
year2012  -235.934 2.893   -241.615 -235.935   -230.257 -235.935   0
year2013   356.431 3.386    349.779  356.433    363.069  356.437   0
year2014   238.186 3.072    232.152  238.187    244.213  238.188   0
year2015    -0.376 3.285     -6.828   -0.375      6.066   -0.373   0

Random effects:
  Name    Model
    w SPDE2 model

Model hyperparameters:
                                          mean    sd 0.025quant 0.5quant 0.975quant   mode
Precision for the Gaussian observations  0.001 0.000      0.001    0.001      0.001  0.001
Theta1 for w                            -3.997 0.049     -4.093   -3.998     -3.899 -4.000
Theta2 for w                             0.973 0.067      0.857    0.967      1.117  0.947
GroupRho for w                          -0.665 0.021     -0.705   -0.665     -0.623 -0.665

Expected number of effective parameters(stdev): 56.81(4.64)
Number of equivalent replicates : 65.06 

Deviance Information Criterion (DIC) ...............: 38409.53
Deviance Information Criterion (DIC, saturated) ....: 3937.44
Effective number of parameters .....................: 55.00

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

上述结果,我们可以看到时间效应的先验分布及area的估计值。

2.5 参数估计

从这个图,可以看到在我们的INLA模型中,各个参数的先验分布。主要是Range参数,可以提供空间相关性的距离。R-INLA-参数介绍

rf <- inla.spde2.result(fit_inla, "w", spde, do.transf = TRUE)
# str(rf)
par(mfrow = c(2, 2), mar = c(3, 3, 1, 0.1), mgp = 2:0)
plot(fit_inla$marginals.hyper[[2]], type = "l", xlab = "beta", ylab = "Density")
plot(rf$marginals.variance.nominal[[1]], type = "l", xlab = "sigma[x]", ylab = "Density")
plot(rf$marginals.kappa[[1]], type = "l", xlab = "kappa", ylab = "Density")
plot(rf$marginals.range.nominal[[1]], type = "l", xlab = "range nominal", ylab = "Density")
par(mfrow=c(1,1))
image.png

2.6 空间效应估计

因为随时间变化,每一年的空间效应也不一样,也就是INLA回归方程中的残差在空间上分布不均。我们可以将这种空间的效应画出来。
同前述预测一样,先用projector建立空的Grid,然后expand grid到研究区域。
然后提取模型中空间效应的的mean与sd。

# predict 
Projection <- inla.mesh.projector(mesh,dims = c(300, 300))
Full.Projection <- expand.grid(x = Projection$x, y = Projection$y)

# get mean for each year
Model=fit_inla
Full.Projection[,paste0("Year",1:Year)] =
  apply(matrix(Model$summary.random$w$mean, ncol = Year), 2,
        function(x) c(inla.mesh.project(Projection, x)))
head(Full.Projection)
          x         y Year1 Year2 Year3 Year4 Year5 Year6
1 -28.29342 -55.87092    NA    NA    NA    NA    NA    NA
2 -28.26937 -55.87092    NA    NA    NA    NA    NA    NA
3 -28.24533 -55.87092    NA    NA    NA    NA    NA    NA
4 -28.22129 -55.87092    NA    NA    NA    NA    NA    NA
5 -28.19725 -55.87092    NA    NA    NA    NA    NA    NA
6 -28.17321 -55.87092    NA    NA    NA    NA    NA    NA

# to raster
library(raster)
dfra=c()
for(i in 1:Year){
  raster_df=Full.Projection %>% dplyr::select(x,y,paste0("Year",i))
  dfr = rasterFromXYZ(raster_df)  #Convert first two columns as lon-lat and third as value                
  #year1=mask(dfr,studyarea)
  dfra=raster::stack(dfr,dfra)
}

plot(dfra)
image.png

上述的空间分布预测只显示了空间效应,如何添加Covariate及year,参见INLA prediction贝叶斯地理统计模型R-INLA-3

参考

1.Geostatistical data
2.Spatial analysis of geotagged data
3.Spatial and spatio-temporal models with INLA
4.Spatio-temporal modeling of areal data. Lung cancer in Ohio
5. Spatio-temporal modeling with INLA

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342