Using R to match a sigmoidal curve

I read the post (Sigmoidal Curve Fit in R). It was marked as duplicated, but I do not see anything related to the messages. And the response provided for the messages was not enough.

I read the web page

Like others, it uses this format to match a string:

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

The problem is that in most cases the values ​​a, b, c were set, and I don't have any hints that I should use for the data set from the set a, b, c. Can someone give me some tips on how to get the parameters?

Here is my set of numbers:

 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) 
+5
source share
3 answers

Fortunately, R offers a homing model for the logistic model. It uses a little reparameterization, but actually the same model as yours: Asym/(1+exp((xmid-input)/scal))

A homing model can evaluate good starting values ​​for you, so you don't need to specify them.

 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)))) 

final schedule

Of course, your data does not support the model. The estimated midpoint is at the right limit of your data range, and therefore parameter estimates (in particular for asymptotes) are very uncertain.

+5
source

The code I used for your data:

  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) 

What it looks like after installation: enter image description here

+2
source

I see two problems.

  • the nls default algorithm is very sensitive to the initial parameter. In your examples, I found it useful to use algorithm='port' . Alternatively, switching to a β€œreliable” implementation can also help.

  • This helps to understand the role of the parameter in your model.

A simple interpretation of your model: A sigmoid goes into y from 0 to a. It reaches the halfway point at x = c. b has the role of tilt, and if the negative model goes from a to 0.

In particular, the test data you submitted, I would evaluate the initial values ​​as follows:

  • The first thing I notice is that your data doesn't exactly β€œclose” to zero, so it might be useful to add an offset d, which is about 1000.
  • a then 5000 or more
  • c somewhere more than 2 - maybe 3
  • b you need to guess - from x 2 to 3.5 your signal jump from 1000 to 6000 gives 5000 differences - divided by a - slope of 1 / 1.5 = 0.66 or more ... allows you to round to one.

So ultimately using the formula

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

gives a fit (also works without d). A search attempt found that setting algorithm='port' made the command even less sensitive to starting values.

+1
source

Source: https://habr.com/ru/post/1233320/


All Articles