将numpy多项式适配到嘈杂数据上

4
我希望用numpy.polynomial多项式精确表示我的嘈杂数据。如何做到这一点?
在这个例子中,我选择了勒让德多项式。当我使用多项式函数legfit时,它返回的系数要么非常大,要么非常小。因此,我认为我需要一些正则化。
为什么随着多项式次数的增加,我的拟合结果并没有更加准确?(可以看到20、200和300次多项式基本相同。)多项式包中是否有任何规则化选项?
我尝试实现自己的回归函数,但感觉像是在重复造轮子。制作自己的拟合函数是否是最好的前进道路?
from scipy.optimize import least_squares as mini
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 5, 1000)
tofit = np.sin(3 * x) + .6 * np.sin(7*x) - .5 * np.cos(3 * np.cos(10 * x))

# This is here to illustrate what I expected the legfit function to do
# I expected it to do least squares regression with some sort of regularization.
def myfitfun(x, y, deg):
    def fitness(a):
       return ((np.polynomial.legendre.legval(x, a) - y)**2).sum() + np.sum(a ** 2)
    return mini(fitness, np.zeros(deg)).x

degrees = [2, 4, 8, 16, 40, 200]
plt.plot(x, tofit, c='k', lw=4, label='Data')
for deg in degrees:
    #coeffs = myfitfun(x, tofit, deg)
    coeffs = np.polynomial.legendre.legfit(x, tofit, deg)
    plt.plot(x, np.polynomial.legendre.legval(x, coeffs), label="Degree=%i"%deg)
plt.legend()

enter image description here


3
你尝试过使用普通的polyfit吗?https://docs.scipy.org/doc/numpy/reference/generated/numpy.polyfit.html - Joe
它不会变得更准确,因为您可能需要非常非常小的系数来处理高阶数。但是它们不能比大约1e-15更小... https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems - Joe
@Joe polyfit可以用于Legendre多项式吗?如果不能,它就不适合我的问题。我编辑了我的问题以删除“任何多项式都可以”。至于机器精度的问题,我认为你没有正确诊断问题。 - kilojoules
polyfit 就是为普通多项式而设计的 legfit。我已经思考过这个问题。我认为这需要超过 2 秒钟的谷歌搜索才能回答。 - kilojoules
你有尝试使用polyfit来进行拟合吗?它是否比legfit更好用呢?您必须使用Legendre多项式吗?还是只需拟合数据即可? - Joe
重申一遍,这个问题不应该只是一个两秒钟的谷歌搜索。你为什么认为polyfit会更好呢? - kilojoules
2个回答

5

Legendre多项式适用于区间[-1,1]。尝试在拟合中使用2*x/x[-1] - 1替换x,您会发现一切都很好:

nx = 2*x/x[-1] - 1
for deg in degrees:
    #coeffs = myfitfun(x, tofit, deg)
    coeffs = np.polynomial.legendre.legfit(nx, tofit, deg)
    plt.plot(x, np.polynomial.legendre.legval(nx, coeffs), label="Degree=%i"%deg)

enter image description here


3
使用合适的拟合间隔的简便方法是使用Legendre类。
from numpy.polynomial import Legendre as L
p = L.fit(x, y, order)

这将把数据缩放和移动到区间[-1, 1],并跟踪缩放因子。

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