Compute goodness of fit (gof) out of sfit-object and fitting data
조회 수: 23 (최근 30일)
이전 댓글 표시
Hi,
I used the Curve Fitting Toolbox to find the parameters of a parametric 3D-surface that matches measured data. After computing a possible solution for the parameters, I only saved the sfit-object, but forgot to also save the gof-struct. What I would like to do is to compute the gof-struct out of the sfit-object and the data used for fitting. Is there any MATLAB function that already does that?
댓글 수: 0
답변 (2개)
Farouk Moukaddem
2016년 8월 25일
편집: Farouk Moukaddem
2016년 8월 25일
Hi Rodrigo,
The only documented way to obtain the goodness-of-fit statistics is by explicitly passing the output parameter "gof" when calling the "fit" function.
[fitobject,gof] = fit(x,y,fitType)
As a workaround, you might be interested in the "goodnessOfFit" function that computes the goodness of fit between test and reference data. Refer to the following documentation link for more information:
Also, you might want to check the following File Exchange submission:
Best,
Farouk
댓글 수: 0
Brandon Ballard
2020년 8월 27일
편집: Brandon Ballard
2020년 8월 27일
Hi all,
A slightly longwinded approach to potentially solving this problem would be first obtaining the coefficient values and coefficient names using coeffvalues and coeffnames. For the example below the following curve cfit object was created for demonstration but it should also work for sfit with the appropriate modifications.
ft = fittype('a*x+b')
ft =
General model:
ft(a,b,x) = a*x+b
curve = cfit(ft,2,1)
curve =
General model:
curve(x) = a*x+b
Coefficients:
a = 2
b = 1
coeffnames(curve)
ans =
2×1 cell array
{'a'}
{'b'}
coeffvalues(curve)
ans =
2 1
Once the coefficient names and values are known the next step is to define the Starting Points and the fitoptions.
fo = fitoptions(ft)
fo =
Normalize: 'off'
Exclude: []
Weights: []
Method: 'NonlinearLeastSquares'
Robust: 'Off'
StartPoint: [1×0 double]
Lower: [1×0 double]
Upper: [1×0 double]
Algorithm: 'Trust-Region'
DiffMinChange: 1.0000e-08
DiffMaxChange: 0.1000
Display: 'Notify'
MaxFunEvals: 600
MaxIter: 400
TolFun: 1.0000e-06
TolX: 1.0000e-06
By changing the StartPoint of the optimisation process to the coefficient values found previously and forcing both the Maximum Number of Function Evaluations and Maximum Number of Iterations to be equal to 1.
fo.StartPoint = [2,1];
fo.MaxFunEvals = 1;
fo.MaxIter = 1;
This forces the algorithm to only evaluate the fit at the Start Point and therefore the coefficient values from the original cfit object and the cfit object obtained through the fit command below.
[fitobject,gof,output] = fit(x,y,ft,fo)
For example using the example data below results in...
x = [1:1:10];
y = curve(x); % [3,5,7,9,11,13,15,17,19,21]
fitobject =
General model:
fitobject(x) = a*x+b
Coefficients (with 95% confidence bounds):
a = 2 (2, 2)
b = 1 (1, 1)
gof =
struct with fields:
sse: 0
rsquare: 1
dfe: 8
adjrsquare: 1
rmse: 0
output =
struct with fields:
numobs: 10
numparam: 2
residuals: [10×1 double]
Jacobian: [10×2 double]
exitflag: 1
firstorderopt: 0
iterations: 0
funcCount: 3
cgiterations: 0
algorithm: 'trust-region-reflective'
stepsize: 1
message: 'Success. Fitting converged to a solution.'
Bear in mind that this method only works on general and nonlinear models as it makes use of the NonlinearLeastSquares fitoptions.
Using the following alternative values for the y data gives...
y = 0.5*curve(x); % [1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5]
fitobject =
General model:
fitobject(x) = a*x+b
Coefficients (with 95% confidence bounds):
a = 2 (0.1118, 3.888)
b = 1 (-10.72, 12.72)
gof =
struct with fields:
sse: 442.5000
rsquare: -4.3636
dfe: 8
adjrsquare: -5.0341
rmse: 7.4372
output =
struct with fields:
numobs: 10
numparam: 2
residuals: [10×1 double]
Jacobian: [10×2 double]
exitflag: 0
firstorderopt: 412.5000
iterations: 0
funcCount: 3
cgiterations: 0
algorithm: 'trust-region-reflective'
stepsize: 1
message: 'Fitting stopped because the number of iterations or function evaluations exceeded the specified maximum.'
This approach may not work for all cases so I would appreciate it if others could verify this method works for other cases. For example using other more complex models.
댓글 수: 1
Ana Maria Velasquez Giraldo
2023년 1월 25일
I used this approach for a custom curve fitting (see below), and it worked very well. It is a simple work around to obtain the goodness-of-fit statistics. Thanks for posting this!
myFit = fittype( @(a, b, c, d, e, x) a*exp(-x/b) + c*exp(-x/d)+e )
참고 항목
카테고리
Help Center 및 File Exchange에서 Linear and Nonlinear Regression에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!