zoukankan      html  css  js  c++  java
  • 曲线拟合——(1)高斯曲线

    作者:桂

    时间: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

  • 相关阅读:
    SXOI2016 部分解题报告
    两道FFT的应用题
    [CQOI2012]交换棋子【网络流】【费用流】
    JAVA-SDK-Excel4j使用遇见的问题
    解决Zookeeper出现Error: Could not find or load main class org.apache.zookeeper.server.quorum.QuorumPeerMain问题
    maven项目打包时jar中不包含依赖
    CentOS_7中的zookeeper安装
    SpringBoot集成Redis出现WRONGTYPE Operation against a key holding the wrong kind of value错误
    主机访问虚拟机中Redis
    使用SpringS声明式的开启事务
  • 原文地址:https://www.cnblogs.com/xingshansi/p/6545162.html
Copyright © 2011-2022 走看看