2012-02-06 3 views
3

선형 모델 목록에서 AIC를 사용하여 단계별 회귀를 수행하고 싶습니다. 아이디어는 선형 모델 목록을 사용하고 각 목록 요소에 stepAIC을 적용하는 것입니다. 그것은 실패합니다.model 목록에서 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"(매개 변수로 전달 된 모델 데이터뿐만 아니라)을 찾는 위치를 어떻게 알 수 있습니까?
Q2 : stepAIC()에 도움말 페이지에 명시되지 않은 다른 매개 변수가 있음을 어떻게 알 수 있습니까? (어쩌면 내 영어가 너무 나쁘다)
Q3 : stepAIC()에 어떻게 매개 변수를 전달할 수 있습니까?

적용 기능의 환경에 있고 데이터를 전달하는 어딘가에 있어야합니다. lm() 또는 stepAIC()와 원시 데이터에 대한 포인터/링크가 어딘가에 없어야합니다. 저는 R의 환경이 무엇인지 잘 이해하지 못했습니다. 저에게는 글로벌 변수와 로컬 변수를 구분하는 것이 었습니다. 그러나 어쩌면 그것의 더 복잡한. 위의 문제와 관련하여 저에게 설명 할 수있는 사람은 누구입니까? 솔직히 나는 R documentation을 많이 읽지 않습니다. 더 나은 이해가 나를 도울 것입니다. 고맙습니다.

올드 : 데이터 프레임이 여러 개의 하위 그룹으로 나눌 수 있습니다. 그 목적을 위해 df $ id라는 groupID를 만들었습니다. lm()은 첫 번째 하위 그룹에 대해 예상대로 coefficent를 반환합니다. 각 하위 그룹별로 AIC를 기준으로 단계별 회귀를 수행하고 싶습니다. 각 하위 그룹 (id)에 대한 모델을 생성하는 lmList {lme4}를 사용합니다. 그러나 stepAIC {MASS}를 list 요소에 사용하면 오류가 발생합니다. 아래를보십시오.

그래서 질문입니다 : 절차/구문에 어떤 실수가 있습니까? 단일 모델에 대한 결과를 얻지 만 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 정보 기준은 어떤 데이터가 주어진 적합성과 일반화간에 어느 모델이 더 잘 균형을 이루는지 평가하는 데 사용될 수 있습니다. 이 최소한의 AIC 때문에 Scherkraft.N ~ Voidflaeche.px :

>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 

은 내가 모델을 사용해야 출력에서 ​​읽습니다. 누군가 출력을 곧 설명 할 수 있다면 좋을 것입니다.계단식 회귀에 대한 나의 이해 (역방향 제거를 가정 함)는 모든 회귀 변수이다. 초기 모델에 포함된다. 그러면 가장 중요한 것은 제거됩니다. 결정할 기준은 AIC입니다. 등등 ... 어떻게 든 나는 해석 된 표를 얻는 데 문제가 있습니다. 누군가 내 해석을 확인할 수 있다면 좋을 것입니다. "-"(빼기)는 제거 된 회귀 변수를 나타냅니다. 맨 위에는 "시작"모델이 있으며 아래 테이블 표에는 가능한 제거를 위해 RSS와 AIC가 계산됩니다. 첫 번째 테이블의 첫 행에 모델 Scherkraft.N ~ Gap.um + Standoff.um + Voidflaeche.px - Standoff.um의 결과는 AIC 293.14가됩니다. Standoff.um없이 하나를 선택 Scherkraft.N ~ Gap.um + Voidflaeche.px을

편집 :
내가 모델 목록을 만들 수 dlply()로 lmList {lme4}을 교체했다. 여전히 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 
+0

그것의 아마 이유를하지만, 'df' 또한 함수이기 때문에 데이터 프레임에 다른 이름을 부여하는 것이 좋습니다. – James

+1

AIC는 편차 설명과 모델 과장 사이의 트레이드 오프입니다. 매개 변수를 추가하거나 편차가 증가하면 벌금이 부과됩니다. – James

+0

(현재) 첫 번째 섹션에서 오류를 재현 할 수 없습니다. 당신은 어떤 결과물을 얻습니까? 그리고 어떤 R 버전을 실행하고 있습니까? – Aaron

답변

4

나는 디버깅 그렇게 어렵게 만들 수있는 버전에서 변경 될 수 있습니다,하지만 하나 개의 솔루션이 그것을 실행하기 전에 호출에서 식을 계산하는 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를 실행 무엇을 참조하십시오. 이 stepAIC가 필요로하는 데이터를 찾기 위해 루프 환경 (즉, 지구 환경에있는)를 벗어날 것으로 보인다으로

+0

[관련 질문] (http://stackoverflow.com/q/7666807/210673)도 참조하십시오. – Aaron

+0

내가 가진 문제는 제공된 데이터에 의존하지 않고 R 버전에 의존하지 않는다고 생각합니다. set.seed (시드)를 시도해 볼 수 있습니까? x1 <-rnorm (n, 평균 = 0, sd = 1); set.seed (seed + 1); x2 <-rnorm (n, 평균 = 1, sd = 1); set.seed (seed + 2); x3 <-rnorm (n, 평균 = 2, sd = 1); set.seed (seed + 3); 엡실론 <-rnorm (n, 평균 = 0, sd = 1) 시드가 <-100이고 시드가 <-99 인. 그러나 제공된 데이터에 관계없이 do.call이 작동하는 것 같습니다. 그게 내 생각에 뭔가 옳지 않다고 생각하게 만든다. – Sebastian

+0

좋아요, 데이터에 대한 아이디어가 있습니다. 나는 완벽한 모델부터 시작하여 단계적으로 축소합니다. 초기 감소 대안으로 AIC가 개선되지 않는 경우 절차가 중단되고 결과적으로 완전한 모델을 얻을 수 있습니다. 축소로 모델을 개선 할 수있는 경우 stepAIC 프로시 저는 검색 공간에서 찾을 수없는 초기 데이터 = d를 사용해야합니다. 따라서 데이터에 의존하는 축소 단계가있는 경우에만 오류가 발생합니다. 샘플 데이터는 매끄럽게 실행될 수 있지만 실제 데이터에서는 프로 시저를 종료 할 수 있기 때문에 이는 매우 까다 롭습니다. 다시 do.call()을 사용하십시오. – Sebastian

3

, 나는 할당 기능을 사용하여 트릭 :

results <- do.call(rbind, lapply(response, function (i) { 
    assign("i", response, envir = .GlobalEnv) 
      mdl <- gls(as.formula(paste0(i,"~",paste(expvar, collapse = "+")), data= parevt, correlation = corARMA(p=1,q=1,form= ~as.integer(Year)), weights= varIdent(~1/Linf_var), method="ML") 
      mdl <- stepAIC(mdl, direction ="backward") 
})) 
+0

감사합니다. 이것이 내 오류의 원인이었습니다. 나는 찾을 수없는 변수의 할당을 <<로 변경하여 글로벌 범위에서 사용할 수있게했습니다. – xiankai

관련 문제