插值与拟合

插值

已知函数在一个区间上的若干个离散的点,需要求解这些节点之间的函数值时,常用满足一定条件的函数替代该函数。插值法和拟合法是两种常用的方法。

插值函数需要过已知节点,拟合函数则不需要,只需要在某种意义下这些节点的总偏差最小。

一维插值

常见插值方法有拉格朗日插值法,分段线性插值法,样条插值法。

  1. 节点数n较大时,拉格朗日插值多项式次数高,计算复杂,会带来误差;
  2. 分段线性插值函数收敛但不光滑;
  3. 抽条插值函数光滑连续,插值误差小,较为常用。若每个节点区间内的多项式插值函数为m次,则称插值函数为m阶。

python的scipy实现插值函数

from scipy.interpolate import interp1d

x=[] # 节点数据
y=[]

# kind可取nearest,zero,slinear,quadratic,cubic
## nearest,zero为阶梯插值
## slinear 为线性插值
## quadratic,cubic 为2阶,3阶样条曲线插值
kind='cubic'
f=interp1d(x,y,kind=kind) # kind类的插值函数

二维插值

若节点是二维,插值函数就是二维函数

py实现二位插值函数

# 二维插值
x,y=[],[] # 节点x-y
z=[] # 节点z

# kind同上
f_2d=interp2d(x,y,z,kind='cubic')

曲线拟合

python拟合任意数据和曲线并求函数表达式

  1. 多项式拟合

    数学上可证明,任意函数都可以表示为多项式。

    # 多项式拟合
    ## deg为多项式阶数
    def PolyFit(x,y,deg):
        z=np.polyfit(x,y,deg)
        p=np.poly1d(z) # 获得拟合函数的多项式系数,按照阶数从高到低排列
        print("你和的多项式为:",p) # 显示拟合的多项式函数
    
        yvals=p(x) # 求对应于x的拟合多项式值
        # yvals=np.polyval(z,x) # 同上
        Draw(x,y,yvals,'polyfitting')
    
  2. 给出拟合函数形式

    使用scipy.optimize的curve_fit进行拟合。

    # curve_fit拟合
    def Func(p,x): # 拟合函数形式,p为系数
        pass
    
    def CurveFit(x,y,Func):
        # 进行拟合
        popt,pcov=curve_fit(Func,x,y) # popt是拟合系数,pcov是在popt参数下得到的协方差
        yvals=Func(popt,x)
        Draw(x, y, yvals, 'curvefitting')
    
  3. 代码整合

    import numpy as np
    import matplotlib.pyplot as plt
    from scipy.optimize import curve_fit
    
    # 绘图
    ##yvals为预测值,kind为拟合类型
    def Draw(x,y,yvals,kind):
        plot1=plt.plot(x,y,'s',label='original values')
        plot2=plt.plot(x,yvals,'r',label=kind+'values')
        plt.xlabel('x')
        plt.ylabel('y')
        plt.legend(loc=4)
        plt.title(kind)
        plt.show()
    
    # 多项式拟合
    ## deg为多项式阶数
    def PolyFit(x,y,deg):
        z=np.polyfit(x,y,deg)
        p=np.poly1d(z) # 获得拟合函数的多项式系数,按照阶数从高到低排列
        print("你和的多项式为:",p) # 显示拟合的多项式函数
    
        yvals=p(x) # 求对应于x的拟合多项式值
        # yvals=np.polyval(z,x) # 同上
        Draw(x,y,yvals,'polyfitting')
    
    
    
    # curve_fit拟合
    def Func(p,x): # 拟合函数形式,p为系数
        pass
    
    def CurveFit(x,y,Func):
        # 进行拟合
        popt,pcov=curve_fit(Func,x,y) # popt是拟合系数,pcov是在popt参数下得到的协方差
        yvals=Func(popt,x)
        Draw(x, y, yvals, 'curvefitting')
    
    
    
    x=[] # 待拟合的节点数据
    y=[]
    x,y=np.array(x),np.array(y)
    
    
  4. 示例

    def f1(x):
        y=x**3-6*x**2+5*x-3
        return y
    
    x=np.linspace(0,10,10)
    y=f1(x)
    noise=np.random.randn(len(x))
    y+=noise
    PolyFit(x,y,3)
    
    
    # 结果
    # 拟合的多项式为:        3         2
    #1.001 x - 6.011 x + 4.996 x - 2.798
    

def Func(x,a,b): # 拟合函数形式,p为系数
    # a,b=p[0],p[1]
    return a*np.e**(b*x)

x=[1,2,3,4,5,6,7,8] # 待拟合的节点数据
y=[15.3,20.5,27.4,36.6,49.1,65.6,87.87,117.6]
x,y=np.array(x),np.array(y)
CurveFit(x,y,Func)

参考:

https://blog.csdn.net/qq_20011607/article/details/81412985

https://www.cnblogs.com/niuniu238/articles/p.html

https://blog.csdn.net/changdejie/article/details/83089933

posted @ 2021-01-25 20:28  圆圆的圈圈  阅读(866)  评论(0)    收藏  举报