[MATLAB 在科学计算中的应用] 使用MATLAB 进行非线性拟合

文章目录

  • [MATLAB 在科学计算中的应用] 使用MATLAB 进行非线性拟合
    • 前言引述
    • MATLAB 曲线拟合函数简述
    • 一二维数据非线性拟合
      • 一维数据拟合例子
      • 二维数据拟合例子
    • 高维数据非线性拟合
      • lsqcurvefit
      • nlinfit 函数
    • 数据拟合工具箱的使用
    • 写在后面的话

前言引述

所谓曲线拟合,就是给定数据和数据可能满足的带参函数表达,希望能找到一组最好的参数,是的这个函数能够“最大限度”地刻画给定的数据。在一维(自变量维数)的情况下,换句话说,就是给定平面上一些点,希望能找一条某种形式的曲线,使得它“尽可能”地通过这些点。

一些工程上的朋友,手头有一些数据,简单地,就希望通过拟合能得到一个不错的函数表达。他们并不在乎也不想去了解底层的算法,只是想要一个结果,这个时候呢,他们就可以利用 MATLAB 自带的函数达到他们的目的。

令他们头大的是,关于 MATLAB 的拟合,他们网上一查,出现了十几个甚至几十个相关的函数。他们懵逼了。一个问题是,他们不理解为什么一个软件要搞出这么多类似功能的函数。另外一个问题是,在众多的选择下,他们不知道该何去何从。

下面,我将来回答这两个问题。

MATLAB 曲线拟合函数简述

MATLAB 拟合曲线的函数有非常多,列举几个最最最常用的:

  • regress 和 polyfit 适用于线性函数的拟合。
  • lsqcurvefit 和 nlinfit 用于较复杂的非线性函数的拟合。
  • fit 适用于最常用函数的拟合,如指数函数,傅立叶函数、高斯函数、多项式函数、幂函数、有理函数等等。它更适用显式地给你函数表达式的情况。
  • cftool 工具箱提供拟合的 GUI 界面,最大限度地体谅了不写程序的选手。

MathWorks 公司为什么要搞这么多似乎功能相同的函数呢?

这其实不怪他们。MATLAB 是个科学工程计算的软件,体量庞大,涉及的领域方方面面。MATLAB 有很多工具箱,每个函数都分属于不同的工具箱。按照分而治之的思想,每个工具箱可能各自有各自的发展,相对独立。这样呢,基于不同的背景和算法,他们可能就有了各自的,看似实现相同功能的模块。这就好比不同的汽车公司,都造轮子,造的轮子的外观和造轮子的方式不尽相同,但是最终都是要装到车上去的。

对于曲线拟合也是一样,有优化、统计、曲线拟合、机器学习等等人都需要用到拟合这个东西,所以在 MATLAB 的优化和统计等工具箱下面都有了各自的拟合实现,只是不同的地方可能叫法不一样。比如统计上喜欢叫“回归”。regress、nlinfit 等是统计工具箱下的,polyfit 是多项式工具箱下的,lsqcurvefit是优化工具箱下的,而 fit 和 cftool 都是曲线拟合工具箱下的。

因为大部分情况下,我们需要用到的是非线性拟合,线性拟合其实也是非线性拟合的特例,所以,下面,我们着重讨论非线性拟合。通过一些简单的例子来掌握非线性拟合工具,包括 fit、nlinfit、lsqcurvefit、cftool的选择和使用。简单地说,一二维的数据拟合,我们选择 fit (cftool),更高维数据的拟合,我们选择 lsqcurvefit 和 nlinfit。这里的维数,我们是对自变量说的。

下面我们都以例子开始进行说明,更详细的内容,请看 MATLAB 的 doc 文档。

一二维数据非线性拟合

一维数据拟合例子

假如我们现在有一组数据,横纵坐标分别用 x 和 y 表示。我们希望通过一个指数函数 y=aebx+cy = ae^{bx}+cy=aebx+c,对它进行拟合,那么我们就可以这么写:

clc
clear
%% 先造个数据用于测试
x = 0:0.01:1;
x = x';%fit函数只支持列向量
y = 1*exp(2*x)+3;
% scatter(x,y);
% hold on;
%% 输入函数形式,进行拟合
ft = fittype('a*x*exp(b*x)+c');%给定函数表达
coeffnames(ft);%查看
model = fit(x,y,ft,'StartPoint',[1,3,5]);%StartPoint表示参数迭代的初值,不知道的情况下随便给一个就行
%% 查看结果和可视化误差
model
plot(model,x,y)

