SciPy RBF 多维插值怎么实现?

文章导读
Previous Quiz Next 径向基函数 (RBF) 插值 是一种基于一组已知数据点估计未测量点值的方法。它使用径向基函数,这些函数是实值函数,其值仅取决于与中心点的距离。这种方法对于多维散乱数据特别有效。
📋 目录
  1. 常见的径向基函数 (RBFs)
  2. 高斯 RBF
  3. 多二次 RBF
  4. 逆多二次径向基函数 RBF
  5. 线性 RBF
  6. Cubic RBF
  7. 薄板样条 RBF
  8. 指数 RBF
A A

SciPy 径向基函数(RBF) 多维插值



Previous
Quiz
Next

径向基函数 (RBF) 插值 是一种基于一组已知数据点估计未测量点值的方法。它使用径向基函数,这些函数是实值函数,其值仅取决于与中心点的距离。这种方法对于多维散乱数据特别有效。

径向基函数 f(x) 的数学公式如下所示 −

RBF Interpolation Example
  • N 是数据点的数量。
  • x 是估计函数值的输入点。
  • xi 是已知数据点。
  • wi 是由数据点处函数值确定的权重。
  • 是径向基函数,通常取决于欧几里得距离 ||x-xi||。

常见的径向基函数 (RBFs)

径向基函数是数学函数,其值仅取决于与中心点的距离。由于其逼近复杂表面的能力,它们广泛用于插值、机器学习和各种数值方法。以下是一些最常见的径向基函数类型 −

高斯 RBF

高斯 RBF 是最广泛使用的径向基函数之一。随着与中心的距离 r 增加,它迅速衰减,提供平滑且局部的影響。

Gaussian RBF Interpolation Formula

以下是高斯 RBF 的关键特性 −

  • 平滑性: 高斯函数是无限可微的,使其非常平滑。此属性有利于插值和逼近的各种应用。
  • 局部影响: 高斯 RBF 的影响随着远离中心而迅速减弱,这意味着它具有强烈的局部影响,有助于捕捉数据的局部变化。
  • 径向对称性: 输出仅取决于与中心的距离,而不取决于方向,使其具有旋转对称性。
  • 应用: 高斯 RBF 常用于以下各种领域 −
    • 机器学习: 在支持向量机和核化方法中。
    • 数据插值: 从散乱数据点构建平滑表面。
    • 函数逼近: 使用 RBF 网络逼近复杂函数。

示例

在 SciPy 中,我们可以使用 RBFInterpolator 来进行使用高斯 RBF 的插值。以下是一个在 SciPy 中使用高斯 RBF 进行 2D 插值的简单示例 −

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import RBFInterpolator

# 样本数据点
x = np.array([0, 1, 2, 3])
y = np.array([0, 1, 0, 1])
z = np.array([1, 2, 0, 1])  # 点处的函数值

# 使用高斯函数和指定 epsilon 创建 RBF 插值器
epsilon = 0.5  # 调整 epsilon 以获得更平滑或更锐利的插值
interpolator = RBFInterpolator(np.array(list(zip(x, y))), z, kernel='gaussian', epsilon=epsilon)

# 定义插值的新点
xi, yi = np.meshgrid(np.linspace(0, 3, 100), np.linspace(0, 1, 100))
zi = interpolator(np.array(list(zip(xi.ravel(), yi.ravel())))).reshape(xi.shape)

# 绘制结果
plt.figure(figsize=(10, 6))
plt.scatter(x, y, c='red', label='数据点', zorder=5)
plt.contourf(xi, yi, zi, levels=15, cmap='viridis', alpha=0.7)
plt.colorbar(label='插值值')
plt.title('高斯 RBF 插值示例')
plt.xlabel('X 轴')
plt.ylabel('Y 轴')
plt.legend()
plt.show()

以下是 SciPy 中高斯 RBF 插值的输出 −

Gaussian RBF Interpolation Example

多二次 RBF

多二次径向基函数 (RBF) 是一种广泛用于插值的径向基函数,特别是在散乱数据插值和曲面拟合中。其数学定义由以下公式给出 −

Multiquadric RBF Interpolation Formula

其中 −

  • r 是给定点与中心点之间的欧几里得距离。
  • 是形状参数,即正常量,用于控制函数的“平坦度”或扩展范围。

以下是多二次 RBF 的主要特性 −

  • 全局影响: 与高斯 RBF 等其他 RBF 不同,多二次 RBF 倾向于产生全局平滑效果,即一点的变化会影响远处的点。
  • 灵活性: 可以调整形状参数 来控制函数衰减的速度,从而平衡局部和全局影响。
  • 平滑插值: 它通常产生平滑的插值,这使其适用于建模预期连续且可微的曲面或函数。
  • 应用: 多二次 RBF 常用于以下各种领域 −
    • 2D 或 3D 曲面拟合。
    • 地理空间数据插值,如地形建模。
    • 通过无网格方法求解偏微分方程 (PDEs)。

