3

我有一组点描述了一个简单的表面空腔/凸起的横截面。多项式近似就足够了,但numpy.polyfit需要一定程度。我想了几次不同程度的迭代来选择一个平均残差最小的迭代。是否有任何现有功能或更好的方法来获得良好的曲线?计算时间非常重要:数据集很小(大约 20 个点),但有数千个。

最初的任务是在一个非常离散的表面上找到这种空腔测地线——是否存在任何更简单的方法?

4

1 回答 1

2

除非我弄错了,否则你总是会得到允许的最大程度的最小残差。如果您允许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), ':')

过拟合

于 2013-11-13T02:01:09.113 回答