How to use use an anonymous function to fit data based on the fittype and fit functions.

조회 수: 25 (최근 30일)
Hi there,
I have some sort of data point and I want to use an anonymous function to fit this data based on the fittype and fit functions.
Also, the function is look like this:
F(x)=a*x^2+b*x+c+d*diff(x^2)+e*diff(x)
Any suggestions?
Thanks

채택된 답변

William Rose
William Rose 2022년 6월 24일
I think the manual page examples for this are pretty good.
a=1; b=2; c=-1; d=-2; e=3;
xdata=-3:.03:3;
%ydata=a*xdata(2:end)+b*xdata(2:end).^2+c+d*diff(xdata)+e*diff(xdata).^2+randn(1,length(xdata)-1);
fun=@(p,x) p(1)*x(2:end)+p(2)*x(2:end).^2+p(3)+p(4)*diff(x)+p(5)*diff(x).^2;
yclean=fun([a,b,c,d,e],xdata);
ydata=yclean+randn(1,length(xdata)-1);
p0=[1,1,1,1,1];
p = lsqcurvefit(fun,p0,xdata,ydata)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
p = 1×5
1.0099 2.0178 -0.8965 -3.6526 -48.7815
yfit=fun(p,xdata);
plot(xdata(2:end),yclean,'-r',xdata(2:end),ydata,'rx',xdata(2:end),yfit,'-b')
legend('Clean Data','Noisy Data','Best Fit')
The fit to the data is excellent, and the two curves are so close that they overlap, but the fitted parameters do not match the original parameters. This is because the input diff(x) is a constant, and therefore is not independent of the "c" term, and the input diff(x^2) is a straight line, and therefore not indepndent of the "a" term.
Try this. Good luck.
  댓글 수: 7
William Rose
William Rose 2022년 6월 27일
편집: William Rose 2022년 6월 27일
[edit: correct typographical errors]
@payam samadi, I would also ask my student to tell me the p-values and 95% confidence intervals for each fitted parameter. To get this info easily, and to do the whole regression easily (with the potential to add stepwise regression), use the Statistics & Machine Learning Toolbox. See how easy it is:
load('xdata'); load('ydata');
%Next: Create array with the four predictor variables as columns.
X=[xdata(2:end),xdata(2:end).^2,diff(xdata),diff(xdata).^2];
y=ydata(2:end);
mdl1=fitlm(X,y) %fit the linear model
mdl1 =
Linear regression model: y ~ 1 + x1 + x2 + x3 + x4 Estimated Coefficients: Estimate SE tStat pValue ________ _______ _______ ___________ (Intercept) -25.451 1.0814 -23.534 1.9701e-104 x1 13.305 0.73942 17.994 1.1296e-65 x2 -1.3349 0.125 -10.679 1.0479e-25 x3 -14.679 0.73364 -20.009 4.2594e-79 x4 -142.2 22.027 -6.4559 1.4506e-10 Number of observations: 1499, Error degrees of freedom: 1494 Root Mean Squared Error: 0.667 R-squared: 0.888, Adjusted R-Squared: 0.888 F-statistic vs. constant model: 2.97e+03, p-value = 0
coefCI(mdl1)
ans = 5×2
-27.5725 -23.3299 11.8543 14.7551 -1.5801 -1.0897 -16.1182 -13.2400 -185.4090 -98.9959
The values intercept,x1,x2,x3,x4 correspond to c,b,a,d,e in your original model. If you look back, you will see that the parameter estimates here match the values obtained above, when we used lsqcurvefit(). Because we used the Statistics toolbox, we get the p values and confidence intervals (with coefCI()) for each fitted parameter. The p-values show that all five fitted parameters are highly significant.
We can do a stepwise linear regression to see if all four predictors are useful in addition to the intercept. Given the highly significant p values above, I expect that all four will turn out to be significant.
%If you don't include 'Upper','linear' below, stepwiselm() will also try to fit
%interaction terms in the model. YOu did not request those.
mdl2=stepwiselm(X,y,'Upper','linear')
1. Adding x1, FStat = 8320.6404, pValue = 0 2. Adding x3, FStat = 361.6586, pValue = 2.142266e-72 3. Adding x2, FStat = 101.3947, pValue = 4.035306e-23 4. Adding x4, FStat = 41.6787, pValue = 1.45062e-10
mdl2 =
Linear regression model: y ~ 1 + x1 + x2 + x3 + x4 Estimated Coefficients: Estimate SE tStat pValue ________ _______ _______ ___________ (Intercept) -25.451 1.0814 -23.534 1.9701e-104 x1 13.305 0.73942 17.994 1.1296e-65 x2 -1.3349 0.125 -10.679 1.0479e-25 x3 -14.679 0.73364 -20.009 4.2594e-79 x4 -142.2 22.027 -6.4559 1.4506e-10 Number of observations: 1499, Error degrees of freedom: 1494 Root Mean Squared Error: 0.667 R-squared: 0.888, Adjusted R-Squared: 0.888 F-statistic vs. constant model: 2.97e+03, p-value = 0
The result above shows that stepwiselm() keeps all four predictor variables in the model - so you are justified in including all four, plus the intercept.
Try it.

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

추가 답변 (2개)

Denis
Denis 2022년 6월 25일
Thanks for post, me need it!

Walter Roberson
Walter Roberson 2022년 6월 24일
There is no chance of fitting that function.
fit() and fittype() pass in numeric data, and diff() of numeric data is always smaller than the original data. Therefore your a*x^2+b*x+c is an incompatible size to be added to d*diff(x^2)+e*diff(x)
It might make sense to rewrite in terms of gradient()
Does diff(x) happen to be constant (points are equally spaced)? If so then I suspect you can rewrite the formulas for more efficient fitting
  댓글 수: 2
Walter Roberson
Walter Roberson 2022년 6월 25일
fit() needs to work mathematically when the order of the input vectors is changed. fitting x, y needs to give you the same sum of squared error as fitting x(P) y(P) gives, where P is a permutation of the indices.
If you were to reorder the inputs, e*diff(x) might balance out, but d*diff(x^2) cannot balance out.
Also could you confirm for us that you mean diff(x.^2) and not diff(x).^2 ?
payam samadi
payam samadi 2022년 6월 25일
Thanks for your answer,
Yes, I can confirm that the equation is the same that I mentioned.
Also, I add the data sets, which may can be useful.

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

카테고리

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

Community Treasure Hunt

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

Start Hunting!

Translated by