示例

此示例展示如何使用多二次 RBF 根据散乱数据点生成平滑曲面 −

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import Rbf

# 定义样本数据点
x = np.random.uniform(-5, 5, 10)  # 10 个随机 x 值
y = np.random.uniform(-5, 5, 10)  # 10 个随机 y 值
z = np.sin(np.sqrt(x**2 + y**2))  # 点处的函数值

# 创建多二次 RBF 插值器
rbf_interpolator = Rbf(x, y, z, function='multiquadric', epsilon=1)

# 创建用于插值的网格
x_grid, y_grid = np.linspace(-5, 5, 100), np.linspace(-5, 5, 100)
x_grid, y_grid = np.meshgrid(x_grid, y_grid)

# 将 RBF 插值器应用于网格
z_grid = rbf_interpolator(x_grid, y_grid)

# 绘制结果
plt.figure(figsize=(8, 6))
plt.imshow(z_grid, extent=(-5, 5, -5, 5), origin='lower', cmap='viridis')
plt.scatter(x, y, color='red', label='Data Points')
plt.colorbar(label='Interpolated Values')
plt.title('Multiquadric Radial Basis Function Interpolation')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

以下是 SciPy 中多二次 RBF 插值的输出 −

Multiquadraic RBF Interpolation Example

逆多二次径向基函数 RBF

逆多二次径向基函数 (RBF) 是一种用于插值和机器学习任务的径向基函数,特别是在多变量插值中应用广泛。逆多二次 RBF 的数学公式如下所示 −

Inverse Multiquadric RBF Interpolation Formula

其中 −

  • r 是点之间的欧几里得距离。
  • 是控制函数平滑度和扩展的形状参数。

以下是逆多二次 RBF 的主要特性 −

  • 局部影响: 逆多二次函数具有明显的局部效应,即更重视距离较近的点。
  • 平滑性: 它能产生平滑的插值表面。
  • 形状参数: 的值显著影响函数。小 的值会在插值点附近产生尖锐峰值,而较大的 值则导致更平滑、更宽广的形状。
  • 应用: 它常用于空间插值,特别是在散乱数据拟合中。

示例

以下示例展示了如何在 SciPy 中生成逆多二次 RBF 插值 −

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import Rbf

# 创建一些样本数据点
x = np.linspace(-5, 5, 10)  # x 坐标
y = np.linspace(-5, 5, 10)  # y 坐标
z = np.sin(np.sqrt(x**2 + y**2))  # 点处的样本函数值

# 为插值创建网格
xi = np.linspace(-5, 5, 100)  # x 的精细网格
yi = np.linspace(-5, 5, 100)  # y 的精细网格
xi, yi = np.meshgrid(xi, yi)   # 创建 2D 网格

# 应用逆多二次 RBF 进行插值
rbf = Rbf(x, y, z, function='inverse_multiquadric', epsilon=1)
zi = rbf(xi, yi)  # 插值值

# 绘制结果
plt.figure(figsize=(8, 6))
plt.imshow(zi, extent=(-5, 5, -5, 5), origin='lower', cmap='viridis')
plt.colorbar()
plt.scatter(x, y, color='red', label='Data Points')
plt.title('Inverse Multiquadric RBF Interpolation')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

以下是在 SciPy 中逆多二次 RBF 插值的输出结果 −

Inverse Multiquadraic RBF Interpolation Example

线性 RBF

线性径向基函数(RBF) 是最简单的 RBF 之一,其距离与函数值之间存在直接关系。线性 RBF 提供了一种基本方法,但缺乏更复杂函数(如高斯或三次 RBF)的灵活性,后者更适合平滑和插值任务。以下是线性 RBF 的数学表示 −

(r) = r

其中 r 是数据点与中心之间的欧几里得距离。

以下是线性 RBF 的关键特性 −

  • 行为: 该函数随距离线性增长,这意味着它不提供超出线性缩放的任何平滑效果。它不常用于需要平滑性或局部影响的实际插值任务。
  • 应用: 它可用于简单或低维问题,但在复杂、噪声或高维数据上效果较差。

示例

此示例展示了如何创建点网格,为其中一些点赋值,然后使用线性 RBF 在新点上插值 −

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import RBFInterpolator

# Sample data points (x, y) and their corresponding values (z)
x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([0, 1, 0, 1, 0, 1])  # Function values at the points

# Create a grid of points for interpolation
grid_x, grid_y = np.meshgrid(np.linspace(0, 5, 100), np.linspace(-0.5, 1.5, 100))

# Create the RBF interpolator using linear basis function
rbf = RBFInterpolator(x.reshape(-1, 1), y, kernel='linear')

# Perform interpolation on the grid points
# Here we only need to use the x-values, y is just for the grid
grid_points = grid_x.ravel()  # Flatten the grid for RBF interpolator
interpolated_values = rbf(grid_points.reshape(-1, 1))  # Reshape for RBFInterpolator

# Reshape the interpolated values to match the grid shape
interpolated_values = interpolated_values.reshape(grid_x.shape)

# Plotting
plt.figure(figsize=(10, 6))
plt.scatter(x, y, color='red', label='Data Points', zorder=5)
plt.contourf(grid_x, grid_y, interpolated_values, levels=50, cmap='viridis', alpha=0.7)
plt.colorbar(label='Interpolated Value')
plt.title('Linear Radial Basis Function (RBF) Interpolation')
plt.xlabel('x')
plt.ylabel('Interpolated Value')
plt.axhline(0, color='black', lw=0.5, ls='--')
plt.axvline(0, color='black', lw=0.5, ls='--')
plt.legend()
plt.show()

以下是 SciPy 中线性 RBF 插值的输出 −

Linear RBF Interpolation Example

Cubic RBF

三次径向基函数 (RBF) 插值 是一种使用三次径向基函数在多维空间中插值数据的方法。在这种方法中,插值函数被构建为以数据点为中心的三次 RBF 的线性组合。下面是三次 RBF 的数学表示 −

(r) = r3

其中 r 是点 x 与中心 c 之间的欧几里得距离,即 r = ||x - c||。

以下是三次 RBF 的主要特性 −

  • 平滑性: 三次 RBF 是一个平滑函数,能够提供平滑的插值结果,使其适合逼近连续数据。
  • 全局影响: 每个 RBF 都会影响域中的所有点,从而产生平滑的整体形状。
  • 形状灵活性: 三次形式允许灵活拟合各种类型的数据。

示例

我们可以使用 scipy 通过在创建 RBFInterpolator 时指定 kernel='cubic' 来执行三次径向基函数 (RBF) 插值。下面是一个展示如何实现三次 RBF 插值的示例 −

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import RBFInterpolator

# 样本数据点 (x, y) 及其对应的值 (z)
x = np.array([0, 1, 2, 3, 4, 5])
y = np.array([0, 1, 0, 1, 0, 1])  # 点处的函数值

# 为插值创建网格点
grid_x = np.linspace(0, 5, 100)
grid_y = np.linspace(-0.5, 1.5, 100)
grid_x, grid_y = np.meshgrid(grid_x, grid_y)

# 使用三次基函数创建 RBF 插值器
rbf = RBFInterpolator(x.reshape(-1, 1), y, kernel='cubic')

# 在网格点上执行插值
interpolated_values = rbf(grid_x.ravel().reshape(-1, 1))

# 将插值值重塑以匹配网格形状
interpolated_values = interpolated_values.reshape(grid_x.shape)

# 绘图
plt.figure(figsize=(10, 6))
plt.scatter(x, y, color='red', label='数据点', zorder=5)
plt.contourf(grid_x, grid_y, interpolated_values, levels=50, cmap='viridis', alpha=0.7)
plt.colorbar(label='插值值')
plt.title('三次径向基函数 (RBF) 插值')
plt.xlabel('x')
plt.ylabel('插值值')
plt.axhline(0, color='black', lw=0.5, ls='--')
plt.axvline(0, color='black', lw=0.5, ls='--')
plt.legend()
plt.show()

下面是 scipy 中三次 RBF 插值的输出 −

三次 RBF 插值示例

薄板样条 RBF

薄板样条 (TPS) 径向基函数 (RBF) 是一种特定的径向基函数,特别用于多维空间中的数据点插值。下面是薄板样条 RBF 的数学表示 −

(r) = r2log(r)

其中 r 是点 x 与中心 c 之间的欧几里得距离,即 r=||x−xi||。

以下是薄板样条 RBF 的主要特性 −

  • 平滑性: TPS 以生成非常平滑的插值曲面而闻名,使其非常适合结果曲面平滑性至关重要的应用。
  • 全局影响: 与某些其他径向基函数(如高斯函数)不同,TPS 的影响随距离衰减更慢,这意味着每个数据点对结果插值都有全局影响。
  • 维度: 它适用于高维数据插值,如 2D 或 3D,因此在图像变形、曲面拟合和地理数据应用中很受欢迎。

示例

以下是如何使用 SciPy 中的 RBFInterpolator 和薄板样条核实现径向基函数 (RBF) 插值的示例 −

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import RBFInterpolator

# 定义样本数据点 (xi, yi) 及其对应的值
x = np.array([0, 1, 2, 3, 4, 5])        # 数据点的 x 坐标
y = np.sin(x)                           # 对应的 y 值(正弦函数)

# 为插值创建网格点
grid_x = np.linspace(0, 5, 100)         # 网格的 x 值
grid_y = np.linspace(-1.5, 1.5, 100)    # 网格的 y 值
grid_x, grid_y = np.meshgrid(grid_x, grid_y)

# 使用薄板样条核创建 RBF 插值器
rbf = RBFInterpolator(x.reshape(-1, 1), y, kernel='thin_plate_spline')

# 准备网格点用于插值
grid_points = np.column_stack((grid_x.ravel(), grid_y.ravel()))

# 在网格点上执行插值
# 输入使用 x 和 y 坐标;插值中将忽略 y 值
interpolated_values = rbf(grid_points[:, 0].reshape(-1, 1))  # 重塑为 2D

# 将插值值重塑以匹配网格形状
interpolated_values = interpolated_values.reshape(grid_x.shape)

# 绘图
plt.figure(figsize=(10, 6))
plt.scatter(x, y, color='red', label='Data Points (sin(x))', zorder=5)
plt.contourf(grid_x, grid_y, interpolated_values, levels=50, cmap='viridis', alpha=0.7)
plt.colorbar(label='Interpolated Value')
plt.title('Thin Plate Spline Radial Basis Function (RBF) Interpolation')
plt.xlabel('x')
plt.ylabel('Interpolated Value')
plt.axhline(0, color='black', lw=0.5, ls='--')
plt.axvline(0, color='black', lw=0.5, ls='--')
plt.legend()
plt.show()

以下是 SciPy 中薄板样条 RBF 插值的输出 −

Thin Plate Spline RBF Interpolation Example

指数 RBF

指数径向基函数 (RBF) 是一种常用的径向基函数,广泛应用于插值、机器学习和神经网络中。它通过指数衰减来定义,能够比其他类型的 RBF 更有效地捕捉数据的局部变化。下面是指数 RBF 的数学表示 −

(r) = e-r

其中 r 是函数中心到输入空间中某一点的欧几里得距离,通常计算为 r=||x-xi||,而 β 是一个控制径向基函数宽度的参数。较大的 β 会导致更局部的响应,而较小的 β 会产生更平滑且更扩散的响应。

指数 RBF 的主要特性如下 −

  • 局部性: 指数衰减使得函数具有局部性,即在中心附近影响较强,随着距离增加迅速减弱。
  • 平滑性: 指数函数是无限可微的,这使其成为一个平滑函数,有利于插值和逼近任务。
  • 应用: 它常用于支持向量机等机器学习算法,以及径向基函数网络中的函数逼近。

示例

此示例生成一些样本数据点,然后使用指数 RBF 在这些点之间进行插值 −

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import RBFInterpolator

# 定义样本数据点 (xi, yi) 及其对应的值
x = np.array([0, 1, 2, 3, 4, 5])        # 数据点的 x 坐标
y = np.sin(x)                           # 对应的 y 值(正弦函数)

# 为插值创建网格点
grid_x = np.linspace(0, 5, 100)         # 网格的 x 值
grid_y = np.linspace(-1.5, 1.5, 100)    # 网格的 y 值
grid_x, grid_y = np.meshgrid(grid_x, grid_y)

# 使用指数核创建 RBF 插值器
# 注意:'exponential' 在 SciPy 中不可直接使用,我们将使用自定义实现
class ExponentialRBF:
    def __init__(self, centers, values, beta=1.0):
        self.centers = centers
        self.values = values
        self.beta = beta

    def __call__(self, x):
        distances = np.linalg.norm(x[:, np.newaxis] - self.centers, axis=2)  # 计算距离
        return np.dot(np.exp(-self.beta * distances), self.values)  # 应用指数 RBF

# 初始化自定义 RBF 插值器
exponential_rbf = ExponentialRBF(x.reshape(-1, 1), y, beta=1.0)

# 准备网格点用于插值
grid_points = np.column_stack((grid_x.ravel(), grid_y.ravel()))

# 使用仅 x 坐标在网格点上进行插值
interpolated_values = exponential_rbf(grid_points[:, 0].reshape(-1, 1))

# 将插值值重塑以匹配网格形状
interpolated_values = interpolated_values.reshape(grid_x.shape)

# 绘图
plt.figure(figsize=(10, 6))
plt.scatter(x, y, color='red', label='数据点 (sin(x))', zorder=5)
plt.contourf(grid_x, grid_y, interpolated_values, levels=50, cmap='viridis', alpha=0.7)
plt.colorbar(label='插值值')
plt.title('指数径向基函数 (RBF) 插值')
plt.xlabel('x')
plt.ylabel('插值值')
plt.axhline(0, color='black', lw=0.5, ls='--')
plt.axvline(0, color='black', lw=0.5, ls='--')
plt.legend()
plt.show()

以下是 SciPy 中指数 RBF 插值的输出 −

指数 RBF 插值示例