数学建模常用Matlab/Lingo/c代码总结系列——参数估计

Matlab中用fminsearch实现参数估计


 文章的主要思想来源于Matlab|Simulink仿真世界的一篇类似的文章。我这里把这个思想引入到我们的体系来,并以一个新的例子讲解这一用法。

fminsearch用来求解多维无约束的非线性优化问题,它的基本形式是:

[X,FVAL,EXITFLAG,OUTPUT] = FMINSEARCH(FUN,X0,OPTIONS).

大段的Matlab帮助文档我就不翻译解释了,有兴趣的朋友可以参见Matlab联机帮助,我这里只介绍他在参数估计中的作用。

在 参数估计中经常用到正态分布的参数估计。在matlab系统中有一个函数叫做normfit就直接可以完成这样的参数估计,返回均值mu和均方差 sigma的估计,但是这里有一个要求,就是它的输入信息必须是随机的数字序列。如得到1000个服从正态分布的随机数向量R,用命令[phat pci]=normfit(R),就可以得到参数估计了。然而如果我我们得知某些已经处于pdf函数曲线上的点时,这时需要对函数进行拟合运算。

估计参数的原理是从已知的一序列数据中,对于给定的任何一组参数,计算用其估计数据得到的方差,然后利用fminsearch函数求当方差满足最小的时候的参数,这就是需要估计的参数。

来看一下下面的列子:

smu=10,ssig=25;
%假设原来均值方差分别为:10,25
R=randn(1000,1)*ssig+smu;

%生成满足要求的1000个随机数
[y x]=myhist(R);
%生成统计信息,x,y分别表示分组中值序列和落入该组的统计数目
bar(x,y)
%绘制直方图
hold on
plot(x,y,'ro')
%绘制对应点
[pms mse]=normpdffit(x,y,8,20);
%根据得到的统计信息x,y对其进行参数估计,8,20分别代表均值和方差的初值
t=min(x):(max(x)-min(x))/200:max(x);
%定义绘图区间
ny=normpdf(t,smu,ssig);
%真实分布曲线数据
nyf=normpdf(t,pms(1),pms(2));
%拟合分布曲线数据
plot(t,ny,'r-')
plot(t,nyf,'b-.')
legend('hist','hist value','ture pdf','fit pdf')
%绘制两条曲线作对比

上面例子中所用的几个函数定义如下:

function [h xout]=myhist(data,nbins)
%用于统计信息,生成和pdf函数值相同的hist统计方式。
if nargin==1
    nbins=uint32(1+log(length(data))/log(2));
end
nbins=double(nbins);
data=data(:);
[h xout]=hist(data,nbins);
ew=xout(2)-xout(1);
h=h./(ew*length(data));
  
function [pab mse]= normpdffit(x,y,a0,b0)
%正态分布pdf参数估计
p=[a0 b0];
opt=optimset('fminsearch');
opt.TolX=0.001;
opt.Display='off';
[pab mse]=fminsearch(@normpdfse,p,opt,x,y);
%这里需要注意,opt参数已经传递给fminsearch,但是对于原计算方差的函数来说,还需要两个参数x,y,这两个参数就写在opt参数的后面,这样可以完成其他参数的传递。
%这里说下以前探索的时候的失败经验:用global把参数公有化,然后函数只传递变化的参数(需要估计的参数),但是失败了。所以了解这种参数传递方法是非常有必要的。
function se= normpdfse(pab,X,Y)
%计算对于任何一组参数pab(1),pab(2),给出当前数据下的方差来。
se=var(Y-normpdf(X,pab(1),pab(2)));


运行结果如图所示:


从图中可以看出,随机数在这里变成了统计信息,统计信息反映到了绘制的点信息上,图中圆圈所示。真实的pdf为红色曲线,估计的曲线为蓝色虚线。从图中可知,估计的效果非常满意。

如果在函数中加上:

disp 'the result of normfit function:'

[mu sg]=normfit(R)

disp 'the result of fminsearch:'

[pms mse]=normpdffit(x,y,8,20)


得到结果:

the result of normfit function:

mu =

  10.44306258428258

sg=

  25.61945417031251

the result of fminsearch:

pms =

  10.30663244862284  25.32479396733891

mse =

    7.093014695522283e-008


 

与真实值相比,我们这里的拟合结果将比直接用normfit的结果更接近真实值。

可 以这么解释:normfit函数是内部通用的拟合函数,适合范围广,而没有任何先验信息加入,而对于我们的fminsearch函数来说,它需要一个先验信息,即参数的初值。我们在调用的时候用了初值8,20.这个先验信息对更进一步的拟合最后的结果有着相当重要的作用!因此,对于参数估计,先验信息还是相当重要的。

 

 

由于有这种技巧存在,了解了fminsearch函数之后,可以有很多的扩展应用。

 

你可能感兴趣的:(数学建模常用Matlab/Lingo/c代码总结系列——参数估计)