gpt4 book ai didi

r - 在模型列表上使用stepAIC

转载 作者:行者123 更新时间:2023-12-01 18:59:06 28 4
gpt4 key购买 nike

我想对线性模型列表使用AIC进行逐步回归。想法是使用线性模型列表,然后在每个列表元素上应用stepAIC。它失败。

大家好,我试图找出问题所在。
我想我找到了问题。但是,我不明白原因。
尝试代码以查看三种情况之间的区别。

require(MASS)
n<-30
x1<-rnorm(n, mean=0, sd=1) #create rv x1
x2<-rnorm(n, mean=1, sd=1)
x3<-rnorm(n, mean=2, sd=1)
epsilon<-rnorm(n,mean=0,sd=1) # random error variable
dat<-as.data.frame(cbind(x1,x2,x3,epsilon)) # combine to a data frame
dat$id<-c(rep(1,10),rep(2,10),rep(3,10))
# y is combination from all three x and a random uniform variable
dat$y<-x1+x2+x3+epsilon
# apply lm() only resulting in a list of models
dat.lin.model.lst<-lapply(split(dat,dat$id),function(d) lm(y~x1+x2+x3,data=d))
stepAIC(dat.lin.model.lst[[1]]) # FAIL!!!
# apply function stepAIC(lm())- works
dat.lin.model.stepAIC.lst<-lapply(split(dat,dat$id),function(d) stepAIC(lm(y~x1+x2+x3,data=d)))
# create model for particular group with id==1
k<-which(dat$id==1) # manually select records with id==1
lin.model.id1<-lm(dat$y[k]~dat$x1[k]+dat$x2[k]+dat$x3[k])
stepAIC(lin.model.id1) # check stepAIC - works!


我很确定stepAIC()需要data.frame“ dat”中的原始数据。那就是我以前想的。 (希望我是对的)
但是在stepAIC()中没有参数可以传递原始数据帧。显然,对于未包装在列表中的普通模型,足以传递模型。 (代码的最后三行)所以我想知道:
Q1:stepAIC如何知道在哪里可以找到原始数据“ dat”(不仅是作为参数传递的模型数据)?
问题2:如何知道stepAIC()中有另一个未在帮助页面中明确说明的参数? (也许我的英语太难找了)
Q3:如何将该参数传递给stepAIC()?

它必须位于apply函数环境中并传递数据。 lm()或stepAIC()以及指向原始数据的指针/链接都必须在某处丢失。我不太了解R中的环境是做什么的。对我来说,这是一种将局部变量与全局变量隔离的方法。但也许它更复杂。关于上述问题,有人可以向我解释吗?老实说,我从 R documentation中读得很少。任何更好的理解都会对我有所帮助。谢谢。

旧:
我在数据帧df中有数据,该数据帧可以分为几个子组。为此,我创建了一个名为df $ id的groupID。 lm()返回第一个子组的期望系数。我想使用AIC作为每个子组的标准分别进行逐步回归。我使用lmList {lme4},它为每个子组(id)生成一个模型。但是,如果我使用stepAIC {MASS}作为列表元素,则会引发错误。见下文。

所以问题是:我的程序/语法有什么错误?我得到的是单个模型的结果,而不是使用lmList创建的模型。 lmList()是否在模型上存储的信息与lm()不同?
但在帮助中指出:
class“ lmList”:具有通用模型的lm类的对象列表。

>lme4.list.lm<-lmList(formula=Scherkraft.N~Gap.um+Standoff.um+Voidflaeche.px |df$id,data = df)
>lme4.list.lm[[1]]
Call: lm(formula = formula, data = data)
Coefficients:
(Intercept) Gap.um Standoff.um Voidflaeche.px
62.306133 -0.009878 0.026317 -0.015048

>stepAIC(lme4.list.lm[[1]], direction="backward")
#stepAIC on first element on the list of linear models
Start: AIC=295.12
Scherkraft.N ~ Gap.um + Standoff.um + Voidflaeche.px
Df Sum of Sq RSS AIC
- Standoff.um 1 2.81 7187.3 293.14
- Gap.um 1 29.55 7214.0 293.37
<none> 7184.4 295.12
- Voidflaeche.px 1 604.38 7788.8 297.97

Error in terms.formula(formula, data = data) :
'data' argument is of the wrong type


显然,该列表不起作用。但是我不知道这可能是什么。
由于我尝试对创建相同模型(至少相同系数)的基本软件包执行相同操作。结果如下:

>lin.model<-lm(Scherkraft.N ~ Gap.um + Standoff.um + Voidflaeche.px,df[which(df$id==1),]) 
# id is in order, so should be the same subgroup as for the first list element in lmList

