Ottenere i giusti valori iniziali per un modello nls in R


12

Sto cercando di adattare un semplice modello di legge di potere a un set di dati che è il seguente:

mydf:

rev     weeks
17906.4 1
5303.72 2
2700.58 3
1696.77 4
947.53  5
362.03  6

L'obiettivo è quello di passare attraverso la linea elettrica e usarla per prevedere i revvlaues per le settimane future. Un gruppo di ricerche mi ha portato alla nlsfunzione, che ho implementato come segue.

newMod <- nls(rev ~ a*weeks^b, data=modeldf, start = list(a=1,b=1))
predict(newMod, newdata = data.frame(weeks=c(1,2,3,4,5,6,7,8,9,10)))

Mentre questo funziona per un lmmodello, ricevo un singular gradienterrore, che capisco ha a che fare con i miei valori iniziali ae b. Ho provato valori diversi, arrivando persino a tracciare questo in Excel, passare un solitario, ottenere un'equazione, quindi utilizzare i valori dell'equazione, ma continuo a ricevere l'errore. Ho guardato un sacco di risposte come questa e ho provato la seconda risposta (non riuscivo a capire la prima), ma senza risultato.

Potrei davvero usare un po 'di aiuto qui su come trovare i giusti valori iniziali. O in alternativa, quale altra funzione posso usare al posto di nls.

Nel caso in cui desideri ricrearlo mydffacilmente:

mydf <- data.frame(rev=c(17906.4, 5303.72, 2700.58 ,1696.77 ,947.53 ,362.03), weeks=c(1,2,3,4,5,6)) 

1
Sebbene dichiarato in termini di R (in realtà deve essere indicato in alcune lingue), come trovare i valori iniziali appropriati per un adattamento del modello non lineare è sufficientemente statistico per essere in argomento qui, IMO. Non è proprio una programmazione Q, ad es.
gung - Ripristina Monica

Risposte:


13

Questo è un problema comune con i modelli dei minimi quadrati non lineari; se i tuoi valori iniziali sono molto lontani dall'ottimale, l'algoritmo potrebbe non convergere, anche se potrebbe comportarsi bene vicino all'ottimale.

Se si inizia prendendo i registri di entrambe le parti e in forma un modello lineare, si ottiene stime di e come la pendenza e intercetta (9,947 e -2,011) (edit: questo è logaritmo naturale)blog(a)b

Se si utilizzano quelli per guidare i valori di partenza per e tutto sembra funzionare bene:bab

 newMod <- nls(rev ~ a*weeks^b, data=mydf, start = list(a=exp(9.947),b=-2.011))
 predict(newMod, newdata = data.frame(weeks=c(1,2,3,4,5,6,7,8,9,10)))
 [1] 17919.2138  5280.7001  2584.0109  1556.1951  1050.1230   761.4947   580.3091   458.6027
 [9]   372.6231   309.4658

È estremamente utile, grazie mille! Ho una domanda su come hai ottenuto il tuo valore "a" qui. Ho provato a eseguire lm (log10 (rev) ~ log10 (settimane)) e quindi utilizzando la funzione "riepilogo", e mentre ottengo lo stesso valore "b", il mio valore "a" esce a 4.3201. Cosa hai fatto diversamente per arrivare a a = 9.947?
NeonBlueHair,

Si noti che ero solito expriportarlo a valori non registrati, il che è un indizio che indica che ho usato la logfunzione semplice . Finché sei coerente con il log e l'antilog che usi, otterrai la stessa risposta per il valore iniziale. Quindi puoi fare la base 10 e io posso fare la base e tutto è uguale. e
Glen_b

Ah, hai perfettamente ragione. Errore amatoriale da parte mia. Ho continuato a pensare alla notazione matematica aspettandomi che "log" significhi log base 10 e "ln" per log naturale. Grazie per il chiarimento.
NeonBlueHair,

