从曲线拟合估计值

Estimate value from curve fit

我正在尝试编写一些非常基本的 Python 代码,根据输入和输出样本输出一个数字。例如,如果:

x  = [1, 2, 3, 4, 5]
y = [2, 5, 10, 17, 26]

z = np.interp(7, xp, yp)
print(z)  ##expected 50, actual was 26

我想通过某种方式找到将这些值映射在一起的最佳拟合函数,以便我可以将另一个 x 值传递给它并获得 y 值的粗略近似值。我尝试阅读有关 scipy.optimize.curve_fit 的内容,但据我所知,这不是我应该使用的内容,因为它使用了我没有的预定义函数。

请注意,我对函数是否应为 linear/periodic/quadratic 等没有任何限制,因为我的值会有所不同,但我的假设是大多数函数应该是线性的。

我也试过 numpy.interp 但我只是得到 y 数组中的最后一个值,无论我输入什么 x

编辑: 在弄乱了 Cleb 的答案然后将其与 kennytm 的原始方法进行比较之后,这是我的发现。 这里最准确的技术应该是离红线最近的函数。绿线代表 kennytm 的方法(二次回归是我尝试过的最准确的方法),黑线代表 Cleb 的技术 (UnivariateSpline)。看来,由于 UnivariateSpline 没有底层模型的先验知识,因此它在适应函数值方面表现得更好一些,这使得它更加准确。

I tried reading about scipy.optimize.curve_fit but as far as I can tell, this isn't what I should be using because this uses a predefined function which in my case I don't have.

实际上 scipy.optimize.curve_fit 的那个函数就是你想要拟合的模型。假设你想要线性回归,那么你使用:

def linear(x, a, b):
    return a*x + b

fit_params, _ = scipy.optimize.curve_fit(linear, xp, yp)
print(linear(7, *fit_params))
# 36.0

类似于二次回归等:

def quadratic(x, a, b, c):
    return a*x*x + b*x + c

fit_params, _ = scipy.optimize.curve_fit(quadratic, xp, yp)
print(quadratic(7, *fit_params))
# 50.000000000004555

curve_fit的第二个return值是输出的协方差矩阵,大致可以看出拟合的好坏)


如果您只想用最小二乘法拟合多项式,您可以 use numpy.polyfit.

linear_coeff = numpy.polyfit(xp, yp, deg=1)
print(numpy.polyval(linear_coeff, 7))
# 35.999999999999986

quadratic_coeff = numpy.polyfit(xp, yp, deg=2)
print(numpy.polyval(quadratic_coeff, 7))
# 50.000000000000085

另一种选择是使用样条曲线,例如scipy.interpolate.UnivariateSpline,如果你不关心底层模型(比如是线性的还是立方的等等)和过拟合。

那么你可以这样做:

from scipy.interpolate import UnivariateSpline

x  = [1, 2, 3, 4, 5]
y = [2, 5, 10, 17, 26]
spl = UnivariateSpline(x, y)

要获得 x=7 的估算值,您现在只需执行以下操作:

spl(7)

哪个 returns 您期望的值:

array(49.99999999999993)

这种方法避免了模型的定义。