我刚刚发现mgcv::s()
允许一个人为其by
参数提供一个矩阵,允许人们为每个变量组合(以及它们的相互作用,如果是这样)平滑连续变量和单独的光滑需要的话)。但是,我无法从这些模型中获得合理的预测,例如:
library(mgcv) #for gam
library(ggplot2) #for plotting
#Generate some fake data
set.seed(1) #for replicability of this example
myData = expand.grid(
var1 = c(-1,1)
, var2 = c(-1,1)
, z = -10:10
)
myData$y = rnorm(nrow(myData)) + (myData$z^2 + myData$z*4) * myData$var1 +
(3*myData$z^2 + myData$z) * myData$var2
#note additive effects of var1 and var2
#plot the data
ggplot(
data = myData
, mapping = aes(
x = z
, y = y
, colour = factor(var1)
, linetype = factor(var2)
)
)+
geom_line(
alpha = .5
)
#reformat to matrices
zMat = matrix(rep(myData$z,times=2),ncol=2)
xMat = matrix(c(myData$var1,myData$var2),ncol=2)
#get the fit
fit = gam(
formula = myData$y ~ s(zMat,by=xMat,k=5)
)
#get the predictions and plot them
predicted = myData
predicted$value = predict(fit)
ggplot(
data = predicted
, mapping = aes(
x = z
, y = value
, colour = factor(var1)
, linetype = factor(var2)
)
)+
geom_line(
alpha = .5
)
产生输入数据的这个图:
这显然是预测值的错误情节:
将以上的gam替换为:
fit = gam(
formula = y ~ s(z,by=var1,k=5) + s(z,by=var2,k=5)
, data = myData
)
但是否则运行相同的代码会产生这个合理的预测值图:
我在这里做错了什么?
答案 0 :(得分:0)
使用矢量值输入到mgcv平滑点here。在我看来,你误解了这些模型类型。
你的第一个公式
myData$y ~ s(zMat,by=xMat,k=5)
适合模特
y ~ f(z)*x_1 + f(z)*x_2
也就是说,mgcv估计单平滑函数f()。在每个协变量下评估此函数,并将权重提供给参数。
你的第二个公式
y ~ s(z,by=var1,k=5) + s(z,by=var2,k=5)
适合模特
y ~ f_1(z)*x_1 +f_2(z)*x_2
其中f_1()和f_2()是两个不同的平滑函数。您的数据模型本质上是第二个公式,所以它给出一个更合理的外观并不奇怪。
当您需要一个加法模型时,第一个公式很有用,其中在每个变量上使用给定的权重评估单个函数。