在 MATLAB 中使用曲线拟合估计泊松 PDF 参数

Estimate Poisson PDF Parameters Using Curve Fitting in MATLAB

我正在尝试拟合似乎服从泊松分布的直方图数据。我声明函数如下,并尝试用最小二乘法拟合它。

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

然而我遇到了下一个问题

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

我在网上看到它有时与除以零有关。这可以通过在分母中添加少量来解决,这样不确定就不会发生。但是,这不是我的情况。那有什么问题呢?

这是错误的做法。
您拥有您认为符合 Poisson Distribution.
的数据 由于 Poisson Distribution 由单个参数 (Lambda) 参数化,因此您需要做的是应用参数估计。

经典的方法是 Maximum Likelihood Estimation

对于这种情况,Poisson Distribution,您需要遵循泊松分布的MLE
即,只需计算数据的样本均值,如 poissfit().

所示

我实现了两种方法(最大似然法和 PDF 曲线拟合)。

你可以在我的Stack Overflow Q45118312 Github Repository中看到代码。

结果:

如您所见,最大似然法更简单更好(MSE Wise)。
所以你没有理由使用PDF曲线拟合方法。

执行繁重工作的部分代码是:

%% 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