使用MATLAB中的曲线拟合估算泊松PDF参数

时间:2017-07-15 12:40:39

标签: matlab probability curve-fitting

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

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.

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

2 个答案:

答案 0 :(得分:0)

这是错误的方法。
您认为根据Poisson Distribution行事的数据 由于Poisson Distribution由单个参数(Lambda)参数化,因此您需要做的是应用参数估计。

这样做的经典方法是Maximum Likelihood Estimation

在这种情况下,Poisson Distribution,您需要关注MLE of Poisson Distribution 也就是说,只需计算poissfit()中可以看到的数据样本均值。

答案 1 :(得分:0)

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

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

结果:

enter image description here

如您所见,最大似然更简单,更好(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