matlab简单拟合,polyfit和curve fit tool(鱼的质量与身长和腰围的关系)

在下小白,只会用简单的curve fit中的polynomial和equation,这里简单介绍了一下用工具箱,poly fit函数拟合和计算相对误差的方法,模型建立如有不合理之处,纯属为了练手而建模。

鱼的质量与身长和腰围的关系

问题重述:

一垂钓俱乐部鼓励垂钓者将钓上的鱼放生,打算按照放生的鱼的重量给予奖励,俱乐部只准备了一把软尺用于测量,请你设计按照测量的长度估计鱼的重量的方法.假定鱼池中只有一种鲈鱼,并且得到8条鱼的如下数据(胸围指鱼身的最大周长):

  

身长(cm)

36.8

31.8

43.8

36.8

32.1

45.1

35.9

32.1

重量(g)

765

482

1162

737

482

1389

652

454

胸围(cm)

24.8

21.3

27.9

24.8

21.6

31.8

22.9

21.6

  先用机理分析建立模型,再用数据确定参数.

 

模型假设

1.      模型一:假设鱼的质量只与身长有关,且假设质量与身长的一次方成正比

2.      模型二:假设鱼的质量与身长腰围同时相关且与质量与身长,腰围的平方,身长与腰围的乘积有关

3.      模型三:假设鱼的质量与身长乘腰围的平方成正比

4.      假设鱼没有四肢,可近似看作圆柱

5.      假设模型拟合效果可由各组数据的相对误差的平均值来衡量

建立模型

模型一

只对身长进行一次拟合 

 

方法一:

使用curvefit工具箱,得到如下系数

运行如下的脚本代码,计算拟合值与真实值的相对误差

x=[31.8,32.1,32.1,35.9,36.8,36.8,43.8,45.1]

z=[482,454,482,652,737,765,1162,1389]

y=[21.3,21.6,21.6,22.9,24.8,24.8,27.8,31.9];

p1 =65.29

p2 =-1637

z1= p1*x + p2

r=z1-z

re=r./z

res=strcat(num2str(mean(re)*100),'%')

 

得到平均相对误差res=' 4.779%'

 

 

方法二:

使用polyfit一次拟合

 

得到平均相对误差res= '4.7701%'

模型评价:

从以上两种方法中可以看出,误差在4.8%左右,还是比较符合实际情况的,poly fit拟合效果略好于curvefit工具箱的效果,但是相对误差还是较大

 

 

模型二:

假设鱼为圆柱体,没有四肢,因为圆柱体的体积为长乘π/4乘直径的平方,底面周长又等于直径乘π,则可认为鱼的质量与身长和腰围的平方的乘积成正比

这里令x为身长,y为腰围,z为质量,

 

选择polynomial拟合,设定质量和身长的一次方,腰围的二次方相关,得到拟合图形及系数如图

运行如下代码求出平均相对误差

x=[31.8,32.1,32.1,35.9,36.8,36.8,43.8,45.1]

z=[482,454,482,652,737,765,1162,1389]

y=[21.3,21.6,21.6,22.9,24.8,24.8,27.8,31.9];

p00 =-187.5 

p10 =-6.198 

p01 =-7.045 

p11 =1.891

p02 =-0.6289 

z1= p00 + p10*x + p01*y +p11*x.*y + p02*y.^2

plot3(x,y,z1)

r=z1-z% r为拟合值和实际值之差的数组

re=absr./z% re为各组数据相对误差res=strcat(num2str(mean(re)*100),'%')

%res为各组相对误差的平均值,可大致反应拟合整体的相对误差

得到相对误差res =1.8121%'

 

 

 

 

 

 

模型评价:

         平均相对误差在1.8%,能够很好地描述身长腰围质量之间的关系,

以上为多项式拟合,另外也可以使用定制拟合的方法,令公式为

z=p00 + p10*x + p01*y + p11*x.*y + p02*y.^2'

得到结果与多项式拟合完全相等

 

 

模型三:

上面讨论了使用多项式拟合的方法,但是只能按照公式z1= p00 + p10*x + p01*y + p11*x.*y + p02*y.^2拟合,由常识我们知道,鱼近似与圆柱体,圆柱体体积与长度乘截面周长的平方成正比,于是我们设想是否三者之间满足z=a*x*y^2+ b关系

curvefit 中选择custom Equation,输入公式,得到如下结果

 

编写脚本文件计算误差

 

x=[31.8,32.1,32.1,35.9,36.8,36.8,43.8,45.1]

z=[482,454,482,652,737,765,1162,1389]

y=[21.3,21.6,21.6,22.9,24.8,24.8,27.8,31.9];

a =0.03056

b =46.46

z1=a*x.*y+b

r=abs(z1-z)

re=r./z

res=strcat(num2str(mean(re)*100),'%')

得到误差为'89.0792%'

可见实际情况并非与理论推导一致

 

总结:

   鱼的质量与身长腰围大致满足z1= p00 + p10*x + p01*y + p11*x.*y + p02*y.^2关系,使用多项式拟合可以控制误差在1.8%,效果较好,而简单地认为鱼的质量与身长乘腰围的平方成正比的结果误差较大,认为只与身长的一次方有关的误差在4.8%左右。

 

使用poly fit计算误差
cla 
x=[31.8,32.1,32.1,35.9,36.8,36.8,43.8,45.1];
y=[482,454,482,652,737,765,1162,1389];
plot(x,y,'bo');title('身长与质量一次拟合');hold on 
a=polyfit(x,y,1)
b=polyval(a,x)
s=poly2sym(a);%系数矩阵转化成方程但是是分数
t=subs(s,x)%把x数组整体带入求值
y1=vpa(y1,8)%转化成小数并稍微控制一下位数
r=abs(y1-y)%平均误差记得用一下绝对值再加
re=r./y%相对误差,得到的是syms类型需要转化成double
res=strcat(num2str(mean(double(re))*100),'%')%平均相对误差并转化成百分数
从curvefit tool中导出
x=[31.8,32.1,32.1,35.9,36.8,36.8,43.8,45.1]
z=[482,454,482,652,737,765,1162,1389]
y=[21.3,21.6,21.6,22.9,24.8,24.8,27.8,31.9];
p=x.*y.^2
a=polyfit(p,z,1)
b=polyval(a,p)
s=poly2sym(a);%系数矩阵转化成方程但是是分数
t=subs(s,p)%把x数组整体带入求值
p1=vpa(p1,8)%转化成小数并稍微控制一下位数
r=abs(p1-p)%平均误差记得用一下绝对值再加
re=r./p%相对误差,得到的是syms类型需要转化成double
res=strcat(num2str(mean(double(re))*100),'%')%平均相对误差并转化成百分数


猜你喜欢

转载自blog.csdn.net/qq_38445415/article/details/79903636