作者:桂
时间:2017-03-13 21:23:57
链接:http://www.cnblogs.com/xingshansi/p/6545162.html
前言
本文主要是上一篇文章的补充,主要针对常用正态分布曲线拟合,文中内容多有借鉴他人,最后一并给出链接。
一、理论分析
对于正态分布:
$f(x) = frac{1}{{sqrt {2pi } sigma }}{e^{ - frac{{{{(x - mu )}^2}}}{{2{sigma ^2}}}}}$
假设数据点{$x_i$,$y_i$}($i = 1,2,3,...N$)符合正态分布曲线,对其进行拟合(曲线拟合不同于分布拟合,需要乘以幅度$A$),给出准则函数:
对准则函数$J_0$求解即可实现参数估计。
由于求导比较复杂(可以借助Mathmatica/Maple),因此这里换一个思路:如果$e^x$—>$y$,则$x$—>$lny$,重新定义准则函数:
此时,变成了{$x_i$,$ln(y_i)$}的一元二次最小二乘拟合问题(此步简便,直接借助MATLAB的polyfit,不再细说)。假设拟合结果为:
对应参数估计:
二、代码实现
A-编程
根据上文理论分析,直接给出代码:
clc;clear all;close all; %generate the orignal data mu = 0; sig2 = 2; A = 4; x=-10:.1:10; y=A/sqrt(2*pi*sig2)*exp(-(x-mu).^2/sig2/2)+.05*randn(1,length(x)); subplot 211 scatter(x,y,'k');grid on; %%curve fitting %1-Gauss distribution p = polyfit(x,log(y),2); sig2_est = -1/2/p(1); mu_est = sig2*p(2); A_est = exp(mu^2/2/sig2+p(3))*sqrt(2*pi*sig2); %plot subplot 212 scatter(x,y,'k');hold on; grid on; plot(x,A/sqrt(2*pi*sig2)*exp(-(x-mu_est).^2/2/sig2),'r--','linewidth',2);
结果图:
B-自带函数
如果单从实现角度,可以直接调用:
clc;clear all;close all; %generate the orignal data mu = 0; sig2 = 2; A = 4; x=-10:.1:10; y=A/sqrt(2*pi*sig2)*exp(-(x-mu).^2/sig2/2)+0.05*randn(1,length(x)); subplot 211 scatter(x,y,'k');grid on; %%curve fitting %1-Gauss distribution f = fittype('a*exp(-((x-b)/c)^2)'); [cfun,gof] = fit(x(:),y(:),f); yo = cfun.a*exp(-((x-cfun.b)/cfun.c).^2); %plot subplot 212 scatter(x,y,'k');hold on; grid on; plot(x,yo,'r--','linewidth',2);
对应结果图:可见二者都可以实现拟合。
三、拟合优化
推导时,我们用了一个前提:如果$e^x$—>$y$,则$x$—>$lny$。对于接近于0处的噪声,$lny$显然会将噪声放大。现在增加噪声,观察编写的code与自带两种结果:
可以看到,对于$y_i$接近0处的噪声,$lny$会将噪声放大。拟合结果非常不理想,现在考虑对编程拟合方法进行优化:
既然在映射到$ln$函数时,$y_i$接近于0点处的噪声会放大,考虑只通过数值较大的点进行拟合,而直接舍去接近0的点。即:添加阈值Th,仅考虑部分样本点。
给出优化后的代码:
clc;clear all;close all; %generate the orignal data mu = 3; sig2 = 2; A = 40; xold=-10:.1:10; yold=A/sqrt(2*pi*sig2)*exp(-(xold-mu).^2/sig2/2)+0.5*randn(1,length(xold)); subplot 211 scatter(xold,yold,'k');grid on; %%curve fitting %select data x = [];y = []; Th = 0.3;%Threshold for n = 1:length(xold) if yold(n)>max(yold)*Th; x = [x,xold(n)]; y = [y,yold(n)]; end end %1-Gauss distribution p = polyfit(x,log(y),2); sig2_est = -1/2/p(1); mu_est = sig2*p(2); A_est = exp(mu^2/2/sig2+p(3))*sqrt(2*pi*sig2); %plot subplot 212 scatter(xold,yold,'k');hold on; grid on; plot(xold,A/sqrt(2*pi*sig2)*exp(-(xold-mu_est).^2/2/sig2),'r--','linewidth',2);
优化结果:
问题得到改善。
参考:
高斯拟合:http://www.cnblogs.com/linkr/p/3632032.html