matlab 最小二乘法拟合

作者&投稿:俟炒 (若有异议请与网页底部的电邮联系)
matlab最小二乘法曲线拟合怎么取~

曲线拟合
已知离散点上的数据集,即已知在点集上的函数值,构造一个解析函数(其图形为一曲线)使在原离散点上尽可能接近给定的值,这一过程称为曲线拟合。最常用的曲线拟合方法是最小二乘法,该方法是寻找函数使得最小。
MATLAB函数:p=polyfit(x,y,n)
[p,s]= polyfit(x,y,n)
说明:x,y为数据点,n为多项式阶数,返回p为幂次从高到低的多项式系数向量p。x必须是单调的。矩阵s用于生成预测值的误差估计。(见下一函数polyval)
多项式曲线求值函数:polyval()
调用格式: y=polyval(p,x)
[y,DELTA]=polyval(p,x,s)
说明:y=polyval(p,x)为返回对应自变量x在给定系数P的多项式的值。
[y,DELTA]=polyval(p,x,s) 使用polyfit函数的选项输出s得出误差估计YDELTA。它假设polyfit函数数据输入的误差是独立正态的,并且方差为常数。则YDELTA将至少包含50%的预测值。


练习:如下给定数据的拟合曲线,x=[0.5,1.0,1.5,2.0,2.5,3.0],
y=[1.75,2.45,3.81,4.80,7.00,8.60]。
解:MATLAB程序如下:
x=[0.5,1.0,1.5,2.0,2.5,3.0];
y=[1.75,2.45,3.81,4.80,7.00,8.60];
p=polyfit(x,y,2)
x1=0.5:0.05:3.0;
y1=polyval(p,x1);
plot(x,y,'*r',x1,y1,'-b')
计算结果为:
p =0.5614 0.82871.1560
即所得多项式为y=0.5614x^2+0.08287x+1.15560
===========================================================================
===========================================================================
polyfit函数是matlab中用于进行曲线拟合的一个函数。曲线拟合:已知离散点上的数据集,即已知在点集上的函数值,构造一个解析函数(其图形为一曲线)使在原离散点上尽可能接近给定的值。
  解释1  用法 polyfit(x,y,n ) ;用多项式求过已知点的表达式,其中x为源数据点对应的横坐标,可为行向量、矩阵,y为源数据点对应的纵坐标,可为行向量、矩阵,n为你要拟合的阶数,一阶直线拟合,二阶抛物线拟合,并非阶次越高越好,看拟合情况  matlab polyfit 做出来的值从左到右表示从高次到低次的多项式系数  给个例子一看就知道了  x = (0: 0.1: 2.5)';  y = erf(x);  p = polyfit(x,y,6)  p =  0.0084 -0.0983 0.4217 -0.7435 0.1471 1.1064 0.0004  则y=0.0084x^6-0.0983x^5+0.4217x^4-0.7435x^3+0.1471x^2+1.1064x+0.0004  解释2:  MATLAB软件提供了基本的曲线拟合函数的命令.  多项式函数拟合:a=polyfit(xdata,ydata,n)  其中n表示多项式的最高阶数,xdata,ydata为将要拟合的数据,它是用数组的方式输入.输出参数a为拟合多项式y=a1xn+...+anx+a n+1的系数  多项式在x处的值y可用下面程序计算.  y=polyval(a,x,m)  线性:m=1, 二次:m=2, …  polyfit的输出是一个多项式系数的行向量。为了计算在xi数据点的多项式值,调用MATLAB的函数polyval。  例:  x=0:0.1:1; y=[-0.447 1.978 3.28 6.16 7.08 7.34 7.66 9.56 9.489.30 11.2];
polyfit用法示例结果
A=polyfit(x,y,2)  z=polyval(A,x);  plot(x,y,'r*',x,z,'b')  释疑:  在不少书中和论坛上,polyfit被误写作“ployfit”,使得很多初学者误解,认为自己安装的MATLAB软件出错,无法找到这样的函数。只要注意拼写正确即可。同样地,polyval函数也易被误写为“ployval”。

最小二乘法,通常用在我们已知数学模型,但是不知道模型参数的情况下,通过实测数据,计算数学模型,例如,在题目中,数学模型就是直线方程y=ax+b,但是不知道直线方程的a和b。
本来呢,我们只需要两组(xi,yi),就可以解得a和b,但是由于实测数据都存在误差,所以,我们很容易想到一个办法,我们测很多组数据来让我的a和b更加准确。
数学模型如下:
F=ax+b-y
那么对于模型上的点(注意是模型上的点,也就是理论值),F=ax+b-y=0
但是对于实际值来说,F=axi+b-yi 一定不等于0。那么我们就要找到一对a和b,使得F尽可能接近于0。
也就是说,“偏离量总和最小”这个概念,在数学上实际上就是要求F的方差最小。
即 Σ F^2→0 (F的平方和趋近于0)
即 Σ(axi+b-yi)^2→0
那么我们得到一个方程f(a,b)=Σ(axi+b-yi)^2,我们要找到合适的a,b使得f(a,b)最小!也就是说,我们要找到的实际上是f(a,b)的最小值点。(因为方差不可能小于0)因此我们需要求f(a,b)的极值点。我们借助数学工具偏导。如果有一组a,b使得 ∂f(a,b)/∂a=0
∂f(a,b)/∂b=0
那么f(a,b)就是极值点,如果a,b只有一对,那么它就是最小值点。即 ∂( Σ(axi+b-yi)^2 )/∂a=0
∂( Σ(axi+b-yi)^2 )/∂b=0化简得到
a*Σxi^2 + b*Σxi = Σ(xi*yi)
a*Σxi + b*N = Σyi
其中N是(xi,yi)的个数。即我们测了多少组数据
解上面的二元方程,我们就可以得到唯一的一组a,b啦,这就是我们所需要的a和b

主要的问题是inline函数写法不对,matlab不能识别下面的写法:

f = inline('R * exp(-a * x)','[R a]','x');

像这种有多个待辨识参数的情况,应该写成一个向量,如

f = inline('c(1) * exp(-c(2) * x)','c','x');

 

 

参考代码:

% 生成测试数据
t=linspace(0,2*pi,50);
x=1.5*cos(t);
y=1.5*sin(t);
plot(x,y)
hold on
t=linspace(0,pi,30);
r=1.5 * exp(-1 * t) + 0.02 * randn(size(t));  % 数据中加入噪声
x=r.*cos(t);
y=r.*sin(t);
plot(x,y,'r')
axis equal
 
% curve fit
[theta, rho] = cart2pol(x, y);  % transform into polar coord
idx = (x<=eps) & (y<=eps);
theta(idx) = [];
rho(idx) = [];
f = inline('c(1) * exp(-c(2) * x)','c','x');
[BestPara,resnorm,residul] = lsqcurvefit(f, [1.5 1], theta, rho);
R = f(BestPara, theta);
X=R.*cos(theta);
Y=R.*sin(theta);
plot(X,Y,':g')
legend('圆', '原始数据', '拟合数据');

结果如图: