如何改善表面对 3D 数据的拟合?

How to improve surface fit to 3D data?

我一直在使用 scipy 将 3d 数据拟合到表面,该表面被定义为多项式函数。但结果看起来与数据不太接近。我怎样才能提高拟合度?

import numpy as np
from scipy.optimize import curve_fit

# import my data
data = my_data_matrix

# define polynomial function
def func(X, A, B, C, D, E, F):
    # unpacking the multi-dim. array column-wise, that's why the transpose
    x, y, z = X.T

    return (A * x ** 2) + (B * y ** 2) + (C * x * y) + (D * x) + (E * y) + F

# fit the polynomial function to the 3d data
popt, _ = curve_fit(func, data, data[:,2])


# print coefficients of the polynomial function, i.e., A, B, C, D, E and F
from string import ascii_uppercase
for i, j in zip(popt, ascii_uppercase):
    print(f"{j} = {i:.3f}")

在这种情况下我得到了:

A = 0.903  
B = 0.022  
C = 0.325  
D = -362.140  
E = -52.875  
F = 31057.352

拟合曲面与原始数据对比(散点):

您确定您的数据来自二次曲面并且没有任何噪声吗?这个 curve_fit 函数基本上是在做 line of best fit 的模拟。最佳拟合线是当您将一些数据像线一样展开但不完全是一条线并且您想要通过数据找到最接近数据的线时。这种“接近度”的定义方式是针对每个数据点,找到该点实际位置与直线预测位置的差异,将其平方,然后将所有数据点相加。最佳拟合线是将其最小化的线。

现在,如果数据嘈杂(几乎总是如此),那么最佳拟合线将不会准确地穿过每个点,而是应该接近。如果您有充分的理由认为您的数据具有线性关系,那么这很好,并且不准确之处告诉您数据有多么嘈杂。

将此扩展到您的示例,您正在尝试找到 x 和 y 二次方的最佳曲面以适合您的数据。如果您有理由相信生成此数据的过程是二次方的,那么您在图中看到的差异就是数据的噪声。

但是,您的数据可能真的来自立方或更高阶的东西。您可以尝试这些类型的功能,但不要太疯狂,通常来自物理过程的数据不是太高阶。过度使用你的函数基本上被称为过度拟合。高阶函数将减少数据误差,您甚至可以达到可以“完美”预测所有数据的程度(通过使用度数 = 数据点数的多项式)。但是,如果您过度拟合(= 阶数太高),那么当您获得新数据时,您的过度拟合模型的预测结果会比更简单的模型更差。