2016-10-17 9 views
0

저는 R이 처음이므로 도움을 주셔서 감사합니다. 제약 조건에 대한 최적화 문제가 있습니다. R에서 최적화를 해결하는 방법은 여러 가지가 있지만, 적용해야하는 제약 조건을 올바르게 표현할 수는 없습니다.주문 제한이있는 LS 회귀

가정하자 I 세 가지 범주에 다음 데이터가 :

A<-c(99.1, 96.5, 94.4, 92.7, 91.5, 91.3, 91.4, 90.1, 87.1, 82.6, 76.4) 
B<-c(146.4, 140.2, 133.6, 126.5, 118.7, 109.4, 101.2, 101.8, 103.7, 102.5, 98.3) 
C<-c(237.5, 213.9, 191, 168.9, 147.4, 124.9, 108.3, 95.7, 84.4, 73.5, 63) 
t<-seq(1:11) 
DT<-cbind.data.frame(t,A,B,C) 

제가 각각의 카테고리에 지수 함수 Y (t) 데이터 포인트 맞게 싶은 (제곱 오차를 최소화)를 그래서 Y (t) _c> Y (t) _B> Y (t) _a> 선택된 t위한 0 [1, 15]

답변

0

I는 회귀에 제약을 통합하려고하지 않을 것이다. 단지 세 개의 회귀 구성 :

fit_loga <- lm(y ~ log(A) + t, data=DT) 
fit_logb <- lm(y ~ log(B) + t, data=DT) 
fit_logc <- lm(y ~ log(C) + t, data=DT) 

fit_a <- exp(A) 
fit_b <- exp(B) 
fit_c <- exp(C) 

후가 그 범위에 사방 제약을 만족하는지 확인 (또는 적어도 모든 데이터 포인트의 정수) (fit_c > fit_b) & (fit_b > fit_a). 단지 그렇지 않다면 우리는 그것에 대해 걱정합니다. 같은 아마도 모델에 t에 다른 측면에서 exp(t), I(t^2), poly(t, <order>) ...

편집을 던져 : 나는 solnp 패키지 몰랐다.

+0

감사 : 위의 데이터를 사용하여 , 나는 다음있어! 나는 당신이 제안한 것처럼 두 단계로 생각하고 있었지만 C가 B와 A를 명확하게 교차시킬 때이 경우 어떻게 할 것입니까? 모든 커브에 대해 동일한 커브 형식 (여기서는 지수)을 유지해야 할까봐 걱정됩니다. 따라서 하나의 매개 변수는 다른 매개 변수에 영향을 미치므로 최적화를 한꺼번에 수행해야합니다. 지수 곡선에 맞추기보다는 로그 공간에서 선형 커브의 매개 변수를 찾아야한다는 것에 전적으로 동의합니다. – Walle

+0

이런 쓰레기. 그럼 그들이 교차하면 어떻게 그 제약 조건을 적용할까요? min/max를 사용하여 클램핑과 같은 일을하지 않고? – smci

+1

불균형 제약을 처리 할 수있는 {solnp()}와 같은 최적화 함수로 문제를 해결할 수 있다고 생각했습니다. 그러나 주어진 constrains으로 제곱 된 오차를 최소화하기 위해 직접적으로 적용될 때 수렴 할 수 없거나 결과를 얻을 수 없다. – Walle

0

나는 solnp을 사용하여 얻는 오류 메시지가 대부분 부적절한 제약을 의미한다고 생각했습니다. 또한 문서에 명시된 바와 같이 모든 매개 변수를 하나의 벡터에 넣어야합니다. 코드를 적절하게 조정 한 후에는 문제를 변경하지 않고도 y(t)_c > y(t)_b > y(t)_a > 0의 제약 조건을 직접 구현할 수있었습니다. 가장 편리한 방법은 해석을위한 행렬 형성을 사용하는 것입니다. 회신 SMCI에 대한 Results shown here

library(data.table) 
library(Rsolnp) 

t<-as.vector(10:20) 
DT<-cbind.data.frame(A,B,C) 
tlogDT<-transpose(log(DT)) 

# min[log(y)'- Ax-b] 
# Arr = [A1 A2 .. An b1 b2 .. bn] 

gofn = function(arrin) 
{ 
    arr = cbind(arrin[1:3],arrin[4:6]) 
    sum(
    (as.matrix(arr[,1])%*%t + arr[,2] - tlogDT)^2 
) 
} 

nocross=t #defines the times where the curves are not allowed to intersect 
ineqfn2=function(arrin) 
{ 
    #constrains: 
    # 0<f_a(t)<f_b(t)<f_c(t), for some t, 
    arr = cbind(arrin[1:3],arrin[4:6]) 
    nextarr=as.matrix(rbind(rep(0,2),arr[1:(length(arr[,1])-1),])) 
    ineqmat=as.matrix(arr[,1])%*%nocross+arr[,2]-nextarr[,1]%*%nocross-nextarr[,2] 
    as.vector(t(ineqmat)) 
} 

#lines should be aligned with the first startvalue 
eqfn = function(arrin) 
{ 
    arr = cbind(arrin[1:3],arrin[4:6]) 
    arr[,1]*t[1]+arr[,2]-tlogDT[,1] 
} 
#start values: 
An=c(1,1,1) 
bn=tlogDT[,1] 
vstart=c(An,bn) 

r <- solnp(
    vstart, gofn, 

    eqfun = eqfn, eqB= c(0,0,0), 

    ineqfun = ineqfn2, 
    ineqLB = rep(0,length(DT[1,])*length(nocross)), 
    ineqUB = rep(5000,length(DT[1,])*length(nocross)) 
) 

r$pars[1] 
line1 = exp(r$pars[4]+r$pars[1]*t) 
line2 = exp(r$pars[5]+r$pars[2]*t) 
line3 = exp(r$pars[6]+r$pars[3]*t) 

plot(t, DT[,3],log = "y") 
points(t, DT[,2],col="green") 
points(t, DT[,1],col="blue") 

lines(t, line1,lwd=2, col = "blue", xlab = "Time (s)", ylab = "Counts") 
lines(t, line2,lwd=2, col = "green", xlab = "Time (s)", ylab = "Counts") 
lines(t, line3,lwd=2, col = "black", xlab = "Time (s)", ylab = "Counts")