代码简洁明了,注释也很清楚,就不详加解释了。这里需要强调的一点是,fittype 函数默认使用 x 来表示自变量的值,依次使用 a、b、c…… 来表示第一个参数、第二个参数、第三个参数……这也就解释了为什么 fit 函数能够识别 ft 中变量哪些是自变量,哪些是参数,而不至于出问题。

结果如下:

从结果中可以看到,虽然得到 a、b、c 的值和真正的值结果有些差距,但是图上的拟合误差还是很小的。

二维数据拟合例子

二维和一维的 fit 的用法是一样的,不同的是,这个时候我们要让程序清楚哪个是第一自变量,哪个是第二自变量,哪些又是参数。要实现这一点,可以在 fittype 中用形如 'coefficients',{'a1','a2'} 等方式指定系数,用 形如 'independent','time' 的方式指定自变量。当然,更简单的方式,是直接采用匿名函数的方式。如下,还是举个例子。
假设我们要拟合 z=ax+beyz=ax+be^yz=ax+bey 这个函数,给定数据点 xxx 和 yyy ,那么用匿名函数来拟合,程序如下。

clc
clear
%% 先造个数据
fun = @(a,b,x,y) a.*x+b.*exp(y);%注意这里要用点乘
x = 0:0.01:1;
y = 0:0.01:1;
x = x';y = y';%一定要列向量
z = fun(x,y,1,2);
%% 对匿名函数拟合,绘图
sf = fit([x,y],z,fun,'StartPoint',[1,3]);
sf
plot(sf,[x,y],z);

结果和一维的例子类似,我就不黏贴了。一二维的例子,用 fit 来拟合是极为简单的,但是 fit 也仅仅是支持最多二维的。fit 函数自动识别了 fun 函数的最后 n (n=1 or 2)个输入变量作为了自变量,其他输入变量自动顺序地成为参数。比如说,这个例子中,fun 输入参数表中的后两个变量x,yx,yx,y,刚好就对应了 fit 中的自变量 [x,y][x,y][x,y] ,而起始点对应关系为 a=1,b=3a=1,b=3a=1,b=3。这是 fit 函数对于参数指派的一种潜规则。

高维数据非线性拟合

lsqcurvefit

lsqcurvefit 用最小二乘求解非线性曲线拟合(数据拟合)问题。
c = lsqcurvefit(fun,c0,xdata,ydata)从 c0 开始,求取合适的系数 c,使非线性函数 fun(x,xdata) 对数据 ydata 的拟合最佳(基于最小二乘指标)。ydata 必须与 fun 返回的向量(或矩阵)F 大小相同。

我们依然从一个例子开始学习。假设我们现在要拟合y=c1x1+c2sin⁡x2+ec3x3y=c_1x_1+c_2\sin x_2+e^{c_3x_3}y=c1​x1​+c2​sinx2​+ec3​x3​,已知一组数组 X=[x1,x2,x3]X=[x_1,x_2,x_3]X=[x1​,x2​,x3​] 和 yyy ,要求最佳的拟合参数 c1,c2,c3c_1,c_2,c_3c1​,c2​,c3​,则一个简单的程序如下:

clc
clear
X = rand(10,3);
fun = @(C,X) C(1)*X(:,1)+C(2)*sin(X(:,2))+exp(C(3)*X(:,3));
y = fun([1,2,5.01],X);
C0 = [1,2,3];
C = lsqcurvefit(fun,C0,X,y);
C

这里也用到了匿名函数,而且 lsqcurvefit 也有所谓的潜规则,即 fun 的第一个变量表示参数组,第二个变量表示变量组。这样最后能得到一组拟合系数。值得一提的是,这个方法是基于最小二乘的,如果初值选得合适,精度相当高。

nlinfit 函数

依然以 y=c1x1+c2sin⁡x2+ec3x3y=c_1x_1+c_2\sin x_2+e^{c_3x_3}y=c1​x1​+c2​sinx2​+ec3​x3​ 为例子。编程如下:

clc
clear
X = rand(10,3);
fun = @(C,X) C(1)*X(:,1)+C(2)*sin(X(:,2))+exp(C(3)*X(:,3));
y = fun([1,2,5.01],X);
C0 = [1,2,30];
C = nlinfit(X,y,fun,C0)

我们发现,在这个例子中,nlinfit 和 lsqcurvefit 有异曲同工之妙。
除了 nlinfit,统计工具箱中和拟合有关的函数还包括betafit.m dfittool.m fitgmdist.m histfit.m nlinfit.p poissfit.m wblfit.m binofit.m distributionFitter.m gamfit.m lognfit.m nlmefit.m raylfit.m copulafit.m evfit.m gevfit.m mnrfit.m nlmefitoutputfcn.m robustfit.m copulafit.p expfit.m glmfit.m nbinfit.m nlmefitsa.m stepwisefit.m coxphfit.m fitdist.m gpfit.m nlinfit.m normfit.m unifit.m等 。

