我正在尝试编写一些非常基本的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
,但据我所知,这不是我应该使用的,因为它使用了一个预定义的函数,在我的情况下我没有。
注意,我对函数是否应该是线性/周期性/二次等没有限制,因为我的值会有所不同,但我的假设是大多数函数应该是线性的。
我也试过了numpy.interp
,但我只是在y
数组中得到了我输入的x
的最后一个值。
编辑:在仔细阅读了Cleb的答案,然后将其与kennytm的原始方法进行比较后,这是我的发现。这里最准确的技术应该是最接近的函数红线。绿线代表kennytm的方法(二次回归是我尝试过的最准确的方法),黑线代表Cleb的技术(UnivariateSpline)。看来,由于UnivariateSpline没有基础模型的先验知识,因此在适应函数值方面稍微好一些,这样可以更准确。
答案 0 :(得分:3)
另一种选择是使用样条曲线,例如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)
返回您期望的值:
array(49.99999999999993)
这种方法避免了模型的定义。
答案 1 :(得分:2)
我试过阅读
scipy.optimize.curve_fit
但据我所知,这不是我应该使用的,因为这使用了一个预定义的函数,在我的情况下我没有。
实际上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
的第二个返回值是输出的协变矩阵,它给出了拟合的好坏情况。
如果您只想使用最小二乘法拟合多项式,则只需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