2012-12-12 4 views
0

24 개의 매개 변수가있는 최대 우도 추정이 필요한 M 단계에서 EM 추정을 수행하고 있습니다. 나는 R에서 nlm/optim/maxLik 함수를 시도했다. 모두 매우 느리다. 어떤 제안이라도 환영합니다. 감사. (선택이, M, S, K, N 및 알파 알려져있다.)r의 MLE가 매우 느립니다.

logl <- function(theta,choices,M,S,K,N,Alpha){ 

betas <- theta[(1:(S*(K+1)))] 
betas<-matrix(betas,S,K+1,byrow=TRUE) 

loglik <-for (n in 1:N){ 
pr1s=foreach (s=1:S) %dopar%{ 
pr11=foreach (i = 1:K) %dopar%{ 
exp(sum(betas[s,]*choices[[n]][i,]))/exp(sum(M[[i]]%*%betas[s,]))} 
pr11=as.numeric(pr11) 
prod(pr11) 
} 
pr1sn=as.numeric(pr1s) 

l[n]= sum(Alpha*pr1sn) 
} 
L=-sum(log((l))) 
return(L)} 

내가 얻고 싶은 것은 :

ops=nlm(logl,theta.start,choices=choices,M=M,S=2,K=11,N=3,Alpha=Alpha,hessian=TRUE) 
+8

"매우 느린"이란 무엇입니까? 초입니까? 의사록? 시간? 일? paralellization없이 시도 했습니까? 반복 횟수가 적 으면 오버 헤드의 가치가 없을 수도 있습니다. 중첩 된 병렬 루프가 실제로 예상대로 작동하는지는 다소 의심 스럽지만이를 시도한 적이 없습니다. 어떤 부분이 느린지 알아 내고, 벡터화하려고 시도하는 기능을 프로파일 링하십시오. – Roland

+3

더 자세한 정보를 제공해야합니다. 모델을 설명하고 LogL 함수를 수학 표기법으로 작성하고 장난감 데이터 세트를 제공하여 몇 가지 시도를 할 수 있습니다. – Elvis

+1

내가 바꾸고 싶은 첫 번째 일은 (단지 단순하기 때문에) 필요할 때까지 $ \ exp (x) $의 사용을 피하는 것입니다. 적어도 K에 대해 내부 루프를 제거 할 수 있다고 생각합니다. 먼저 분석적으로 $ \ exp (x-y) $와 같은 $ \ frac {\ exp (x)} {\ exp (y)} $를가집니다. 그런 다음 로그 합계의 지수 함수 인 지수 값을 계산합니다. \ exp (x_1-y_1) \ exp (x_2-y_2) ... \ exp (x_K-y_K) = \ exp (x_1 + ... + x_K-y_1 -...- y_K) $. 이것들이 정답에 아무런 차이가 없지만, 그것은 당신의 컴퓨팅 시간에 큰 차이를 만들 수 있습니다. – probabilityislogic

답변

9

I 조언 당신은 당신의 코드를 만들기 위해이는 LogL 기능입니다 더 깔끔한. 일관성있게하십시오. 코드를 읽고 개선하는 것이 더 쉬울 것입니다.

3 개의 루프가 있다는 것을 알고 있습니다. 모두 병렬로 처리 할 수 ​​있지 않습니까? for과 함께 하나의 루프를 수행하고 다른 두 루프를 foreach과 함께 사용하는 이유는 무엇입니까? 그 이유가 있을까요?

이 지정 loglik <- for (n in 1:N)은 무엇을위한 것입니까?

여기에 foreach.combine 인수가 있습니다. 중첩 루프에는 %:% 연산자가 있습니다.

코드 개선을 시도했습니다. 그러나 내가 그것을 정확하게 이해했는지 확실하지 않은 경우. 그리고 그것이 당신보다 빠르면 확실하지 않습니다. 재현 가능한 예는 타이밍에 대한보다 정확한 대답을 제공하는 데 필요합니다.

logl <- function(theta, choices, M, S, K, N, Alpha) { 
    betas <- theta[(1:(S*(K+1)))] 
    betas <- matrix(betas, S, K+1, byrow=TRUE) 

    l <- foreach(n = 1:N, .combine = c) %:% 
    foreach(s = 1:S, .combine = sum) %:% 
     foreach(i = 1:K, .combine = prod) %dopar% { 
     exp(sum(betas[s,] * choices[[n]][i,]))/exp(sum(M[[i]] %*% betas[s,])) 
     } 

    return(-sum(log(Alpha * l))) 
} 
+0

'foreach' 사용법에 대한 좋은 강의! – Elvis