Why do my Weibull functions give me arrays of zeros?

3 views (last 30 days)
Hi all,
I have been running a behavioral experiment and want to fit a Weibull function over my results. Unfortunately, whenever I try, the Weibull function that gets plotted is all zeros. Below are the figures it generates- the red and blue dotted curves are my data, while the red line on the x-axis is my Weibull curve:
My code is below:
hold on
plot(PresentationLevel,Hit_Rate)
f = fit(PresentationLevel',Hit_Rate','weibull','StartPoint',[PresentationLevel(1),Hit_Rate(1)]);
plot(f,PresentationLevel,Hit_Rate);
tt = sprintf('Hit Rate at %d Hz',Freqlist(Freq));
title(tt)
xlabel('Amplitude (dB)')
ylim([0 1])
hold off
I wasn't sure if it was a matter of not having enough data points, but interpolation didn't fix it. Any suggestions would be greatly appreciated. Please let me know if there is anything else I can provide.
Thank you,
Andrew

Answers (1)

Saarthak Gupta
Saarthak Gupta on 18 Dec 2023
Hi Andrew,
I understand you wish to fit a Weibull curve to your data.
Due to lack of the exact data, I created a comparable dataset using a 2 parameter Weibull distribution with a=10 and b=2, with the x coordinates shifted by 35 units:
When a Weibull curve is fitted to this data (using default starting points), the following result is obtained:
This is very similar to the result you are getting with your data.
The standard Weibull distribution, as specified in the Curve Fitting Toolbox, is characterized by two parameters: the Shape parameter (b) and the Scale parameter (a). However, this 2-parameter version of the Weibull distribution could fall short in fully capturing your data if the data is shifted from the origin.
For a more precise fit, you might want to use a 3-parameter Weibull distribution that includes an extra parameter for location/threshold, denoted as "c":
The Curve Fitting Toolbox does not provide the 3-parameter Weibull distribution as part of its model library, but you can create a custom equation to use it.
Please refer to the following code:
nSamples=5;
a=10;
b=2;
x=linspace(1,10,nSamples);
y=wblpdf(x,a,b);
x=x+35; % shift x values by 35 units
createFit(x,y);
hold on
plot(x,y,'x-');
createFit.m:
function [fitresult, gof] = createFit(x, y)
[xData, yData] = prepareCurveData( x, y );
% Set up fittype and options.
% ft = fittype( 'weibull' );
% Define an anonymous function with 3 parameters to model the distribution
ft = fittype( @(a,b,c,x) a*b*(x-c).^(b-1).*exp(-a*(x-c).^b));
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.Lower = [0 0];
opts.StartPoint = [0.779051723231275 0.715037078400694];
% Important: Provide a suitable starting point for the location parameter,
% otherwise, the model won't converge
opts.StartPoint = [opts.StartPoint 34];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% Plot fit with data.
figure( 'Name', '3 param Weibull fit' );
h = plot( fitresult, xData, yData );
legend( h, 'y vs. x', 'fitted Weibull curve', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'x', 'Interpreter', 'none' );
ylabel( 'y', 'Interpreter', 'none' );
grid on
end
This following result is obtained when the Weibull curve is fitted to the data now:
The new model perfectly captures the data. As emphasized in the comments, it is very important that you provide a suitable initial value for the location parameter otherwise the model will not converge.
Please refer to the following MATLAB documentation for further reference:
Hope this helps!
Best regards,
Saarthak

Products


Release

R2019a

Community Treasure Hunt

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

Start Hunting!