Sigmoid function shaping and fitting by curve-fitting toolbox
22 views (last 30 days)
I am trying to fit a sigmoid function to my data.
x=1 2 3 4 5 6 7 48
y= 119 163 240 395 617 1461 4310 36955464
first seven data are Electric Vehicles in a country corresponding to year number 1 to 7, and last data (48, 36955464) is the 48th year data.
I have fitted a Logistic Curve as y=36.955.464/(1+119*e^-0,425x)
However, although it fits my data well and ends up showing an expected curve, I need to shape the curve a bit. For instance, parabolic part of the logistic function has to be a bit stronger (neds to increase a bit faster), while exponential part of the sigmoid curve should increase slower.
Is there any other suggestion to fit an adjustable Sigmoid Curve to build up a nicer curve? For example, if I prefer to construct a Hyperbolic Tangent curve (which is also a S-shaped function) how should I construct it ?
Best wishes to all Matlab community
William Rose on 5 Jul 2022
A fairly general sigmoid curve can be expressed with four parameters: ymin, ymax, x0, and slope (dy/dx) at x0. The wikipedia article Sigmoid Function has equations for various sigmoid functions. It has a nice plot comparing different functions. The functions in the wikipedia image all have ymin=-1, ymax=+1, x0=0, and slope=1 at x=0. The image shows that different sigmoid funcitons with the same central slope, and the same upper and lower limits (ymin and ymax) differ in how rapidly they approach the asymptotes. Therefore you can try the different functions and select the one whose results you like.
I do not really understand what you mean by a "nicer curve". You said it "needs to increase a bit faster", etc. When you say "it needs to...", do you means based on the eye-test of what looks good, or some quantifiable goodness of fit criterion? I do not know what you mean by the "parabolic" and "exponential" parts of the curve. Perhaps you mean the left side and the ridght side? Or the middle versus the outpr parts? Typical sigmoid curves are symmetrical about the center.
The equations given for sigmoid functions in the wikipedia article all are centered at x=0. Replace "x" with "(x-x0)" in the wikipedia equations, and set x0 as you wish, to get sigmoid curves that are centered at x=x0.
The hyperbolic tangent funciton is just a shifted and scaled version of the logistic function, so it has the exact same shape as the logistic function, when the parameters are adjusted appropriately. The hyperbolic tangent function is
Replace x with x-x0 to shift the curve horizontally, and add a vertical shift and scale, as you wish. I notice that your logistic function has ymin=0, which is a sensible choice for the number of EVs in a coutry at early times. To shift the hyperbolic tangent function so that it has ymin=0, do this:
In the equation above, k determines the slope at the center. The center is at x=x0. The max value is ymax. You can show with a bit of algebra that the equation above is eqivalent to a logistic function. Notice that the immediately preceding equation has 3 adjustable parameters: ymax, k, and x0. I said earlier that a general sigmoid function has 4 adjustable parameters. The equation above has only three, because we fixed ymin at 0, thus eliminating one adjustable parameter.
Good luck with your work.
More Answers (1)
Sam Chak on 5 Jul 2022
Edited: Sam Chak on 6 Jul 2022
Edit 2: Since the shape of the Black curve is preferred, Gompertz function is proposed for the fitting.
Click on the link to understand how you can adjust parameters b and c to obtain the fine-tune desired shape.
x = [1 2 3 4 5 6 7 48];
y = [119 163 240 395 617 1461 4310 36955464];
% Proposed non-symmetrical S-shaped Gompertz function
xx = linspace(1, 48, 47001);
a = 36955464; % a stands for amplitude (max value of y data)
b = 5.631e-09; % adjust the displacement in x-axis (if d is tuned, leave b = 0)
c = 0.2184; % growth rate (or the slope)
d = 17.08; % adjust the displacement in x-axis (if b is tuned, leave d = 0)
yy = a*exp(-exp(-b - c*(xx - d)));
plot(xx, yy, 'linewidth', 1.5), hold on
plot(x, y, 'ro', 'MarkerSize', 10)
grid on, xlabel('x'), ylabel('y'), hold off
legend('Gompertz', 'data', 'location', 'northwest', 'FontSize', 10)
General Gompertz model:
f(x) = a*exp(-exp(-b - c*(x - d)))
Coefficients (with 95% confidence bounds):
a = 3.7e+07 (3.654e+07, 3.746e+07)
b = 5.631e-09 (fixed at bound)
c = 0.2184 (-0.04142, 0.4782)
d = 17.08 (5.059, 29.09)
Goodness of fit:
Adjusted R-square: 1