我很难弄清楚为什么我的 plt.legend 显示错误的多项式度数。它说 53 而不是 100。我的代码应该是这样的:
import scipy as sp
import numpy as np
import urllib2
import matplotlib.pyplot as plt
url = 'https://raw.github.com/luispedro/BuildingMachineLearningSystemsWithPython/master/ch01/data/web_traffic.tsv'
src = urllib2.urlopen(url)
data = np.genfromtxt(src)
x = data[:, 0]
y = data[:, 1]
x = x[~sp.isnan(y)]
y = y[~sp.isnan(y)]
def error(f, a, b):
return sp.sum((f(a) - b) ** 2)
fp100 = sp.polyfit(x, y, 100)
f100 = sp.poly1d(fp100)
plt.plot(x, f100(x), linewidth=4)
plt.legend("d={num}".format(num=f100.order), loc=2)
plt.show()
最佳答案
我可以用你的数据重现:
>>> np.__version__
1.8.0
>>> fp100 = sp.polyfit(x, y, 100)
polynomial.py:587: RankWarning: Polyfit may be poorly conditioned
warnings.warn(msg, RankWarning)
>>> f100 = sp.poly1d(fp100)
>>> f100.order
53
注意警告并咨询the docs :
polyfit issues a RankWarning when the least-squares fit is badly conditioned. This implies that the best fit is not well-defined due to numerical error. The results may be improved by lowering the polynomial degree or by replacing x by x - x.mean()
您的y
具有低方差:
>>> y.mean()
1961.7438692098092
>>> y.std()
860.64491521872196
因此,人们不会期望更高的多项式能够很好地拟合它。请注意,在按照文档的建议替换 x 之后,x 被 x-x.mean()
近似为低阶多项式,并不比高阶多项式差:
>>> xp=x-x.mean()
>>> f100 = sp.poly1d(sp.polyfit(xp, y,100))
>>> max(abs(f100(xp)-y)/y)
2.1173504721727299
>>> abs((f100(xp)-y)/y).mean()
0.18100985148093593
>>> f4 = sp.poly1d(sp.polyfit(xp, y, 4))
>>> max(abs(f4(xp)-y)/y)
2.1228866902203842
>>> abs((f4(xp)-y)/y).mean()
0.20139219654066282
>>> print f4
4 3 2
8.827e-08 x + 3.161e-05 x + 0.0003102 x + 0.06247 x + 1621
事实上,最重要的分量似乎有 2 次。所以这是正常的,最接近你的数据的次数不大于 100 的多项式实际上有 53 次。所有更高的单项式都是退化的。下图表示近似值,红线对应 4 次多项式,绿线对应 53 次多项式:
关于python - scipy.polyfit(x, y, 100) 将是 100 阶多项式,但 matplotlib.pyplot.legend 显示 53?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20838970/