fitting data with a combination of exponential and linear form ( a*exp(-x/b)+c*x+d )

조회 수: 27 (최근 30일)
Hello Altruists,
I have been trying to fit my data to a combination of exponential and linear form, i.e., a*exp(-x/b)+c*x+d . I am not getting a good fit (image attached). I am getting an warning as well (Warning: Start point not provided, choosing random start point). Could anyone offer some help?
I have tried with this code:
data= readmatrix('data');
x= data(:,1);
y = data(:,2);
% getting fitting parameters
explinearfit = fittype('a*exp(-x/b)+c*x+d')
fo = fitoptions(explinearfit);
fo.normalize = 'on';
myFit = fit(x,y,explinearfit);
%plot
plot(myFit,x,y)
ylabel('Y')
xlabel('X')
legend('Data','Fit', 'location', 'best')

답변 (4개)

Matt J
Matt J 2023년 7월 4일
편집: Matt J 2023년 7월 4일
If you download fminspleas, you can get a pretty good fit with a fairly naive initial guess [b,e,f]=[-1,0,0]:
[x,y]=readvars('data.csv');
flist={ @(p,x)exp(p(1)*x) ,@(p,x) x, 1, @(p,x)tanh(p(2)*x+p(3))};
warning off
[p,coeff]=fminspleas(flist,[-1,0,0],x,y,-inf(1,3),[0,inf,inf]); warning on
p(:).'
ans = 1×3
-0.0007 0.0005 0.0075
xs=linspace(min(x),max(x));
plot(x,y,'--g',xs, ffit(xs,p,coeff,flist));
function y=ffit(x,p,coeff,flist)
y=0;
for i=1:numel(flist)
f=flist{i};
if isnumeric(f)
y=y+coeff(i)*f;
else
y=y+coeff(i)*f(p,x);
end
end
end

Torsten
Torsten 2023년 7월 3일
이동: Torsten 2023년 7월 3일
Try
f(x) = a*atan(b*x)
It's too steep at the beginning and too flat at the end, but better than your model function.
data= readmatrix('data');
x = data(:,1);
y = data(:,2);
f = @(p) p(1)*atan(p(2)*x);
fun = @(p) f(p) - y;
sol = lsqnonlin(fun,[2/pi 1])
Local minimum possible. lsqnonlin stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
sol = 1×2
0.6070 0.0006
hold on
plot(x,y,'o')
plot(x,f(sol))
hold off
  댓글 수: 1
Md Shariful Islam
Md Shariful Islam 2023년 7월 3일
Thanks for your time answering my question. I appreciate this.
If I use 2 expoential functions (a*exp(b*x)+c*exp(d*x)), I could achieve a better fit as well. I used curve fitting tool achieve the fitting parameters. I was looking for something better; that is why I was exploring to linear+exponential form.
"
clc; clear; close all;
%%
data= readmatrix('data');
x= data(:,1);
y = data(:,2);
a = 0.7057;
b = 1.746e-05;
c = -0.6389;
d = -0.0006763;
y_f= a*exp(b*x)+c*exp(d*x);
figure;
plot(x,y, 's')
hold on
plot(x,y_f)
ylabel('X')
xlabel('Y')
legend('data', 'fit')
set(gca, 'fontname', 'times', 'fontsize', 12)
box on
"

댓글을 달려면 로그인하십시오.


Alex Sha
Alex Sha 2023년 7월 4일
If taking fitting function as "y=a*exp(-x/b)+c*x+d", the result will be:
Sum Squared Error (SSE): 0.473516174967249
Root of Mean Square Error (RMSE): 0.0194398036424297
Correlation Coef. (R): 0.993172772220197
R-Square: 0.986392155479551
Parameter Best Estimate
--------- -------------
a -0.626947642051749
b 1365.46862978889
c 1.57136165222552E-5
d 0.682801486192597
If taking fitting function as "y=a*exp(b*x)+c*exp(d*x)", the result will be:
Sum Squared Error (SSE): 0.517841961771885
Root of Mean Square Error (RMSE): 0.0203293308633968
Correlation Coef. (R): 0.992531430423344
R-Square: 0.985118640378209
Parameter Best Estimate
--------- -------------
a -0.637793104918275
b -0.00067464442828496
c 0.705787394940032
d 1.74592589676531E-5
A much better result will be obtained if taking fitting function as "y=a*exp(b*x)+c*x+d+tanh(e*x+f)*p"
Sum Squared Error (SSE): 0.154723411889559
Root of Mean Square Error (RMSE): 0.0111122622277951
Correlation Coef. (R): 0.997774312797138
R-Square: 0.995553579277802
Parameter Best Estimate
--------- -------------
a -0.44380788683452
b -0.000338851451599573
c 1.0070723631259E-5
d 0.571547658395962
e 0.0025117355962601
f -0.850904593274322
p 0.195041944730927
  댓글 수: 3