1
Per molti matematici (e molti statistici), un "log" disadorno è il log naturale, così come un argomento disadorno a una funzione del peccato è nei radianti. [Le convenzioni in conflitto possono portare alla confusione, sfortunatamente, ma quando ho iniziato a usare R, per esempio, non ci ho pensato due volte sull'uso della funzione log poiché R e condivido la stessa convenzione.]
Glen_b -Restate Monica

4

Provare

 newMod <- nls(rev ~ a*weeks^b, data=mydf, startlist(a=17919.2127344,b=-1.76270557120))

Mi è stato chiesto di espandere un po 'questa risposta. Questo problema è così semplice che sono un po 'sorpreso che nls fallisca. Il vero problema tuttavia è con l'intero approccio R e la filosofia di adattamento del modello non lineare. Nel mondo reale si ridimensionerebbe x in modo da trovarsi tra -1 e 1 e in ye tra 0 e 1 (y = ax ^ b). Sarebbe probabilmente sufficiente per far convergere nls. Naturalmente, come sottolinea Glen, puoi adattare il modello log-lineare corrispondente. Ciò si basa sul fatto che esiste una semplice trasformazione che linearizza il modello. Questo non è spesso il caso. Il problema con le routine R come nls è che non offrono supporto per la parametrizzazione del modello. In questo caso la reparameterizzazione è semplice, basta riscalare / recentre xey. Tuttavia, adattandosi al modello, l'utente avrà diversi parametri aeb da quelli originali. Mentre è semplice calcolare quelli originali da questi, l'altra difficoltà è che non è così semplice in generale ottenere le deviazioni standard stimate per queste stime dei parametri. Questo viene fatto con il metodo delta che coinvolge l'Assia della probabilità logaritmica e alcuni derivati. Il software di stima dei parametri nonlineari dovrebbe fornire automaticamente questi calcoli, in modo che la riparametrizzazione del modello sia facilmente supportata. Un'altra cosa che il software dovrebbe supportare è la nozione di fasi. Puoi pensare di adattare prima il modello con la versione di Glen come fase 1. Il modello "reale" si adatta alla fase 2. l'altra difficoltà è che in generale non è così semplice ottenere le deviazioni standard stimate per queste stime dei parametri. Questo viene fatto con il metodo delta che coinvolge l'Assia della probabilità logaritmica e alcuni derivati. Il software di stima dei parametri nonlineari dovrebbe fornire automaticamente questi calcoli, in modo che la riparametrizzazione del modello sia facilmente supportata. Un'altra cosa che il software dovrebbe supportare è la nozione di fasi. Puoi pensare di adattare prima il modello con la versione di Glen come fase 1. Il modello "reale" si adatta alla fase 2. l'altra difficoltà è che in generale non è così semplice ottenere le deviazioni standard stimate per queste stime dei parametri. Questo viene fatto con il metodo delta che coinvolge l'Assia della probabilità logaritmica e alcuni derivati. Il software di stima dei parametri nonlineari dovrebbe fornire automaticamente questi calcoli, in modo che la riparametrizzazione del modello sia facilmente supportata. Un'altra cosa che il software dovrebbe supportare è la nozione di fasi. Puoi pensare di adattare prima il modello con la versione di Glen come fase 1. Il modello "reale" si adatta alla fase 2. Il software di stima dei parametri nonlineari dovrebbe fornire automaticamente questi calcoli, in modo che la riparametrizzazione del modello sia facilmente supportata. Un'altra cosa che il software dovrebbe supportare è la nozione di fasi. Puoi pensare di adattare prima il modello con la versione di Glen come fase 1. Il modello "reale" si adatta alla fase 2. Il software di stima dei parametri nonlineari dovrebbe fornire automaticamente questi calcoli, in modo che la riparametrizzazione del modello sia facilmente supportata. Un'altra cosa che il software dovrebbe supportare è la nozione di fasi. Puoi pensare di adattare prima il modello con la versione di Glen come fase 1. Il modello "reale" si adatta alla fase 2.

Adatto il tuo modello con AD Model Builder che supporta le fasi in modo naturale. Nella prima fase è stato stimato solo un. Questo porta il tuo modello nel campo da baseball. Nella seconda fase si stima che a e b ottengano la soluzione. AD Model Builder calcola automaticamente le deviazioni standard per qualsiasi funzione dei parametri del modello tramite il metodo delta in modo da incoraggiare una riparametrizzazione stabile del modello.


2

L'algoritmo Levenberg-Marquardt può aiutare:

modeldf <- data.frame(rev=c(17906.4, 5303.72, 2700.58 ,1696.77 ,947.53 ,362.03), weeks=c(1,2,3,4,5,6))

require(minpack.lm)
fit <- nlsLM(rev ~ a*weeks^b, data=modeldf, start = list(a=1,b=1))

require(broom)
fit_data <- augment(fit)

plot(.fitted~rev, data=fit_data)

1

Nella mia esperienza, un buon modo per trovare i valori iniziali per i parametri dei modelli NLR è usare un algoritmo evolutivo. Da una popolazione iniziale (100) di stime casuali (genitori) in uno spazio di ricerca, scegli i 20 migliori (prole) e usali per aiutare a definire una ricerca in una popolazione successiva. Ripeti fino alla convergenza. Non sono necessari gradienti o assiane, solo valutazioni SSE. Se non sei troppo avido questo funziona molto spesso. Il problema che le persone hanno spesso è che stanno usando una ricerca locale (Newton-Raphson) per eseguire il lavoro di una ricerca globale. Come sempre si tratta di utilizzare lo strumento giusto per il lavoro da svolgere. È più sensato utilizzare una ricerca globale di EA per trovare i valori iniziali per la ricerca locale di Newton e quindi ridurla al minimo. Ma, come per tutte le cose, il diavolo è nei dettagli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.