数模(3):线性、多项式、简单曲线拟合

1.线性函数拟合

先来看最简单的例子,对于线性函数 y = a x + b y=ax+b ,可以使用最小二乘法来确定a、b两个系数。对于N个点,x值对应函数值与y值的差值平方和(残差平方和)作为目标函数,分别对a、b求偏导,令偏导为0,得到两个方程,联立解得系数。

设有N个点坐标为 ( x i , y i ) , i = 1 , 2 , . . . , N (x_i,y_i),i=1,2,...,N ,则残差平方和为 i = 1 N ( a x i + b y i ) 2 \sum_{i=1}^N(ax_i+b-y_i)^2 ,展开来就是 ( a x 1 + b y 1 ) 2 + ( a x 2 + b y 2 ) 2 + . . . + ( a x N + b y N ) 2 (ax_1+b-y_1)^2+(ax_2+b-y_2)^2+...+(ax_N+b-y_N)^2 ,分别对a、b求偏导并令偏导为0得两个方程:

  1. i = 1 N ( a x i + b y i ) x i = 0 \sum_{i=1}^{N}(ax_i+b-y_i)x_i=0
  2. i = 1 N ( a x i + b y i ) = 0 \sum_{i=1}^{N}(ax_i+b-y_i)=0

联立以上两个方程即可求解。

2.可化成线性函数的曲线拟合

幂函数拟合、双曲线(在一三象限的那种形式)拟合、指数函数拟合、对数函数拟合,都可以利用最小二乘法来解决。但是这些函数的偏导数可能很复杂,列出的方程组是非线性方程组,解算较为困难。因此我们需要通过变换点坐标把这些曲线转化为线性函数。

幂函数的一般方程为 y = a x b y=ax^b ,两边取对数可变换为 l n y = b l n x + l n a lny=blnx+lna ,换元可得 y = b x + a y'=bx'+a' 。对每个点(x,y)的x值和y值取对数可得到(x’,y’),化为线性函数拟合问题。

双曲线的一般方程为 y = 1 a x + b y=\frac{1}{ax+b} ,两边取倒数可变换为 1 y = a x + b \frac{1}{y}=ax+b ,换元得 y = a x + b y'=ax+b 。对每个点(x,y)的y值取倒数即可得到(x,y’),化为线性函数拟合问题。

指数函数的一般方程为 y = a e b x y=ae^{bx} ,两边取自然对数可变换为 l n y = l n a + b x lny=lna+bx ,换元得 y = a + b x y'=a'+bx 。对每个点(x,y)的y值取对数即可得到(x,y’),化为线性函数拟合问题。

对数函数的一般方程为 y = a l n x + b y=alnx+b ,换元得 y = a x + b y=ax'+b 。对每个点(x,y)的x值取对数即可得到(x’,y),化为线性函数拟合问题。

3.系数间为线性关系的曲线拟合

再来看个例子 y = a e x + b s i n x + c x 3 y=ae^x+bsinx+cx^3 ,虽然这不是一个线性函数,也不能通过坐标变换化成线性函数,但如果设x为常量,a、b、c为变量,则a、b、c三个系数之间是线性关系的,因此残差平方和求偏导后得到的方程组依然是线性方程组。

设有N个点坐标为 ( x i , y i ) , i = 1 , 2 , . . . , N (x_i,y_i),i=1,2,...,N ,则残差平方和为 i = 1 N ( a e x i + b s i n x i + c x i 3 y i ) 2 \sum_{i=1}^N(ae^{x_i}+bsinx_i+cx_i^3-y_i)^2 ,展开来就是 ( a e x 1 + b s i n x 1 + c x 1 3 y 1 ) 2 + ( a e x 2 + b s i n x 2 + c x 2 3 y 2 ) 2 + . . . + ( a e x N + b s i n x N + c x N 3 y N ) 2 (ae^{x_1}+bsinx_1+cx_1^3-y_1)^2+(ae^{x_2}+bsinx_2+cx_2^3-y_2)^2+...+(ae^{x_N}+bsinx_N+cx_N^3-y_N)^2 ,分别对a、b、c求偏导并令偏导为0得三个方程:

  1. i = 1 N ( a e x i + b s i n x i + c x i 3 y i ) e x i = 0 \sum_{i=1}^N(ae^{x_i}+bsinx_i+cx_i^3-y_i)e^{x_i}=0
  2. i = 1 N ( a e x i + b s i n x i + c x i 3 y i ) s i n x i = 0 \sum_{i=1}^N(ae^{x_i}+bsinx_i+cx_i^3-y_i)sinx_i=0
  3. i = 1 N ( a e x i + b s i n x i + c x i 3 y i ) x i 3 = 0 \sum_{i=1}^N(ae^{x_i}+bsinx_i+cx_i^3-y_i)x_i^3=0

