简体   繁体   中英

Estimate Poisson PDF Parameters Using Curve Fitting in MATLAB

I am trying to fit histogram data that seem to follow a poisson distribution. I declare the function as follows and try to fit it by using the least squares method.

xdata; ydata; % Arrays in which I have stored the data. 
%Ydata tell us how many times the xdata is repeated in the set.

fun= @(x,xdata) (exp(-x(1))*(x(1).^(xdata)) )./(factorial(xdata)) %Function I 
% want to use in the fit. It is a poisson distribution.

x0=[60]; %Approximated value of the parameter lambda to help the fit

p=lsqcurvefit(fun,x0,xdata,ydata); % Fit in the least square sense

I however encounter the next problem

Error using snls (line 48)
Objective function is returning undefined values at initial point.
lsqcurvefit cannot continue.

I have seen online that it sometimes had to do with a division by zero for example. This can be solved by adding a small amount in the denominator so that that indetermination never happens. However, that is not my case. What is the problem then?

This is the wrong way to do so.
You have data you believe acts according to Poisson Distribution .
Since the Poisson Distribution is parameterized by single parameter (Lambda) then what you need to do is apply Parameter Estimation.

The classic way to do so is by Maximum Likelihood Estimation .

For this case, Poisson Distribution , you need to follow the MLE of Poisson Distribution .
Namely, just calculate the sample mean of data as can be seen in poissfit() .

I implemented both methods (Maximum Likelihood and PDF Curve Fitting).

You can see the code in my Stack Overflow Q45118312 Github Repository .

Results:

在此处输入图片说明

As you can see, the Maximum Likelihood is simpler and better (MSE Wise).
So you have no reason to use the PDF Curve Fitting method.

Part of the code which does the heavy lifting is:

%% Simulation Parameters

numTests            = 50;
numSamples          = 1000;
paramLambdaBound    = 10;
epsVal              = 1e-6;

hPoissonPmf = @(paramLambda, vParamK) ((paramLambda .^ vParamK) * exp(-paramLambda)) ./ factorial(vParamK);


for ii = 1:ceil(1000 * paramLambdaBound)
    if(hPoissonPmf(paramLambdaBound, ii) <= epsVal)
        break;
    end
end

vValGrid = [0:ii];
vValGrid = vValGrid(:);

vParamLambda    = zeros([numTests, 1]);
vParamLambdaMl  = zeros([numTests, 1]); %<! Maximum Likelihood
vParamLambdaCf  = zeros([numTests, 1]); %<! Curve Fitting


%% Generate Data and Samples

for ii = 1:numTests

    paramLambda = paramLambdaBound * rand([1, 1]);

    vDataSamples    = poissrnd(paramLambda, [numSamples, 1]);
    vDataHist       = histcounts(vDataSamples, [vValGrid - 0.5; vValGrid(end) + 0.5]) / numSamples;
    vDataHist       = vDataHist(:);

    vParamLambda(ii)    = paramLambda;
    vParamLambdaMl(ii)   = mean(vDataSamples); %<! Maximum Likelihood
    vParamLambdaCf(ii)   = lsqcurvefit(hPoissonPmf, 2, vValGrid, vDataHist, 0, inf); %<! Curve Fitting
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM