几种常见的插值方法

插值的概念和方法

插值是指通过已知数据点的信息,构造出一条经过这些点的曲线或曲面,从而在已知数据点之间进行预测或估计。插值方法可以保证插值曲线通过已知数据点,因此在这些点上的预测或估计结果是准确的。然而,插值方法不能保证在已知数据点之外的区域的预测或估计结果的准确性,因为插值曲线可能会出现振荡或不合理的行为。

常见的插值方法有如下几种:

  • 线性插值:使用两个相邻数据点之间的直线来进行插值。线性插值简单直观,但在数据点之间可能会产生不连续或不光滑的曲线。
  • 多项式插值:使用多项式函数来拟合数据点之间的曲线。常见的多项式插值方法包括拉格朗日插值和牛顿插值。
    拉格朗日插值通过构造一个多项式函数,使得该函数在已知数据点上与原始函数完全一致。拉格朗日插值可以保证插值曲线通过已知数据点,但在高次插值中可能会出现振荡现象。
    牛顿插值通过构造一个递推的多项式,使得该多项式在已知数据点上与原始函数完全一致。牛顿插值可以保证插值曲线通过已知数据点,且在高次插值中不容易出现振荡现象。
  • 二次插值:二次插值是通过已知的三个数据点构造出一个二次多项式来拟合数据。它能够准确预测已知数据点之间的值,并且插值曲线相对于线性插值曲线更平滑。然而,二次插值只能拟合三个数据点,对于更复杂的数据分布可能不够准确。在选择插值方法时,需要根据具体情况权衡其优缺点。
  • 样条插值:样条插值是一种插值方法,通过使用分段连续的低次多项式来逼近数据,从而得到一条平滑的曲线。样条插值的基本思想是将插值区间分成多个小段,每个小段内使用一个低次多项式进行插值。最常见的样条插值方法是三次样条插值。样条插值曲线平滑且连续,能够更好地逼近实际曲线,并且可以通过调整边界条件来控制曲线的性质,如曲率、斜率等。然而,样条插值的计算复杂度高,尤其是在大数据集或高维数据情况下。另外,样条插值需要确定边界条件,不同的边界条件可能会导致不同的插值结果。
  • 三次样条插值:三次样条插值是一种常用的插值方法,它通过在给定的数据点上构造一组三次多项式来逼近原始数据,从而实现数据的插值。三次样条插值的基本思想是将插值区间划分为若干小段,每一段使用一个三次多项式进行插值。这些多项式的系数由插值条件(保证插值多项式经过给定的数据点)和光滑条件(保证相邻插值多项式在插值点处的函数值和导数值连续)决定。通过求解这些条件,可以得到每个小段上的三次多项式的系数,从而完成插值。三次样条插值的优点是可以较好地保持原始数据的特征,同时具有较好的光滑性质。然而,它的计算复杂度较高,需要求解大量的线性方程组,因此在实际应用中需要考虑计算效率和精度的平衡。
  • 最小二乘插值:最小二乘插值的目标是找到一个函数,使得该函数在给定数据点上的误差的平方和最小。其优点是可以灵活地选择插值函数的形式,并且可以通过最小二乘法来优化拟合函数的参数,得到更好的拟合结果。然而,最小二乘插值也有一些限制,例如当数据点较少或分布不均匀时,可能会导致拟合函数的不准确性。此外,最小二乘插值只能在已知数据点的范围内进行插值,无法对超出数据范围的自变量进行估计。

几种插值方法的代码演示

三次样条插值

import numpy as np
from scipy.interpolate import interp1d


# wavelength和absorbance是以列表形式存储的对齐的数据
wavelength_arr = np.array(wavelength)  # 转成numpy数组
absorbance_arr = np.array(absorbance)  # 转成numpy数组

# 定义插值函数;'cubic'为三次样条插值,'linear'为线性插值,'quadratic'为二次插值
interpolator = interp1d(wavelength_arr, absorbance_arr, kind='cubic')  # 三个参数分别为自变量、因变量、插值类型

# 定义要计算的插值数据的自变量
interpolated_wavelength_arr = np.linspace(470, 645, 175)  # 自变量范围为470-645,共175个自变量值

# 进行插值计算,得到插值后的absorbance数据
interpolated_absorbance_arr = interpolator(interpolated_wavelength_arr)

最小二乘插值

import numpy as np
from scipy.optimize import least_squares


# wavelength和absorbance是以列表形式存储的对齐的数据
wavelength_arr = np.array(wavelength)  # 转成numpy数组
absorbance_arr = np.array(absorbance)  # 转成numpy数组

# 选择插值函数,例如多项式插值
def polynomial_func(x, coeffs):
    return np.polyval(coeffs, x)  # 多项式求解,两个参数分别为多项式系数和自变量

# 构建拟合方程
def fit_func(coeffs, x, y):
    return polynomial_func(x, coeffs) - y

# 初始化多项式系数
initial_coeffs = np.zeros(3)

# 定义插值方法
result = least_squares(fit_func, initial_coeffs, args=(wavelength_arr, absorbance_arr))

# 获取拟合参数
fit_coeffs = result.x

# 定义要计算的插值数据的自变量
interpolated_wavelength_arr = np.linspace(470, 645, 175)

# 进行插值计算,得到插值后的absorbance数据
interpolated_absorbance_arr = polynomial_func(interpolated_wavelength_arr, fit_coeffs)

线性插值(自定义函数版)

import numpy as np


def linear_interpolation(x, y, x_new):
    # 确保输入的x和y是一维数组,并且长度相同
    x_arr = np.array(x)
    y_arr = np.array(y)
    assert x_arr.ndim == 1 and y_arr.ndim == 1 and len(x_arr) == len(y_arr)

    # 根据输入的x和y计算斜率
    slopes = np.diff(y_arr) / np.diff(x_arr)

    # 根据斜率和x_new计算插值结果
    y_new = y_arr[:-1] + slopes * (x_new - x_arr[:-1])

    return y_new


x_list = [1, 2, 3, 4, 5]
y_list = [2, 4, 6, 8, 10]
x_new_list = [1.5, 2.5, 3.5, 4.5]

y_new = linear_interpolation(x_list, y_list, x_new_list)

print(y_new)
---------
[3. 5. 7. 9.]

拟合的概念和方法

拟合是指通过已知数据点的信息,找到一条曲线或曲面,使得该曲线或曲面与已知数据点的偏差最小。拟合的目标是找到一个简单的函数或模型来近似描述数据的整体趋势。拟合方法可以在已知数据点之外的区域进行预测或估计,但预测或估计结果可能会有一定的误差。

常见的拟合方法有如下几种:

  • 线性拟合:建立线性模型,通过最小化观测值与线性模型之间的平方差来拟合数据。

  • 非线性拟合:用于拟合非线性函数的方法,如曲线拟合、曲面拟合等。非线性拟合方法通常使用迭代优化算法,通过不断调整模型参数,使得拟合曲线与数据点之间的误差最小。

  • 最小二乘法拟合:通过最小化数据点与拟合曲线之间的误差平方和,找到最优的拟合曲线。最小二乘法拟合可以用于拟合线性函数、多项式函数、指数函数等不同类型的曲线。

  • 插值法:通过已知数据点之间的插值来拟合数据,常见的插值方法包括线性插值、拉格朗日插值、样条插值等。在插值过程中,我们假设已知数据点之间存在某种函数关系,并使用这种函数关系来填补未知数据点的值。因此,插值可以被认为是拟合的一种方法,通过拟合已知数据点之间的函数来推断未知数据点的值。

拟合的优点是可以找到一个整体的近似描述,可以在已知数据点之外的区域进行预测或估计。然而,拟合方法在已知数据点上的结果可能存在一定的误差,因为拟合曲线只是对数据的近似描述,并不一定通过所有已知数据点。

总结

插值和拟合的区别在于插值方法可以确保通过已知数据点,因此在这些点上的结果是准确的,但在已知数据点之外的区域可能不准确;而拟合方法是找到一个整体的近似描述,可以在已知数据点之外的区域进行预测或估计,但结果可能有一定的误差。插值可以被认为是拟合的一种方法。

猜你喜欢

转载自blog.csdn.net/weixin_48158964/article/details/132184770