Eu tenho alguns dados básicos sobre reduções de emissões e custo por carro:
q24 <- read.table(text = "reductions cost.per.car
50 45
55 55
60 62
65 70
70 80
75 90
80 100
85 200
90 375
95 600
",header = TRUE, sep = "")
Sei que essa é uma função exponencial, portanto, espero encontrar um modelo que se encaixe com:
model <- nls(cost.per.car ~ a * exp(b * reductions) + c,
data = q24,
start = list(a=1, b=1, c=0))
mas estou recebendo um erro:
Error in nlsModel(formula, mf, start, wts) :
singular gradient matrix at initial parameter estimates
Eu li várias perguntas sobre o erro que estou vendo e estou percebendo que o problema provavelmente é que preciso de start
valores melhores / diferentes (o que initial parameter estimates
faz um pouco mais de sentido), mas não tenho certeza, considerando o dados que tenho, como calcularia melhores parâmetros.
r
self-study
exponential
starting-values
Amanda
fonte
fonte
exp(50)
eexp(95)
com os valores de y em x = 50 ex = 95. Se você definirc=0
e registrar o log de y (estabelecendo um relacionamento linear), poderá usar a regressão para obter estimativas iniciais do log ( ) que serão suficientes para seus dados (ou se você ajustar uma linha na origem, poderá sair em 1 e use apenas a estimativa para ; isso também é suficiente para seus dados). Se estiver muito fora de um intervalo bastante estreito em torno desses dois valores, você terá alguns problemas. [Como alternativa, tente um algoritmo diferente]b a b bRespostas:
Encontrar automaticamente bons valores iniciais para um modelo não linear é uma arte. (É relativamente fácil para conjuntos de dados pontuais quando você pode apenas plotar os dados e fazer algumas boas suposições visualmente.) Uma abordagem é linearizar o modelo e usar estimativas de mínimos quadrados.
Nesse caso, o modelo tem a forma
para parâmetros desconhecidos . A presença do exponencial nos encoraja a usar logaritmos - mas a adição de torna difícil fazer isso. Observe, porém, que, se é positivo, então será menor do que o menor valor esperado de --e, portanto, pode ser um pouco menos do que o menor observado valor de . (Se puder ser negativo, você também terá que considerar um valor de um pouco maior que o maior valor observado de ).c a c Y Y aa , b , c c uma c Y Y uma c Y
Vamos, então, cuidar de usando como estimativa inicial algo como metade do mínimo das observações . O modelo agora pode ser reescrito sem esse termo aditivo espinhoso comoc c0 0 yEu
Que podemos pegar o log de:
Essa é uma aproximação linear ao modelo. Ambos e podem ser estimados por mínimos quadrados.registro( Um ) b
Aqui está o código revisado:
Sua saída (para os dados de exemplo) é
A convergência parece boa. Vamos traçar isso:
Funcionou bem!
Ao automatizar isso, você pode executar algumas análises rápidas dos resíduos, como comparar seus extremos com a dispersão nos dados ( ). Você também pode precisar de código análogo para lidar com a possibilidade ; Deixo isso como um exercício.a < 0y a < 0
Outro método para estimar valores iniciais baseia-se na compreensão do que eles significam, que podem ser baseados em experiência, teoria física etc. Um exemplo extenso de um ajuste não-linear (moderadamente difícil) cujos valores iniciais podem ser determinados dessa maneira é descrito em minha resposta em /stats//a/15769 .
A análise visual de um gráfico de dispersão (para determinar as estimativas iniciais dos parâmetros) é descrita e ilustrada em /stats//a/32832 .
Em algumas circunstâncias, é feita uma sequência de ajustes não lineares em que você pode esperar que as soluções mudem lentamente. Nesse caso, geralmente é conveniente (e rápido) usar as soluções anteriores como estimativas iniciais para as próximas . Lembro-me de usar essa técnica (sem comentários) em /stats//a/63169 .
fonte
Esta biblioteca conseguiu resolver meu problema com o nls
singular gradient
: http://www.r-bloggers.com/a-better-nls/ Um exemplo:fonte
nls.lm
agora.Então ... acho que interpretei errado isso como uma função exponencial. Tudo que eu precisava era
poly()
Ou, usando
lattice
:fonte