我正在使用多元GAM模型来了解有关多个区域的雾趋势的更多信息。雾是由能见度低于某个阈值(<400米)确定的。我们的GAM模型用于确定能见度对一系列气象变量的响应。
但是,我现在面临的挑战是,我真的希望y轴成为实际的可见性观测值,而不是居中平滑。有趣的是,相对于该位置的平均可见性,协变量如何影响可见性,但是对于平均可见性不同的多个位置(因此,0点能见度提高或降低的可比性意义不大)。
为了比较多个位置的结果,我尝试进行y轴实际可见性观察,然后将一条线放在我们有兴趣查看的可见性阈值(400 m) 评估低于该阈值的预测变量值是什么样的(例如,温度与低于400 m的能见度相关联)。
一般来说,我还是GAM和R的初学者,但到目前为止,我已经找到了一些有用的内容。
到目前为止有用的东西:
尝试1.如何为模型中的每个变量提取gam fit Extracting data used to make a smooth plot in mgcv
尝试2.如何使用预测函数重建单变量模型 http://zevross.com/blog/2014/09/15/recreate-the-gam-partial-regression-smooth-plots-from-r-package-mgcv-with-a-little-style/
尝试3.如何使用“拟合”获得看起来像能见度观察的y轴的某种外观-尽管我认为这不是 正确的方法,因为我没有考虑拦截 http://gsp.humboldt.edu/OLM/R/05_03_GAM.html
install.packages("mgcv") #for gam package
require(mgcv)
install.packages("pspline")
require(pspline)
#simulated GAM data for example
dataSet <- gamSim(eg=1,n=400,dist="normal",scale=2)
visibility <- dataSet[[1]]
temperature <- dataSet[[2]]
dewpoint <- dataSet[[3]]
windspeed <- dataSet[[4]]
#Univariable GAM model
gamobj <- gam(visibility ~ s(dewpoint))
plot(gamobj, scale=0, page=1, shade = TRUE, all.terms=TRUE, cex.axis=1.5, cex.lab=1.5, main="Univariable Model: Dew Point")
summary(gamobj)
AIC(gamobj)
abline(h=0)
露点单变量模型 https://imgur.com/1uzP34F
#dummy var that spans length of original covariate
maxDP <-max(dewpoint)
minDP <-min(dewpoint)
DPtrial.seq <-seq(minDP,maxDP,length=3071)
DPtrial.seq <-data.frame(dewpoint=DPtrial.seq)
#predict only the DP term
preds <- predict(gamobj, type="terms", newdata=DPtrial.seq, se.fit=TRUE)
#determine confidence intervals
DPplot <-DPtrial.seq$dewpoint
fit <-preds$fit
fit.up95 <-fit-1.96*preds$se.fit
fit.low95 <-fit+1.96*preds$se.fit
#plot
plot(DPplot, fit, lwd=3,
main="Reconstructed Dew Point Covariate Plot")
#plot confident intervals
polygon(c(DPplot, rev(DPplot)),
c(fit.low95,rev(fit.up95)), col="grey",
border=NA)
lines(DPplot, fit, lwd=2)
rug(dewpoint)
重构露点协变量图 https://imgur.com/VS8QEcp
plot(dewpoint,fitted(gamobj), main="Fitted Response of Y (Visibility) Plotted Against Dew Point")
abline(h=mean(visibility))
rug(dewpoint)
针对露点https://imgur.com/RO0q6Vw绘制的Y的拟合响应
最终,我需要一条水平线,在这里我可以研究相对于400米的预测变量,而不仅仅是响应变量的均值。这样,在平均可见度不同的多个站点中,它是可比的。最重要的是,它必须用于多个协变量!
Gavin Simpson在几篇文章中已经解释了该方法,但是不幸的是,当我使用预测函数时,我真的不明白如何保持其他协变量的平均值不变。
Changing the Y axis of default plot.gam graphs
对此方法进行更深入的说明将非常有帮助!
答案 0 :(得分:0)
我不确定这将有多大帮助,因为您的问号比我们通常在SO上要开放的要开放一些,但是,到了。
首先,我认为考虑对响应变量建模是有帮助的,我认为当前是可见性。这将是一个连续变量,以0为界(也许数据永远不会达到零?),因此建议将数据建模为有条件分布
family = Gamma(link = 'log')
)的可见度永远不会为零。family = tw()
)用于包含零的数据。另一种方法是模拟雾的发生;如果将其定义为可见度<400m的事件,则可以将所有观测值转换为0/1值(如果是大雾事件)。然后,您可以使用family = binomial()
将数据建模为有条件分布的Bernoulli。
决定采用建模方法后,我们需要对响应进行建模。这应该使用多元回归类型的方法来完成,并且GAM包括多个预测变量。通过这种方式,您可以估算每个潜在预测变量对响应的影响,同时控制其他预测变量的影响。如果您一次只使用一个预测变量,例如说dewpoint
,则该变量很可能“解释”数据的变化,这可能是由于另一个预测变量windspeed
引起的,而您不会不知道。
此外,您可能想要控制的预测变量之间可能存在交互,这只能在
中完成然后,为了最终解决问题的症结,已经为“解释”可见性安装了多预测器模型,您将需要从模型中预测可能的条件集。要查看在其他预测变量有影响的模型中可见性随dewpoint
的变化,您需要将其他变量固定为一些合理的值;一种选择是将其设置为平均值(或在任何因子预测变量的情况下为模态值),或其他表示该变量通常值的其他值。您必须使用您的领域知识。
如果模型中存在交互,则需要更改交互中的两个变量,同时将所有其他变量固定为某个值。
假设您没有互动,并且对dewpoint
感兴趣,但是该模型还包含windspeed
。可从拟合模型的cmX
组件中找到用于拟合模型的值的平均风速。您可以只从观察到的windpseed
值中计算出该值,或将其设置为您要使用的某个已知数字。用m
表示拟合,用df
表示包含数据的数据框,然后我们可以创建新数据以在dewpoint
范围内进行预测,同时按住{{1 }}。
windspeed
那你就可以做
mn.windspd <- m$cmX['windspeed']
## or
mn.windspd <- with(df, mean(windspeed))
## or set it some some value
mn.windspd <- 10 # say
然后,您可以使用它来预测拟合模型:
preddata <- with(df,
expand.grid(dewpoint = seq(min(dewpoint),
max(dewpoint),
length = 300),
windspeed = mn.windspd))
现在,我们希望将这些预测恢复到响应规模,并且我们需要一个置信区间,因此我们必须先创建该区间,然后再进行逆变换:
pred <- predict(m, newdata = preddata, type = "link", se.fit = TRUE)
pred <- as.data.frame(pred)
现在,您可以可视化ilink <- family(m)$linkinv
pred <- transform(pred,
Fitted = ilink(fit),
Upper = ilink(fit + (2 * se.fit)),
Lower = ilink(fit - (2 * se.fit)),
dewpoint = preddata = dewpoint)
对响应的影响,同时保持dewpoint
固定。
在您的情况下,您还必须将其扩展为也保持windspeed
不变,但这可以通过相同的方式完成
temperature
,然后按照上述步骤进行预测。
对于一个或两个变量,我在 gratia 包中有一个函数mn.windspd <- m$cmX['windspeed']
mn.temp <- m$cmX['temperature']
preddata <- with(df,
expand.grid(dewpoint = seq(min(dewpoint),
max(dewpoint),
length = 300),
windspeed = mn.windspd,
temperature = mn.temp))
,它将为您完成上述data_slice()
的工作,因此您不必指定其他协变量的平均值:
expand.grid()
从技术上讲,这将找到最接近中值的数据值(对于协变量不变)。如果您想要手段,那么
preddata <- data_slice(m, 'dewpoint', n = 300)
如果您有互动,例如说fixdf <- data.frame(windspeed = mn.windspd, temperature = mn.temp)
preddata <- data_slice(m, 'dewpoint', data = fixdf, n = 300)
和dewpoint
之间,则需要改变两个变量。使用windspeed
再次很容易:
expand.grid()
这将创建一个100 x 100的协变量值网格,以在保持温度恒定的同时进行预测。
对于mn.temp <- m$cmX['temperature']
preddata <- with(df,
expand.grid(dewpoint = seq(min(dewpoint),
max(dewpoint),
length = 100),
windspeed = seq(min(windspeed),
max(windspeed),
length = 300),
temperature = mn.temp))
,您需要执行以下操作:
data_slice()
将此模式扩展到您想要变化的更多协变量,也很容易遵循fixdf <- data.frame(temperature = mn.temp)
preddata <- data_slice(m, 'dewpoint', 'windpseed',
data = fixdf, n = 300)
遵循此模式;我尚未实现expand.grid()
中两个以上的变量。