具有多个变量(包括分类变量)的非线性建模

机器算法验证 r 非线性回归 广义加法模型 nls
2022-04-10 13:37:33

我正在尝试对有关捕食者猎物相互作用实验(n = 26)的一些数据进行建模。捕食率是我的响应变量,我有 4 个解释变量:捕食者密度(1、2、3、4 5)、捕食者大小、猎物密度(5、10、15、20、25、30)和猎物类型(3 个类别)。我从几个线性模型(GLM)开始,发现(如预期的那样)猎物和捕食者的密度与捕食率呈非线性关系。如果我对这些变量使用对数变换,我会得到非常好的曲线和调整后的为 0.82,但这并不是建模非线性关系的真正正确方法。R2

model <-glm(rates ~ log(pred) + log (prey) + type)

因此我切换到非线性最小二乘回归(nls)。我有几个基于现有生态文献的捕食者 - 猎物模型,例如:

 ### Holling's type II functional response

model1 <- nls(rates ~ (a * prey)/(1 + b * prey),
start = list(a = 0.27,b = 0.13), trace = TRUE)

### Beddington-DeAngelis functional response

model2 <- nls(rates ~ (a*prey)/(1+ (b * prey) + c * (pred -1 )),
start = list(a=0.22451, b=-0.18938, c=1.06941), trace=TRUE, subset=I1) 

这些模型完美地工作,但现在我也想添加猎物类型。在线性模型中,猎物类型是最重要的变量,所以我不想忽略它。我知道你不能在 nls 中添加分类变量,所以我想我尝试一个广义加法模型(GAM)。

gam 模型的问题在于平滑器(样条曲线和黄土)对这两个变量都不起作用,因为猎物密度和捕食者密度的值数量非常有限。我可以设法得到一个使用黄土平滑的单个变量的模型。但是对于两个变量,它根本不起作用。样条函数根本不起作用,因为我的变量值(5)太少(参见模型 4)。

model3 <- gam(rates~ lo(pred, span=0.9)+prey)
## this one is actually working but does not include a smoother for prey.

model4 <- gam(rates~ s(pred)+prey)
## this one gives problems: 
A term has fewer unique covariate combinations than specified maximum degrees of freedom

我的问题是:是否有任何其他可能性来使用 2 个非线性相关变量对数据进行建模,其中我还可以包含一个分类变量。我更喜欢使用nls( model2) ,例如每个类别的不同截距,但我不确定如何排序,如果可能的话。数据集太小,无法将其分为三类,而且其中一类仅包含 5 个数据点。

1个回答

对于迟到的回复,我深表歉意,但我最近遇到了同样的问题。我发现可以使用 nls() 对分类变量进行编码,只需将真/假向量乘以方程即可。例子:

# null model (no difference between groups; all have the same coefficients)
nls.null <- nls(formula = percent_on_cells ~ vmax*(Time/(Time+km)),
            data = mehg,
            start = list(vmax = 0.6, km = 10))

# alternative model (each group has different coefficients)
nls.alt <- nls(formula = percent_on_cells ~ 
              as.numeric(DOC==0)*(vmax1)*(Time/(Time+(km1))) 
            + as.numeric(DOC==1)*(vmax2)*(Time/(Time+(km2)))
            + as.numeric(DOC==10)*(vmax3)*(Time/(Time+(km3)))
            + as.numeric(DOC==100)*(vmax4)*(Time/(Time+(km4))),
            data = mehg, 
            start = list(vmax1=0.63, km1=3.6, 
                         vmax2=0.64, km2=3.6, 
                         vmax3=0.50, km3=3.2,
                         vmax4= 0.40, km4=9.7))

虽然,使用 4 个不同的分类变量,这可能会让编码变得乏味。您必须非常小心您的设计矩阵。