2015-10-09 31 views
5

Przeczytałem post (Sigmoidal Curve Fit w R). Został oznaczony jako zduplikowany, ale nie widzę niczego związanego ze swoimi wpisami. I odpowiedź udzielona na posty nie była wystarczająca.Użycie R do dopasowania krzywa sigmoidalna

Czytałem webpage

podobne do innych, używa tego formatu, aby pasowały do ​​linii:

fitmodel <- nls(y~a/(1 + exp(-b * (x-c))), start=list(a=1,b=.5,c=25)) 

Problem polega na tym, że a, b, c dano w większości przypadków i nie mam wskazówek, które zestaw a, b, c powinienem użyć dla mojego zestawu danych. Czy ktoś mógłby mi doradzić, jak uzyskać parametry?

Oto mój zestaw liczb:

x <- c(3.9637878,3.486667,3.0095444,2.5324231,2.0553019,1.5781806,1.1010594,0.6242821) 
y <- c(6491.314,6190.092,2664.021,2686.414,724.707,791.243,1809.586,541.243) 
+0

trzeba odgadnąć 'a, b, C'. Jeśli masz pojęcie o tym, jak powinna wyglądać krzywa, zawsze pomagasz narysować krzywą o losowych współczynnikach (np. A = 20, b = 0,1, c = 0,2, krzywa (a/(1 + exp (-b *) (xc))), 0, 100) 'i zobacz, jak są twoje domysły sprawdź, czy' xc' jest poprawny. Nie powinno to być 'x^(- c)' – Mateusz1981

+0

Jest to możliwy sposób, ale czy istnieje wszelkie inne możliwe sposoby, aby zrobić to w bardziej "statystycznie przekonujący" sposób? Na przykład, czy można zrobić pętlę, aby znaleźć optymalny zestaw kombinacji a, b, c. Lub, jeśli w ogóle, mogę użyć niektóre funkcje lub polecenia pozostawiają go programowi do obliczenia go dla mnie? – FunnyFunkyBuggy

+0

raz szukałem również tego "grala" Nie znalazłem jeszcze, nie jestem statystykiem, ale myślę, że zgadywanie wartości początkowych jest powszechnym sposobem szacowania parametry równania w 'nlm' – Mateusz1981

Odpowiedz

5

szczęście R oferuje model selfstarting dla modelu logistycznego. Używa ona nieznacznej reparametryzacji, ale jest to naprawdę ten sam model co Twój: Asym/(1+exp((xmid-input)/scal))

Model samostartrujący może oszacować dla ciebie dobre wartości początkowe, więc nie musisz ich określać.

plot(y ~ x) 
fit <- nls(y ~ SSlogis(x, Asym, xmid, scal), data = data.frame(x, y)) 

summary(fit) 
#Formula: y ~ SSlogis(x, Asym, xmid, scal) 
# 
#Parameters: 
#  Estimate Std. Error t value Pr(>|t|) 
#Asym 1.473e+04 2.309e+04 0.638 0.551 
#xmid 4.094e+00 2.739e+00 1.495 0.195 
#scal 9.487e-01 5.851e-01 1.622 0.166 
# 
#Residual standard error: 941.9 on 5 degrees of freedom 
# 
#Number of iterations to convergence: 0 
#Achieved convergence tolerance: 4.928e-06 

lines(seq(0.5, 4, length.out = 100), 
     predict(fit, newdata = data.frame(x = seq(0.5, 4, length.out = 100)))) 

resulting plot

Oczywiście dane tak naprawdę nie obsługują modelu. Oszacowany punkt środkowy leży dokładnie na granicy zakresu danych, dlatego też oszacowania parametrów (w szczególności asymptoty) są bardzo niepewne.

+0

Dziękuję, twoja odpowiedź jest bardzo przydatna dla mnie.Istnieje inne pytanie: dlaczego kształt krzywej nie jest w kształt "S"? To bardziej przypomina wykładniczą krzywą do mnie. Widzę, że twoje równanie jest takie samo jak moje, ale gdzie jest problem? – FunnyFunkyBuggy

+0

Model jest krzywą sigmoidalną. Po prostu nie widzisz górnej części litery S, ponieważ znajduje się poza granicami fabuły. – Roland

1

Widzę dwa problemy.

  1. domyślny algorytm nls jest bardzo czuły na parametr początkowy. W Twoich przykładowych danych okazało się, że użyteczne jest użycie algorithm='port'. Ewentualnie może również pomóc przejście na "solidną" implementację.

  2. Pomaga zrozumieć rolę parametru w modelu.

Prosta interpretacja dla danego modelu jest: esicy idzie y od 0 do a. Osiąga punkt "w połowie" w punkcie x = c. b ma rolę nachylenia, a jeśli jest ujemny, model będzie zamiast niego przechodził od 0 do 0.

szczególności z danymi z badań opublikowanych przez ciebie Chciałbym oszacować wartości początkowe, jak następuje:

  • Pierwszą rzeczą, jaką zauważył - dane nie jest dokładnie „blisko” do zera, więc może to może być przydatne, aby dodać przesunięcie d co stanowi około 1000.
  • a wynosi wtedy 5000 lub większy
  • c jest gdzieś większy 2 - może 3
  • jeden b musi odgadnąć - od 2 do 3,5 x sygnał skacze od 1000 do 6000 daje 5000 różnic - podzielone przez a - nachylenie 1/1,5 = 0,66 lub większe ... l ets round to one.

więc ostatecznie za pomocą wzoru

fitmodel <- nls(y ~a/(1 + exp(-b * (x-c))) + d, start=list(a=5000,b=1,c=3, d=1000)) 

daje Fit (działa również bez d). Podczas próby znalezienia ustawienia ustawienie algorithm='port' spowodowało, że polecenie było jeszcze mniej wrażliwe na wartości początkowe.

2

Kod Kiedyś dopasować swoje dane:

df <- data.frame(x=c(3.9637878,3.486667,3.0095444,2.5324231,2.0553019,1.5781806,1.1010594,0.6242821),      
        y=c(6491.314,6190.092,2664.021,2686.414,724.707,791.243,1809.586,541.243)) 

library(drc) 
fm <- drm(y ~ x, data = df, fct = G.3()) 

plot(fm) 
summary(fm) 

Jak to wygląda po zamontowaniu: enter image description here