Torsten
Torsten 2023년 7월 4일
편집: Torsten 2023년 7월 4일
Try if you can reproduce the results if you use the fitting parameters as initial guesses in MATLAB.
@Alex Sha has his "special tool" to do the fitting (not part of MATLAB), and I think he invests quite a long time to adequate initial guesses for the parameters.
Alex Sha
Alex Sha 2023년 7월 5일
I'm ashamed that it's not my product, although hopefully it's a commercial optimization solver package, I just like to use it because it's simple to use but works well.

댓글을 달려면 로그인하십시오.


Sam Chak
Sam Chak 2023년 7월 5일
The data seems to exhibit the pattern of an nth-root function (a form of the power function), given by
where is a negative exponent function that varies with x. Because the data is bounded by 1, we can assume that . Since the exponential function-based models yield some good results in @Alex Sha's fitting, I attempted with the following model:
Fit model #1
% Data Sets
[x, y] = readvars('data.csv');
% Curve-fitting
fo = fitoptions('Method', 'NonlinearLeastSquares', ...
'Lower', [-0.9, -0.006, -0.07, -0.0002, -1.2, -0.04, -0.2, -0.0008], ...
'Upper', [0, 0, 0, 0, 0, 0, 0, 0], ...
'StartPoint', [1 1 1 1 1 1 1 1]);
ft = fittype('x^(a*exp(b*x) + c*exp(d*x) + e*exp(f*x) + g*exp(h*x))', 'options', fo);
[yfit, gof] = fit(x, y, ft)
yfit =
General model: yfit(x) = x^(a*exp(b*x) + c*exp(d*x) + e*exp(f*x) + g*exp(h*x)) Coefficients (with 95% confidence bounds): a = -0.289 (-0.5166, -0.06147) b = -0.003427 (-0.004609, -0.002245) c = -0.06304 (-0.06519, -0.06088) d = -0.0001293 (-0.0001322, -0.0001264) e = -0.975 (-1.186, -0.7636) f = -0.008562 (-0.01062, -0.006502) g = -0.1089 (-0.1211, -0.09673) h = -0.0007063 (-0.0007685, -0.0006441)
gof = struct with fields:
sse: 0.1447 rsquare: 0.9958 dfe: 1245 adjrsquare: 0.9958 rmse: 0.0108
figure
plot(x, y, '.', 'color', '#A7B7F7'), hold on
plot(yfit, 'r'), hold off, grid on
legend('Data', 'Fitted curve', 'location', 'best')
Note that the coefficients are not unique. In my machine, I got different results"
Fit model #2
General model:
f(x) = x^(a*exp(b*x) + c*exp(d*x) + e*exp(f*x) + g*exp(h*x))
Coefficients (with 95% confidence bounds):
a = -0.1227 (-0.1285, -0.1169)
b = -0.0007697 (-0.0008078, -0.0007315)
c = -0.06455 (-0.06617, -0.06292)
d = -0.0001311 (-0.0001335, -0.0001288)
e = -1.12 (-1.968, -0.2716)
f = -0.03423 (-0.0573, -0.01116)
g = -0.8431 (-0.929, -0.7572)
h = -0.005286 (-0.005609, -0.004962)
Goodness of fit:
SSE: 0.1438
R-square: 0.9959
Adjusted R-square: 0.9958
RMSE: 0.01075
Fit model #3
General model:
f(x) = x^(a*exp(b*x) + c*exp(d*x) + e*exp(f*x) + g*exp(h*x))
Coefficients (with 95% confidence bounds):
a = -0.8429 (-0.9291, -0.7566)
b = -0.005285 (-0.00561, -0.00496)
c = -0.06455 (-0.06617, -0.06292)
d = -0.0001311 (-0.0001335, -0.0001288)
e = -1.107 (-1.94, -0.2753)
f = -0.03402 (-0.05694, -0.01109)
g = -0.1227 (-0.1285, -0.1169)
h = -0.0007697 (-0.0008078, -0.0007315)
Goodness of fit:
SSE: 0.1438
R-square: 0.9959
Adjusted R-square: 0.9958
RMSE: 0.01075
  댓글 수: 3
Alex Sha
Alex Sha 2023년 7월 5일
For fitting function provided by @Sam Chak, the results are actually unique, only the order is different
Sum Squared Error (SSE): 0.143801140894944
Root of Mean Square Error (RMSE): 0.0107128649564239
Correlation Coef. (R): 0.997931669471303
R-Square: 0.995867616933781
Parameter Best Estimate
--------- -------------
a -0.842982011054431
b -0.00528502909652476
c -0.122676258206711
d -0.000769613241785951
e -0.0645440331501187
f -0.000131143071549622
g -1.11996380236003
h -0.0342317204260728
Sam Chak
Sam Chak 2023년 7월 5일
Thanks @Alex Sha for the clarification on the coefficients in Fit models #2 and #3.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Linear and Nonlinear Regression에 대해 자세히 알아보기

제품


릴리스

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by