我需要找到完全适合30个数据点的29阶多项式函数。我们可以肯定,这样的功能存在。但是,numpy.polyfit的错误只在三点之后急剧增加。
import numpy as np
y = [126, 34, 78, 120, 83, 62, 104, 6, 70, 142, 147, 63, 35, 126, 9, 84, 7, 122, 93, 29, 95, 141, 42, 102, 38, 96, 130, 83, 138, 148]
print(len(y))
x = np.arange(len(y))
f = np.polyfit(x,y,30)
def eval_polynom(f, x):
res = 0
for i in range(len(f)):
res += f[i] * x**(len(f)-i-1)
return res
for i in range(len(y)):
print(y[i], " -- ", eval_polynom(f, x[i]))
我的数据点是(x,y),x = [0,1,2,3,4,...,29]
输出
126 -- 125.941598976
34 -- 34.7366402172
78 -- 73.703669116
120 -- 134.514176467
83 -- 51.6471546864
62 -- 105.143046704
104 -- 70.1470309453
6 -- 13.808372367
70 -- 347.425617622
142 -- -1281.11122538
...
有没有办法获得精确的多项式函数,使误差为0?
答案 0 :(得分:1)
y - 绿色,多项式 - 红色,错误 - 蓝色,它的140度多项式
我需要找到完全适合30个数据点的29阶多项式函数。我们可以肯定,这样的功能存在
为什么你确定这个?我尝试了一些曲折和可视化,并认为你的数据点不适合这样的polinome。
我尝试过切比雪夫的多项式,它做得更好,但即使用140度多项式也无法拟合这些值。
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
from numpy.polynomial.chebyshev import chebfit,chebval
%matplotlib inline
y = [126, 34, 78, 120, 83, 62, 104, 6, 70, 142, 147, 63, 35, 126, 9, 84, 7, 122, 93, 29, 95, 141, 42, 102, 38, 96, 130, 83, 138, 148]
print(len(y))
x = np.arange(len(y))
c = chebfit(x, y, 30)
p = []
for i in np.arange(len(y)):
p.append(chebval(i, c))
df = pd.DataFrame(data={'x': x, 'y': y, 'p': p})
df['diff'] = df['y'] - df['p']
sns.pointplot(x = 'x', y = 'y', data=df, color='green')
sns.pointplot(x = 'x', y = 'p', data=df, color='red')
sns.pointplot(x = 'x', y = 'diff', data=df, color='blue')
答案 1 :(得分:1)
eval_polynom
函数中几乎肯定会出现整数溢出问题(由于指数较大),因为x
中的值都是整数。尝试替换
res += f[i] * x**(len(f)-i-1)
与
res += f[i] * float(x)**(len(f)-i-1)
您可能最终会得到仍然不完全匹配的值,但请记住,浮点运算本质上是不准确的。如果数字变大则更是如此,就像这里的情况一样。
答案 2 :(得分:1)
虽然不准确,但如果使用NumPys polyval
import numpy as np
y = [126, 34, 78, 120, 83, 62, 104, 6, 70, 142, 147, 63, 35, 126, 9, 84, 7, 122, 93, 29, 95, 141, 42, 102, 38, 96, 130, 83, 138, 148]
x = np.arange(len(y))
f = np.polyfit(x ,y, 30)
for i in range(len(y)):
print(y[i], " -- ", np.polyval(f, x[i]))
给出了
(126, ' -- ', 125.94427340268774)
(34, ' -- ', 34.674505165214924)
(78, ' -- ', 73.961360153890183)
(120, ' -- ', 133.96863767482208)
(83, ' -- ', 52.113307162099574)
(62, ' -- ', 105.65069882437891)
(104, ' -- ', 68.588480573695762)
(6, ' -- ', 14.814788499822299)
(70, ' -- ', 76.373263353880958)
(142, ' -- ', 149.39793233756134)
...
请注意,您应该使用29度多项式来拟合30个点。