Coefficients:
(Intercept) Gap.um Standoff.um Voidflaeche.px
62.306133 -0.009878 0.026317 -0.015048


好吧,这就是我在linear.model上使用stepAIC返回的内容。
据我所知,akaike信息准则可用于估计在给定数据的情况下哪种模型在拟合和泛化之间取得更好的平衡。

>stepAIC(lin.model,direction="backward")
Start: AIC=295.12
Scherkraft.N ~ Gap.um + Standoff.um + Voidflaeche.px
Df Sum of Sq RSS AIC
- Standoff.um 1 2.81 7187.3 293.14
- Gap.um 1 29.55 7214.0 293.37
<none> 7184.4 295.12
- Voidflaeche.px 1 604.38 7788.8 297.97

Step: AIC=293.14
Scherkraft.N ~ Gap.um + Voidflaeche.px
Df Sum of Sq RSS AIC
- Gap.um 1 28.51 7215.8 291.38
<none> 7187.3 293.14
- Voidflaeche.px 1 717.63 7904.9 296.85

Step: AIC=291.38
Scherkraft.N ~ Voidflaeche.px
Df Sum of Sq RSS AIC
<none> 7215.8 291.38
- Voidflaeche.px 1 795.46 8011.2 295.65
Call: lm(formula = Scherkraft.N ~ Voidflaeche.px, data = df[which(df$id == 1), ])

Coefficients:
(Intercept) Voidflaeche.px
71.7183 -0.0151


我从输出中读取了应该使用的模型:Scherkraft.N〜Voidflaeche.px,因为这是最小的AIC。好吧,如果有人可以简短描述输出,那就太好了。我对逐步回归(假设向后消除)的理解是,所有回归变量都包含在初始模型中。然后消除最不重要的一个。决定的标准是AIC。依此类推...某种程度上,我无法正确解释表格。如果有人可以证实我的解释,那就太好了。 “-”(减号)代表消除的回归变量。最重要的是“开始”模型,并在下表中的RSS和AIC进行了计算以消除可能的情况。因此,第一张表中的第一行显示模型Scherkraft.N〜Gap.um + Standoff.um + Voidflaeche.px-Standoff.um将得出AIC 293.14。选择没有Standoff.um的一个:Scherkraft.N〜Gap.um + Voidflaeche.px

编辑:
我将lmList {lme4}替换为dlply()以创建模型列表。
stepAIC仍然无法处理该列表。它引发了另一个错误。实际上,我认为stepAIC需要运行的数据存在问题。我想知道它如何仅从模型数据计算每个步骤的AIC值。我将使用原始数据来构建模型,每次都保留一个回归器。我将据此计算AIC并进行比较。因此,如果stepAIC无法访问原始数据,它将如何工作。 (我看不到将原始数据传递给stepAIC的参数)。不过,我不知道为什么它适用于普通模型,但不适用于列表中的模型。

>model.list.all <- dlply(df, .id, function(x) 
{return(lm(Scherkraft.N~Gap.um+Standoff.um+Voidflaeche.px,data=x)) })
>stepAIC(model.list.all[[1]])
Start: AIC=295.12
Scherkraft.N ~ Gap.um + Standoff.um + Voidflaeche.px
Df Sum of Sq RSS AIC
- Standoff.um 1 2.81 7187.3 293.14
- Gap.um 1 29.55 7214.0 293.37
<none> 7184.4 295.12
- Voidflaeche.px 1 604.38 7788.8 297.97
Error in is.data.frame(data) : object 'x' not found

最佳答案

我不确定版本控制中可能进行了哪些更改,从而使调试变得如此困难,但是一种解决方案是使用do.call,它在执行调用之前先评估调用中的表达式。这意味着,除了在调用中仅存储d之外,updatestepAIC为了执行工作还需要查找d,它存储了数据帧本身的完整表示形式。

那就是

do.call("lm", list(y~x1+x2+x3, data=d))


代替

lm(y~x1+x2+x3, data=d)


通过查看模型的 call元素,您可以看到它正在尝试做什么,也许是这样的:

dat.lin.model.lst <- lapply(split(dat, dat$id), function(d)
do.call("lm", list(y~x1+x2+x3, data=d)) )
dat.lin.model.lst[[1]]$call


也有可能在全局环境中列出数据帧列表,然后构造调用,以便 updatestepAIC依次查找每个数据帧,因为它们的环境链总是引回到全局环境。像这样:

dats <- split(dat, dat$id)
dat.lin.model.list <- lapply(seq_along(dats), function(d)
do.call("lm", list(y~x1+x2+x3, data=call("[[", quote(dats),i))) )


要查看更改,请再次运行 dat.lin.model.lst[[1]]$call

关于r - 在模型列表上使用stepAIC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9161273/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com