我有一组点描述了一个简单的表面空腔/凸起的横截面。多项式近似就足够了,但numpy.polyfit需要一定程度。我想了几次不同程度的迭代来选择一个平均残差最小的迭代。是否有任何现有功能或更好的方法来获得良好的曲线?计算时间非常重要:数据集很小(大约 20 个点),但有数千个。
最初的任务是在一个非常离散的表面上找到这种空腔测地线——是否存在任何更简单的方法?
我有一组点描述了一个简单的表面空腔/凸起的横截面。多项式近似就足够了,但numpy.polyfit需要一定程度。我想了几次不同程度的迭代来选择一个平均残差最小的迭代。是否有任何现有功能或更好的方法来获得良好的曲线?计算时间非常重要:数据集很小(大约 20 个点),但有数千个。
最初的任务是在一个非常离散的表面上找到这种空腔测地线——是否存在任何更简单的方法?
除非我弄错了,否则你总是会得到允许的最大程度的最小残差。如果您允许d
优化器选择度数,它将选择无限大d
,但实际上它会在您的拟合自由度数(基本上是数据点数)在d = dof
哪里时停止,此时您'dof
将有零残差。
如果您对拟合的真正功能形式并不真正感兴趣并且只想要曲线,您可以使用scipy.interpolate
模块查看插值,这对于您可能正在做的事情的类型更灵活。
如果速度很重要,并且格式不是那么重要,只需尝试np.polynomial.polynomial.polyfit
一些合理的程度, and scipy.interpolate.UnivariateSpline
,看看哪个更快。
在我看来样条曲线要快得多,对于我的示例,它们给出了相同的结果(请记住,样条曲线基本上只是串在一起的多项式)
import numpy as np
from numpy.polynomial import polynomial as poly
from scipy import interpolate as interp
import matplotlib.pyplot as plt
n = 20
x = np.linspace(0, 2*np.pi, n)
a = np.sin(x) + np.random.uniform(-.2, .2, n)
s = interp.UnivariateSpline(x, a)
p = poly.polyfit(x, a, 3)
p = poly.Polynomial(p)
plt.figure()
plt.plot(x, np.sin(x), '-', x, a, 'o', x, s(x), '--', x, p(x), '.-')
In [32]: timeit s = interp.UnivariateSpline(x, a)
10000 loops, best of 3: 22.1 µs per loop
In [33]: timeit p = poly.Polynomial(poly.polyfit(x, a, 3))
1000 loops, best of 3: 392 µs per loop
In [34]: timeit p = poly.polyfit(x, a, 3)
1000 loops, best of 3: 311 µs per loop
包括评价:
In [35]: timeit interp.UnivariateSpline(x, a)(x)
10000 loops, best of 3: 44.9 µs per loop
In [37]: timeit poly.Polynomial(poly.polyfit(x, a, 3))(x)
1000 loops, best of 3: 470 µs per loop
为了好玩,并说明过拟合的概念,这是一个多项式d >= dof
:
p = poly.Polynomial(poly.polyfit(x, a, x.size-1))
plot(x, np.sin(x), '-', x, a, 'o', x, p(x), ':')