Mam podstawowe dane na temat redukcji emisji i kosztu na samochód:
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 = "")
Wiem, że jest to funkcja wykładnicza, dlatego spodziewam się, że uda mi się znaleźć model pasujący do:
model <- nls(cost.per.car ~ a * exp(b * reductions) + c,
data = q24,
start = list(a=1, b=1, c=0))
ale pojawia się błąd:
Error in nlsModel(formula, mf, start, wts) :
singular gradient matrix at initial parameter estimates
Przeczytałem mnóstwo pytań na temat błędu, który widzę i rozumiem, że problemem jest prawdopodobnie to, że potrzebuję lepszych / różnych start
wartości ( initial parameter estimates
ma to trochę więcej sensu), ale nie jestem pewien, biorąc pod uwagę dane, które mam, jak poszedłbym na temat szacowania lepszych parametrów.
r
self-study
exponential
starting-values
Amanda
źródło
źródło
exp(50)
iexp(95)
do wartości y przy x = 50 i x = 95. Jeśli ustawiszc=0
i weź dziennik y (tworząc relację liniową), możesz użyć regresji, aby uzyskać wstępne szacunki dla dziennika ( ) ib, które będą wystarczające dla twoich danych (lub jeśli dopasujesz linię przez początek, możesz wyjść a na 1 i po prostu użyj szacunku dla b ; to również wystarcza dla twoich danych). Jeśli b jest znacznie poza dość wąskim przedziałem wokół tych dwóch wartości, napotkasz pewne problemy. [Alternatywnie spróbuj innego algorytmu]Odpowiedzi:
Automatyczne znajdowanie dobrych wartości początkowych dla modelu nieliniowego jest sztuką. (Jest to stosunkowo łatwe w przypadku jednorazowych zestawów danych, gdy można po prostu wykreślić dane i dokonać pewnych domysłów wizualnie.) Jednym z podejść jest linearyzacja modelu i użycie oszacowań metodą najmniejszych kwadratów.
W takim przypadku model ma formę
dla nieznanych parametrów . Obecność wykładnicza zachęca nas do korzystania z logarytmów - ale dodanie c utrudnia to. Zauważmy jednak, że jeśli jest dodatnie, to C jest mniejsza od najmniejszej wartości oczekiwanej Y --and zatem może być nieco mniejsza niż najmniejszy obserwowanych wartości Y . (Jeśli a może być ujemne, musisz również wziąć pod uwagę wartość c, która jest nieco większa niż największa obserwowana wartość Y ).a , b , c do za do Y Y za do Y
Zajmijmy się zatem , stosując jako wstępne oszacowanie c 0 około połowy minimum obserwacji y i . Model można teraz przepisać bez tego kolczastego dodatku jakdo do0 yja
Że możemy wziąć dziennik:
Oto poprawiony kod:
Jego dane wyjściowe (dla przykładowych danych) to
Konwergencja wygląda dobrze. Nakreślmy to:
Działa dobrze!
Inna metoda szacowania wartości początkowych polega na zrozumieniu, co one oznaczają, co może być oparte na doświadczeniu, teorii fizycznej itp . Rozszerzony przykład (umiarkowanie trudnego) dopasowania nieliniowego, którego wartości początkowe można określić w ten sposób, opisano w mojej odpowiedzi na /stats//a/15769 .
Analiza wizualna wykresu rozrzutu (w celu określenia wstępnych oszacowań parametrów) została opisana i zilustrowana na stronie /stats//a/32832 .
W niektórych okolicznościach powstaje sekwencja nieliniowych dopasowań, w której można oczekiwać, że rozwiązania będą się zmieniać powoli. W takim przypadku często wygodne (i szybkie) jest użycie poprzednich rozwiązań jako wstępnych szacunków dla następnych . Pamiętam, używając tej techniki (bez komentarza) na /stats//a/63169 .
źródło
Ta biblioteka była w stanie rozwiązać mój problem z nls
singular gradient
: http://www.r-bloggers.com/a-better-nls/ Przykład:źródło
nls.lm
teraz wywoływana .Więc ... Myślę, że źle odczytałem to jako funkcję wykładniczą. Potrzebowałem tylko
poly()
Lub używając
lattice
:źródło