Python交叉截面曲线拟合

3

我有一组描述简单表面空腔/隆起的横截面点集。多项式逼近就足够了,但是numpy.polyfit需要指定一个阶数。我考虑多次迭代,使用不同阶数选择平均残差最小的那个。是否存在现成的函数或更好的方法来得到一个好的曲线?计算时间非常重要:数据集很小(约20个点),但数量有几千个。

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

1个回答

2
如果我没弄错的话,你总是可以得到最小残差和允许的最大度数。如果你允许优化器选择度数,它将选择无限大的,但实际上它会在时停止,其中是拟合的自由度数(基本上是数据点的数量),此时您将获得零残差。
如果你不真正关心拟合的真实函数形式,只是想要曲线,那么你可以研究一下插值,使用更灵活的scipy.interpolate模块,这对于你可能正在做的类型的事情更加灵活。
如果速度很重要,而格式并不那么重要,只需尝试以一些合理的度数使用np.polynomial.polynomial.polyfitscipy.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), '.-')

fits

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), ':')

overfit


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接