数据拟合工具箱的使用

拟合工具箱,本质上不过是 fit 的一个 GUI 可视化界面而已。
下面我们依然用一个例子开始。

在命令行输入 cftool 打开数据拟合工具箱。之后,从工作空间中选择自变量和因变量,即 x,y,zx,y,zx,y,z 变量。

鼠标点选你想要的拟合函数表达式即可。依然习惯用 a,b,c…a,b,c\ldotsa,b,c… 表示顺序的参数,用 x,yx,yx,y 表示自变量。这里我们选择 Custom Equation,输入我们要拟合的表达式。结果如下:

对于拟合得到的结果,我们可以保存数据到工作空间,也可以生成代码,还可以做对已有数据进行验证等等操作,这里就不再赘述了。生成代码如下:

function [fitresult, gof] = createFit(x, y, z)
%CREATEFIT(X,Y,Z)
%  Create a fit.
%
%  Data for 'untitled fit 1' fit:
%      X Input : x
%      Y Input : y
%      Z Output: z
%  Output:
%      fitresult : a fit object representing the fit.
%      gof : structure with goodness-of fit info.
%
%  另请参阅 FIT, CFIT, SFIT.%  由 MATLAB 于 22-Dec-2020 00:42:46 自动生成%% Fit: 'untitled fit 1'.
[xData, yData, zData] = prepareSurfaceData( x, y, z );% Set up fittype and options.
ft = fittype( 'a + b*sin(c*pi*x*y)+d+log(e*x+10)+f', 'independent', {'x', 'y'}, 'dependent', 'z' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.StartPoint = [0.189570472126967 0.108311946115659 0.592044939420046 0.957384022595723 0.26532203619292 0.924580895239601];% Fit model to data.
[fitresult, gof] = fit( [xData, yData], zData, ft, opts );% Plot fit with data.
figure( 'Name', 'untitled fit 1' );
h = plot( fitresult, [xData, yData], zData );
legend( h, 'untitled fit 1', 'z vs. x, y', 'Location', 'NorthEast' );
% Label axes
xlabel x
ylabel y
zlabel z
grid on

从这里也可以看出,工具箱的拟合本质上用的还是 fit 函数,只不过提供了一个界面。而且这里的拟合选项用的也是非线性最小二乘拟合。

所以这里的拟合自变量维数也无法超过 2。每个自变量都是一个向量,不能是矩阵。因此,拟合工具箱和 fit 函数函数有相同的局限性,即维数不能太高。

仔细观察工具箱你会发现,在自变量为一维的时候,它比起 fit 有个缺陷,就是不能自定义关于系数的非线性拟合函数。不过可以生成代码后再进行修改。

写在后面的话

综上所提,MATLAB 函数是默认地是接受输入表 “先参数后变量” 的形式。这点可以记住。

如果不追求速度的话,线性拟合和多项式拟合以及插值,当然也可以用非线性拟合的函数来做拟合。

那么,我们现在对于 MATLAB 拟合方法的选择,就有了一个思路。简便最优选择是:当你拟合的自变量维数是一维二维的时候,实用 cftool 拟合工具箱,生成代码,加以改写利用。当你拟合的自变量维数大等于三的时候,如果你和优化更近的话,用 lsqcurvefit 函数,如果你和统计更近的话,用 nlinfit 函数。

[MATLAB 在科学计算中的应用] 使用MATLAB 进行非线性拟合相关推荐

  1. matlab在数值计算中的应用,详解MATLAB在科学计算中的应用

    详解MATLAB在科学计算中的应用 编辑 锁定 讨论 上传视频 <详解MATLAB在科学计算中的应用>是2011年电子工业出版社出版的图书,作者是陈泽占海明. 书    名 详解MATLA ...

  2. matlab hilb,MATLAB在科学计算中的应用:第2章 MATLAB 语言程序设计基础

    <MATLAB在科学计算中的应用:第2章 MATLAB 语言程序设计基础>由会员分享,可在线阅读,更多相关<MATLAB在科学计算中的应用:第2章 MATLAB 语言程序设计基础(7 ...

  3. 全面对比 MATLAB、Julia、Python,谁在科学计算中更胜一筹?

    数百种编程语言,各有优劣,各自也都有自己最为适用的场景.那么就科学计算领域而言,主流的 MATLAB.Julia.Python 会有哪些最为独特的优势呢?又存在哪些让开发者无力的缺陷?在本文中,我们将 ...

  4. python 对比matlab_全面对比 MATLAB、Julia、Python,谁在科学计算中更胜一筹?

    原标题:全面对比 MATLAB.Julia.Python,谁在科学计算中更胜一筹? 数百种编程语言,各有优劣,各自也都有自己最为适用的场景.那么就科学计算领域而言,主流的 MATLAB.Julia.P ...

  5. matlab 与 python 在科学计算中的区别比较

    本文以求解拟一维喷管流动为例,比较两者在科学计算中的区别. 感受:matlab矩阵实验室在求解矩阵方面具有得天独厚的优势,尤其是在矩阵之间的运算方面.求解方程过程中,能够明显感觉到编程给人带来的快感, ...

  6. matlab求解helmholtz,MATLAB与科学计算(第2版)

    第1章  安装及使用前的准备1.1  MATLAB 6.x简介1.1.1  21世纪的科学计算语言1.1.2  MATLAB的发展历史1.1.3  MATLAB 6.x的新特点1.1.4  MATLA ...

  7. python应用实例论文_浅谈Python在科学计算中的应用

    55 SYS PRACTICE 系统实践 有效的计算工具能为工作提高效率,Python 在实际工作与 科学调研中等运用的也越来越广泛,通过专家不断的研究与分 析,通过 Python 进行科学计算是再合 ...

  8. matlab将常值函数转换为变量,MATLAB与科学计算期末复习题题库15.11.12

    MATLAB 与科学计算期末复习题题库(第一部分) 一.填空 1.MATLAB 的主界面是一个高度集成的工作环境,有四个不同职责分工的窗口,分别 为 . . .和 窗口. 2.MATLAB 的值,应在 ...

  9. matlab实现线性函数逼近,1基于MATLAB的科学计算—函数逼近1.doc

    1基于MATLAB的科学计算-函数逼近1 数值分析-最佳逼近 ━基于MATLAB的实现与分析 §1 引 言 所谓函数最佳逼近就是从指定的一类简单的函数中寻找一个和给定的函数"最贴近" ...

  10. matlab与科学计算 王沫然,MATLAB与科学计算(第3版) 王沫然著 电子工业出版社 9787121180521...

    商品描述: 基本信息 书名:MATLAB与科学计算(第3版) 定价:49.80元 作者:王沫然 编著 出版社:电子工业出版社 出版日期:2012-10-01 ISBN:9787121180521 字数 ...

最新文章

  1. R语言gganimate包创建可视化gif动图、可视化动图:、gganimate包创建动态线型图动画基于transition_time函数、使用geom_point函数显示动画移动的数据点
  2. 静态方法调用注入对象(springMvc)
  3. oracle win10家庭版,Windows10远程报错:由于CredSSP加密Oracle修正(ps:Win10家庭版)
  4. 史上最全的正则表达式
  5. 1031:反向输出一个三位数
  6. 怎样重建一个损坏的调用堆栈(callstack)
  7. B程序员:讲述三年计算机学习辛酸史
  8. 如何为CentOS 7配置静态IP地址
  9. niceScroll 滚动条的用法
  10. 使用现有在线翻译服务进行代码翻译的体验
  11. 微信小程序使用本地背景图无法渲染的解决办法
  12. Centos 添加新硬盘,分区格式化、挂载硬盘
  13. 2022非常全的接口测试面试题及参考答案-软件测试工程师没有碰到算我输~
  14. int int int * int**的区别、联系和用途
  15. Omniverse元宇宙开发框架
  16. 【软考-软件设计师】(五).计算机网络
  17. 神经网络隐含层节点数
  18. html响应式页面源码,关于响应式页面
  19. MEMS加速度计如何选型?
  20. Serdes系列总结——Xilinx serdes IP使用(二)——10G serdes

热门文章

  1. 使用android sqlite读取数据库的简单方法
  2. 出现Ncat: bind to 0.0.0.0:9999: Address already in use. QUITTING.如何解决?
  3. 变量、函数、类等编程时常用英文命名和缩写
  4. 微信可以设置雪花昵称了,真漂亮!
  5. [免费专栏] Android安全之Root检测与Root绕过(浅析)
  6. 洪荒修真服务器名字可以修改吗,洪荒修真变态版
  7. ESXI系统安装教程
  8. 初级系列11.个人所得税问题
  9. 190824-英雄联盟传记爬取
  10. 问答搜索 全网搜索平台