将 numpy 多项式拟合到噪声数据
fit numpy polynomials to noisy data
我想用 numpy.polynomial
多项式准确表示我的噪声数据。我怎样才能做到这一点?。
在这个例子中,我选择了勒让德多项式。当我使用多项式 legfit
函数时,它 returns 的系数不是很大就是很小。所以,我认为我需要某种规范化。
为什么当我增加多项式的次数时,我的拟合没有变得更准确? (可以看出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()
Legendre 多项式用于区间 [-1,1]。尝试将 x
替换为 2*x/x[-1] - 1
,您会发现一切正常:
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)
在拟合中使用适当区间的简单方法是使用 Legendre class
from numpy.polynomial import Legendre as L
p = L.fit(x, y, order)
这会将数据缩放并移动到区间 [-1, 1] 并跟踪缩放因子。
我想用 numpy.polynomial
多项式准确表示我的噪声数据。我怎样才能做到这一点?。
在这个例子中,我选择了勒让德多项式。当我使用多项式 legfit
函数时,它 returns 的系数不是很大就是很小。所以,我认为我需要某种规范化。
为什么当我增加多项式的次数时,我的拟合没有变得更准确? (可以看出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()
Legendre 多项式用于区间 [-1,1]。尝试将 x
替换为 2*x/x[-1] - 1
,您会发现一切正常:
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)
在拟合中使用适当区间的简单方法是使用 Legendre class
from numpy.polynomial import Legendre as L
p = L.fit(x, y, order)
这会将数据缩放并移动到区间 [-1, 1] 并跟踪缩放因子。