[R-br] Regressão segmentada!

Walmes Zeviani walmeszeviani em gmail.com
Quinta Novembro 17 12:08:48 BRST 2011


Ivan,

O modelo que você passou não é contínuo nos "cotovelos". Pelos dados que
passou, penso que você queira um modelo contínuo nas trocas de taxa. Eu fiz
uns ajustes quanto à isso

# modelo não contínuo
curve(segment_lpl(x, b0=7.8, b1=-0.02, b2=-0.01, K=7.5, X0=10, X1=20), -1,
30)

# modelo tri-linear segmentado contínuo
tri.lin <- function(x, x0, b0, x1, b1, x2, b2){
  ## x0: intercepto
  ## b0: inclinação/taxa do primeiro segmento
  ## x1: primeiro "cotovelo", mudança de taxa
  ## b1: inclinação/taxa do segundo segmento
  ## x2: segundo "cotovelo", mudança de taxa
  ## b2: inclinação/taxa do terceiro segmento
  (x0+b0*x)*(x<x1)+
  (x0+b0*x1+b1*(x-x1))*(x>x1)*(x<x2)+
  (x0+b0*x1+b1*(x2-x1)+b2*(x-x2))*(x>x2)
}

curve(tri.lin(x, x0=0, b0=1, x1=2, b1=-1, x2=4, b2=1), -1, 6)
abline(v=c(0,2,4), lty=2)

x <- c(0,0,0,10,10,10,20,20,20,35,35,35)
y <- c(7.77, 7.81, 7.81, 7.60, 7.67, 7.65, 7.60, NA, 7.66, 7.60, 7.42, 7.50)
plot(y~x)
curve(tri.lin(x, x0=7.8, b0=-0.017, x1=10, b1=0, x2=20, b2=-0.01), add=TRUE)

da <- data.frame(x=x, y=y)
da <- da[complete.cases(da),]

> n0 <- nls(y~tri.lin(x, x0, b0, x1, b1, x2, b2), data=da, trace=TRUE,
+           start=list(x0=7.8, b0=-0.017, x1=10, b1=0.001, x2=20,
b2=-0.01))
Erro em nlsModel(formula, mf, start, wts) :
  matriz gradiente singular com estimativas de parâmetros iniciais
>
> tri.lin.model <- deriv3(~(x0+b0*x)*(x<x1)+
+   (x0+b0*x1+b1*(x-x1))*(x>x1)*(x<x2)+
+   (x0+b0*x1+b1*(x2-x1)+b2*(x-x2))*(x>x2),
+   c("x0","b0","x1","b1","x2","b2"),
+   function(x, x0, b0, x1, b1, x2, b2){NULL})
Erro em deriv3.formula(~(x0 + b0 * x) * (x < x1) + (x0 + b0 * x1 + b1 *  :
  Função '`>`' não está na tabela de derivadas
>

Porém, o problema da não convergência não é qualidade do chute mas a função
do modelo em si. Ao usar o o operador lógico "<" (e outros) a nls() não
consegue interpretar para criar a matriz gradiente. O curioso que o modelo
bi-segmentado ela faz, não sei como, mas. O mais apropriado, dado que se os
valores de x0, x1 e x2 fossem conhecidos isso seria um problema de modelo
linear, seria escrever o modelo não linear tirando vantagem disso, dessa
linearidade parcial, e usar o algorithm="plinear" na nls(). No livro MASS
tem usa seção curta, embora suficiente, para entender como fazer isso. Não
sei se os dados que você me mandou são reais ou não, mas entre ficar com
uma trilinear (6 parâmetros) passando por 4 pontos no domínio da
covariável, eu prefiro ajustar uma cúbica (pelo menos usa menos parâmetros,
é contínua). Esse trilinear é ligar com segmentos as médias, e as
inclinações são como se fossem contrastes entre essas médias
(delta_y/delta_x). Note que trilinear requer mais parâmetros do o temos em
grau de liberdade para oferecer!! Outra maneira seria usar a optim() para
fazer o ajuste.

À disposição.
Walmes.

==========================================================================
Walmes Marques Zeviani
LEG (Laboratório de Estatística e Geoinformação, 25.450418 S, 49.231759 W)
Departamento de Estatística - Universidade Federal do Paraná
fone: (+55) 41 3361 3573
VoIP: (3361 3600) 1053 1173
e-mail: walmes em ufpr.br
twitter: @walmeszeviani
homepage: http://www.leg.ufpr.br/~walmes
linux user number: 531218
==========================================================================
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://listas.inf.ufpr.br/pipermail/r-br/attachments/20111117/425f121b/attachment.html>


Mais detalhes sobre a lista de discussão R-br