2023年6月29日发(作者:)
Python⼩⽩的数学建模课-22.插值⽅法Python⼩⽩的课-22.插值⽅法插值、拟合、回归和预测,都是数学建模中经常提到的概念,也经常被混淆。插值,是在离散数据的基础上补插连续函数,使得插值函数通过全部给定的离散数据点,多⽤于图像处理和缺失数据处理。使⽤ Scipy ⼯具包的 interpolate 插值模块,通过例程讲解⼀维插值、⼆维插值的实现⽅法。带你从数模⼩⽩成为国赛达⼈。1. 数据1.1 插值与插值与拟合,不仅是基本的数学建模⽅法,也是最常⽤的数据处理⽅法。不过,插值和拟合却经常会被混为⼀谈,所以我们⾸先看看这两个概念。插值,是在离散数据的基础上补插连续函数,使得插值函数通过全部给定的离散数据点。 插值是离散函数逼近的重要⽅法,利⽤它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值。简单地说,插值是求过⼀组已知点的近似函数。拟合,是⽤⼀个连续函数(曲线)靠近给定的离散数据,使其与给定的数据相吻合。拟合也是根据⼀组已知点求近似函数,但不要求过已知点。因此,插值和拟合都是根据⼀组已知数据点,求变化规律和特征相似的近似曲线的过程。但是插值要求近似曲线完全经过所有的给定数据点,⽽拟合只要求近似曲线在整体上尽可能接近数据点,并反映数据的变化规律和发展趋势。插值可以看作是⼀种特殊的拟合,是要求误差函数为 0 的拟合。由于数据点通常都带有误差,误差为 0 往往意味着过度拟合,过拟合模型对于训练集以外的数据的泛化能⼒往往是较差的。因此在实践中,插值多⽤于和缺失数据处理,拟合多⽤于实验数据处理。此外,还有⼀个常⽤⽽且容易混淆的概念: 回归。回归是研究⼀组随机变量与另⼀组随机变量之间关系的统计分析⽅法,包括建⽴数学模型并估计模型参数,并检验数学模型的可信度,也包括利⽤建⽴的模型和估计的模型参数进⾏预测或控制。回归是⼀种数据分析⽅法,拟合是⼀种具体的数据处理⽅法。拟合侧重于曲线参数寻优,使曲线与数据相符;⽽回归侧重于研究两个或多个变量之间的关系。1.2 插值⼯具箱数据插值是数据处理的常⽤⽅法,常见的插值算法有线性插值、B样条插值、临近插值等。Scipy ⼯具包带有插值⼯具箱,提供了丰富的插值⽅法和函数,可以⽤于⼀维、⼆维和多维插值。⼀维函数插值的类 interp1d,提供了多种插值⽅法,如样条函数插值、⼀维和多维插值、拉格朗⽇插值、泰勒多项式插值及⾃定义插值函数。函数 griddata 则提供了 N维插值的接⼝(N=1,2,3,…)。2. Scipy ⼀维插值⽅法:内插值2.1 ⼀维插值类 olate 中的 interp1d 类是⼀种基于固定数据点创建函数的⽅法,可以使⽤函数插值在给定数据定义的域内的任何位置对其进⾏计算。注意 interp1d 是内插法,不能外推运算(外插值)。该类定义调⽤,允许使⽤ x 轴值调⽤对象,此时应计算插值函数,并返回插值的 y 轴值。具体地说,interp1d 类⽣成已知数据点集的插值函数 y=f(x),通过调⽤这个插值函数,可以在已知数据之间插值,得到指定 x 的函数值 f(x)。class 1d(x, y, kind=‘linear’, axis=- 1, copy=True, bounds_error=None, fill_value=nan,assume_sorted=False)主要参数:x:⼀维数组,给定数据点集的 x 值。y:N 维数组,给定数据点集的 y 值,数组长度必须与 x 相等。kind:字符串或整数,可选项,指定使⽤的样条曲线的种类或插值⽅法。 可选的字符串:‘linear’, ‘nearest’, ‘nearest-up’,‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘previous’, ‘next’;‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’ 分别表⽰零次、⼀次、⼆次、三次样条插值;‘previous’, ‘next’ 分别表⽰只前点插值或后点插值;‘nearest’ 表⽰向下舍⼊,‘nearest-up’ 表⽰向上舍⼊;默认值为 ‘linear’,即线性插值。interp1d 允许通过参数 bounds_error、fill_value 设置外推时的边界值,但这并不是进⾏外推插值。返回值:类 interp1d() 返回⼀个函数,其调⽤⽅法使⽤插值来查找新点的值。2.2 Python 例程:interp1d 的使⽤使⽤⽰例:# 1.
⼀维插值使⽤⽰例import numpy as npimport as plt #
导⼊ Matplotlib
⼯具包from olate import interp1d #
导⼊ scipy
中的⼀维插值⼯具 interp1d#
已知数据点集 (x,y)x = [0.0, 2.0, 4.0, 6.0, 8.0, 10.0] #
已知数据 xy = [3.1, 2.7, 1.5, 0.1, 1.0, 3.9] #
已知数据 y#
由给定数据点集 (x,y)
求插值函数 fxfx = interp1d(x, y, kind='linear') #
由已知数据 (x,y)
求出插值函数 fx#
由插值函数 fx
计算插值点的函数值xInterp = ce(0,10,100) #
指定需插值的数据点集 xInterpyInterp = fx(xInterp) #
调⽤插值函数 fx,计算 xInterp
的函数值#
绘图(xInterp, yInterp, label="linear interpolate")()2.3 Python 例程:⼀维插值⽅法⽐较通过设置 interp1d 类的参数kind,可以指定使⽤的样条曲线的种类或插值⽅法。上节中介绍了 kind 各种选项所指的插值⽅法,本节进⼀步通过例程来⽐较不同⽅法的插值结果。Python 例程:829363738394647484950515253# mathmodel24_# Demo24 of mathematical modLSing algorithm# Demo of interpolate with olate# Copyright 2021 YouCans, XUPT# Crated:2021-08-01# 2.
⼀维插值⽅法(内插)⽐较import numpy as npimport as plt #
导⼊ Matplotlib
⼯具包from olate import interp1d #
导⼊ scipy
中的⼀维插值⼯具 interp1d#
⽣成已知数据点集 (x,y),需插值的数据点集 (5)x = ce(0, 5, 10) #
⽣成已知数据点集的 xy = (x/10)*2 + 0.5*(10) #
⽣成已知数据点集的 yxnew = ce(0, 5, 100) #
指定需插值的数据点集 xnew#
使⽤不同插值⽅法,由给定数据点集 (x,y)
求插值函数 fxf1 = interp1d(x, y, kind="linear") #
线性插值f2 = interp1d(x, y, kind="zero") #
零阶样条插值f3 = interp1d(x, y, kind="slinear") #
⼀次样条插值f4 = interp1d(x, y, kind="quadratic") #
⼆次样条插值f5 = interp1d(x, y, kind="cubic") #
三次样条插值f6 = interp1d(x, y, kind="nearest") #
临近点插值,向下舍⼊# f7 = interp1d(x, y, kind="nearest-up") #
临近点插值,向上舍⼊f8 = interp1d(x, y, kind="previous") #
前点插值f9 = interp1d(x, y, kind="next") #
后点插值#
绘图(figsize=(8,6))le("Data interpolate") #
全局标题t(221)(x, y, "o", label="data") #
已知数据点(xnew, f2(xnew), label="0-order spline") #
零阶样条插值(xnew, f3(xnew), label="1-order spline") #
⼀阶样条插值(loc="lower left")t(222)(x, y, "o", label="data") #
已知数据点(xnew, f4(xnew), label="2-order spline") #
⼆阶样条插值(xnew, f5(xnew), label="3-order spline") #
三阶样条插值(loc="lower left")t(223)(x, y, "o", label="data") #
已知数据点(xnew, f1(xnew), label="linear") #
线性插值(xnew, f6(xnew), label="nearest") #
临近点插值,向下舍⼊# (xnew, f7(xnew), label="nearest-up") #
临近点插值,向上舍⼊(loc="lower left")t(224)(x, y, "o", label="data") #
已知数据点(xnew, f8(xnew), label="previous") #
前点插值(xnew, f9(xnew), label="next") #
后点插值(loc="lower left")()程序运⾏结果:结果分析:1. 线性插值是常⽤的插值⽅法,简单地说可以理解为将相邻的数据点⽤线段连接,算法简单、运算速度快。⼀阶样条曲线插值,等效于线性插值。2. 最近邻点插值、前点插值、后点插值和 0阶样条插值的结果都是阶梯形状曲线,只是选点⽅法不同。3. 样条插值是重要的插值⽅法,⽤光滑曲线连接数据点。每⼀个样条都是⽤⼀个多项式表达的,多项式的次数就是样条曲线的阶数,决定了样条曲线的形状和性质:1. 0 阶样条曲线,在每⼀区间上样条函数为常数,样条曲线呈阶梯形状;2. 1 阶样条曲线,在每⼀区间上样条函数为线性函数,样条曲线呈折线段形状;3. 2 阶样条曲线,在每⼀区间上样条函数为⼆次函数,整体⼀阶连续可导;依次类推。4. 由⼆阶开始,插值函数不再具有局域性,改变某⼀节点,函数整体都会改变。5. 2 阶和 3阶样条插值最为常⽤,更⾼阶的样条插值过于复杂,通常结果的差异并不⼤。图中的 2阶和 3阶样条插值结果就已经近似是重合的。3. Scipy ⼀维插值⽅法:外插值3.1 ⼀维插值类 olate 中的 UnivariateSpline 类是⼀种基于固定数据点创建函数的⽅法,使⽤⼀维样条曲线拟合到给定的数据点集。该类定义调⽤,允许使⽤ x 轴值调⽤对象,此时应计算样条曲线,并返回插值的 y 轴值。具体地说,UnivariateSpline 类⽣成已知数据点集的样条插值函数 y=spl(x),通过调⽤样条插值函数,可以计算指定 x 的函数值 f(x)。class iateSpline(x, y, w=None, bbox=[None, None], k=3, s=None, ext=0, check_finite=False)主要参数:x:⼀维数组,数值必须递增。y:⼀维数组,数组长度必须与 x 相等。w:⼀维数组,正数,可选项。每个数据点的权重,默认所有点的权重相等。k:整数,可选项。样条函数的阶数, 1 ≤ k ≤ 5 1 leq k leq 5 1≤k≤5,默认值为 3。s:实数,可选项,平滑参数: s=0,数据插值,样条曲线必须通过所有数据点;s>0,数据拟合,满⾜ ∑ ( w ( y − s p l ( x ) ) ) 2≤ s sum(w(y-spl(x)))^2 leq s ∑(w(y−spl(x)))2≤s;默认不设置 s,则 s=len(w)。ext:整数或字符串,可选项。⽤于控制外推插值的⽅案: ext= 0 或 “extrapolate”,返回外推值,默认值;ext= 1 或“zeros”,返回 0;ext= 2 或 “raise”,抛出异常值 ValueError;ext= 3 或 “const”,返回边界值。返回值:类 UnivariateSpline() 返回⼀个函数,其调⽤⽅法使⽤插值来查找新点的值。UnivariateSpline 可以外插值,允许通过设置参数 ext= 0 或 “extrapolate” 外推插值。但如果外推范围过⼤,3.2 Python 例程:⼀维插值(UnivariateSpline)Python 例程:829# 3.
⼀维插值⽅法(外插)import numpy as npimport as plt #
导⼊ Matplotlib
⼯具包from olate import UnivariateSpline #
导⼊ scipy
中的⼀维插值⼯具 UnivariateSpline#
⽣成已知数据点集 (x,y),需插值的数据点集 xnewx = ce(0, 10, 11) #
⽣成已知数据点集的 xy = ((x)**2/30)*2+2 #
⽣成已知数据点集的 yxnew = ce(-0.5, 10.5, 110) #
指定需插值的数据点集 xnew#
使⽤ UnivariateSpline
插值⼯具,由给定数据点集 (x,y)
求插值函数 fSplfSpl1 = UnivariateSpline(x, y, s=0) #
三次样条插值,s=0:插值函数经过所有数据点y1 = fSpl1(xnew) #
由插值函数 fSpl1
计算插值点的函数值 y1fSpl2 = UnivariateSpline(x, y) #
三次样条插值,默认 s= len(w)y2 = fSpl2(xnew) #
由插值函数 fSpl2
计算插值点的函数值 _smoothing_factor(0.1) #
设置光滑因⼦ sfy3 = fSpl2(xnew) #
由插值函数 fSpl2(sf=0.1)
计算插值点的函数值 y3#
绘图fig, ax = ts(figsize=(8,6))(x, y, 'ro', ms=5, label="data")(xnew, y1, 'm', label="3rd spline interpolate")(xnew, y2, 'g', label="3rd spline fitting")(xnew, y3, 'b--', label="smoothing factor")_title("Data interpolate with extrapolation")(loc="best")()程序运⾏结果:结果分析:1. 类 UnivariateSpline 既可以进⾏数据插值,也可以进⾏数据拟合。1. 参数 s=0 时,要求样条函数通过所有数据点,即为数据插值;2. s>0 或不设置参数 s 时,不要求样条函数通过所有数据点,就是⽤样条函数拟合给定的数据。2. 类 UnivariateSpline 进⾏数据插值或数据拟合,具有⼀定的外推能⼒,可以由插值函数进⾏外推计算。但插值算法的外推范围⼗分有限,容易发散或失真,使⽤时要⾮常谨慎。3. 图中绿⾊曲线是三次样条数据拟合的结果,蓝⾊曲线对拟合曲线作了进⼀步的平滑处理。4. Scipy ⼆维插值⽅法4.1 ⼆维插值类 olate 中的 interp2d 类是⼀种基于固定数据点集创建函数的⼆维插值⽅法,经常⽤于⼆维图像处理。类 interp2d 的定义和使⽤⽅法与⼀维插值 interp1d 类似。该类定义调⽤,允许使⽤ (x,y) 值调⽤对象,此时计算插值函数,并返回插值的 z轴值。具体地说,interp2d 类⽣成已知数据点集的插值函数 z=f(x,y),通过调⽤这个插值函数,可以在已知数据之间插值,得到指定(x,y) 的函数值 f(x,y)。class 2d(x,y,z,kind=‘linear’,copy=True,bounds_error=False,fill_value=None))主要参数:x,y:⼀维数组,给定数据点集的 x,y 值。z:⼀维数组,给定数据点集对应的函数值 z。kind:字符串或整数,可选项,指定使⽤的样条曲线的种类或插值⽅法:‘linear’ 表⽰线性插值,‘cubic’ 表⽰三次插值,‘quintic’ 表⽰五次插值。默认值为 ‘linear’,即线性插值。返回值:类 interp2d() 返回⼀个函数,其调⽤⽅法使⽤插值来查找新点的值。注意:给定数据点集 x,y,z 有两种⽅式:1. 以⼀维数组 x 和 y 定义给定⽹络点集的列坐标和⾏坐标序列,⼀维数组 x 与 y 的长度 len(x)、len(y) 不⼀定相等,⼆维数组 z 的形状为 len(x)*len(y),zij=f(xi,yi) 是数据⽹格点 (xi,yj) 的函数值。2. 以⼀维数组 x, y 定义给定⽹络点集的列坐标和⾏坐标序列,⽹络点集中每个点的坐标分别由⼆维数组 xx 和 yy 表⽰, ⼆维数组 z 是与 (xx,yy) 对应的⽹格中每⼀个数据点的函数值,$z_{ij} = f(xx_{ij}, yy_{ij}) $。4.2 Python 例程:⼆维插值(interp2d)使⽤⽰例:82936373839404142# mathmodel24_# Demo24 of mathematical modLSing algorithm# Demo of interpolate with olate# Copyright 2021 YouCans, XUPT# Crated:2021-08-01# 4.
⼆维插值⽅法import numpy as npimport as pltfrom olate import interp2d #
导⼊ scipy
中的⼆维插值⼯具 interp2d#
⽣成已知数据⽹格点集 (xx,yy,z)x = ce(-1, 1.5, 25) # x
是⼀维数组y = ce(-1, 1, 20) # y
是⼀维数组xx, yy = id(x, y) #
⽣成⽹格点的坐标 xx,yy (⼆维数组)z = ((xx+yy+xx**2+yy**2)) #
计算数据⽹格点的值 z=f(xx,yy)print("shape of original dataset:ntxx:{},yy:{},z:{}".format(,,))#
由给定数据⽹格点集 (xx,yy,z)
求插值函数 fInterp: xx,yy,z
都是形状相同的⼆维数组fInterp = interp2d(xx, yy, z, kind='cubic') #
三阶样条插值#
由插值函数 fInterp
计算需插值的数据点的函数值xnew = ce(-1, 1.5, 150) # xnew
是⼀维数组ynew = ce(-1, 1, 100) # ynew
是⼀维数组znew = fInterp(xnew, ynew) #
计算插值函数 fInterp
在 (xnew, ynew)
所描述⽹格点集的函数值print("shape of interpolation dataset:ntxnew:{},ynew:{},znew:{}".format(,,))#
绘图fig = (figsize=(10, 6))ax1 = t(1, 2, 1, projection='3d')_title("2-D original data")# _wireframe(xx, yy, z, rstride=2, cstride=2, linewidth=1)surf = _surface(xx, yy, z, rstride=2, cstride=2, cmap=rm)_zlabel('zData')xxnew, yynew = id(xnew, ynew) #
将⼀维数组 xnew, ynew
转换为⽹格点集(⼆维数组)print("txxnew:{},yynew:{},znew:{}".format(,,))ax2 = t(1, 2, 2, projection='3d') # 3D
绘图要求 x,y,z
都是 n*m
⼆维数组_title("2-D interpolation data")_wireframe(xxnew, yynew, znew, rstride=2, cstride=2,linewidth=1)surf2 = _surface(xxnew, yynew, znew, rstride=2, cstride=2, cmap=rm)_zlabel('zInterp')()运⾏结果:12345shape of original dataset: xx:(20, 25),yy:(20, 25),z:(20, 25)shape of interpolation dataset: xnew:(150,),ynew:(100,),znew:(100, 150) xxnew:(100, 150),yynew:(100, 150),znew:(100, 150)注意: 由给定数据点集 (xx,yy,z) 求插值函数 fInterp 时 xx,yy,z 都是形状相同的⼆维数组(矩阵),由插值函数 fInterp 计算插值时所使⽤的 xnew,ynew 是⼀维数组,插值函数 fInterp 在 (xnew, ynew) 所构造的栅格点计算并返回插值函数值,返回值 z 是⼆维数组(矩阵)。4.3 Python 例程:⼆维插值通过设置 interp1d 类的参数kind,可以指定使⽤的样条曲线的种类或插值⽅法。上节中介绍了 kind 各种选项所指的插值⽅法,本节进⼀步通过例程来⽐较不同⽅法的插值结果。Python 例程:82936373839464748495051# mathmodel24_# Demo24 of mathematical modLSing algorithm# Demo of interpolate with olate# Copyright 2021 YouCans, XUPT# Crated:2021-08-01# 5.
⼆维插值⽅法import numpy as npimport as pltfrom olate import interp2d #
导⼊ scipy
中的⼆维插值⼯具 interp2d#
⽣成已知数据⽹格点集 (xx,yy,z)yy, xx = [-2:2:20j,-3:3:30j] #
⽣成⽹格点 30x20 = 600z = (1-0.5*xx+xx**5+yy**3) * (-xx**2-2*yy**2) #
计算⽹格点的值 zx, y = xx[0,:], yy[:,0] #
由数据⽹格点 xx,yy
转换⼀维数组 x, yprint("shape of original dataset:ntxx:{},yy:{},z:{}".format(,,))print("tx:{},y:{},z:{}".format(, , ))#
由给定数据点集 (x,y,z)
求插值函数 fInterp: x,y
是⼀维数组,z
是 len(x)*len(y)
⼆维数组f1 = interp2d(x, y, z, kind='linear') #
线性插值f2 = interp2d(x, y, z, kind='cubic') #
三阶样条插值f3 = interp2d(x, y, z, kind='quintic') #
五阶样条插值#
由插值函数 fInterp
计算需插值的⽹格点集 ynew,xnew
的函数值xnew = ce(-3, 3, 120) # xnew
是⼀维数组ynew = ce(-2, 2, 80) # ynew
是⼀维数组z1 = f1(xnew, ynew) #
根据线性插值函数 f1
计算需插值的⽹格点集的函数值z2 = f2(xnew, ynew) #
根据三阶样条插值函数 f2
计算需插值的⽹格点集的函数值z3 = f3(xnew, ynew) #
根据五阶样条插值函数 f3
计算需插值的⽹格点集的函数值print("shape of interpolation dataset:ntxnew:{},ynew:{},znew:{}".format(,,))#
绘图(figsize=(8,6))le("2-D data interpolate") #
全局标题t(221)(xx, yy, z, cmap=, shading='auto')("original")ar()t(222)(xnew, ynew, z1, cmap=, shading='auto')("linear")ar()t(223)(xnew, ynew, z2, cmap=, shading='auto')("cubic")ar()t(224)(xnew, ynew, z3, cmap=, shading='auto')("quintic")ar()()程序运⾏结果:【本节完】版权声明:欢迎关注 原创作品Copyright 2021 Youcans, XUPTCrated:2021-08-01欢迎关注 系列,持续更新
发布者:admin,转转请注明出处:http://www.yc00.com/web/1687976637a62759.html
评论列表(0条)