联立以上三个方程即可求解。

典例:n阶多项式拟合

n阶多项式拟合同样采用最小二乘法。大体思路是对于N个点,用n+1个待定系数设出函数,将残差平方和作为目标函数,分别对n+1个系数求偏导,令偏导为0,得到n+1个方程,联立解得系数。

设有N个点坐标为 ( x i , y i ) , i = 1 , 2 , . . . , N (x_i,y_i),i=1,2,...,N ,设n次函数 f ( x ) = k = 0 n a k x k f(x)=\sum_{k=0}^{n}a_kx^k ,则其残差平方和为 i = 1 N k = 0 n ( a k x i k y i ) 2 \sum_{i=1}^N\sum_{k=0}^{n}(a_kx_i^k-y_i)^2 ,展开来就是 ( a 0 + a 1 x 1 + . . . + a n x 1 n y 1 ) 2 + ( a 0 + a 1 x 2 + . . . + a n x 2 n y 2 ) 2 + . . . + ( a 0 + a 1 x N + . . . + a n x N n y N ) 2 (a_0+a_1x_1+...+a_nx_1^n-y_1)^2+(a_0+a_1x_2+...+a_nx_2^n-y_2)^2+...+(a_0+a_1x_N+...+a_nx_N^n-y_N)^2 ,设其对aj求偏导并令偏导等于0,得 2 ( a 0 + a 1 x 1 + . . . + a n x 1 n y 1 ) x 1 j + 2 ( a 0 + a 1 x 2 + . . . + a n x 2 n y 2 ) x 2 j + . . . + 2 ( a 0 + a 1 x N + . . . + a n x N n y N ) x N j = 0 2(a_0+a_1x_1+...+a_nx_1^n-y_1)x_1^j+2(a_0+a_1x_2+...+a_nx_2^n-y_2)x_2^j+...+2(a_0+a_1x_N+...+a_nx_N^n-y_N)x_N^j=0 ,整理得 i = 1 N k = 0 n a k x i j + k i = 1 N y i x i j = 0 , j = 0 , 1 , . . . , n \sum_{i=1}^{N}\sum_{k=0}^{n}a_kx_i^{j+k}-\sum_{i=1}^{N}y_ix_i^j=0,j=0,1,...,n ,可见j有n+1个取值,将n+1个点代入可以列出n+1个线性方程,利用线性代数知识可以解出系数值。

4.n阶多项式拟合实例

本实例演示使用python进行n阶多项式拟合,线性函数拟合其实就是一阶多项式拟合,而非线性函数拟合实例则放到下一期进行讲解。

1999-2004年长江排污量如下表:

年份 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
排污量/亿吨 174 179 183 189 207 234 220 256 270 285

用二次多项式来拟合以上数据,python代码如下:

import numpy as np
from matplotlib import pyplot

num=int(input())
x=[]
y=[]
for i in range(0,num):
    x.append(int(input()))
    y.append(int(input()))
z1 = np.polyfit(x, y, 2)
z = np.polyval(z1, x)
print(z1)

pyplot.plot(x,y,'.')
pyplot.plot(x,z,'-')
pyplot.show()

得到模型为 y = 0.84 x 2 3349.94 x + 3336464.85 y=0.84x^2-3349.94x+3336464.85 ,图像如下:
在这里插入图片描述

发布了24 篇原创文章 · 获赞 11 · 访问量 3901

猜你喜欢

转载自blog.csdn.net/weixin_43441742/article/details/97835081