在Python中有没有简单的方法可以外推数据点到未来?

11 投票
4 回答
28334 浏览
提问于 2025-04-15 15:14

我有一个简单的numpy数组,每个日期都有一个数据点。大概是这样的:

>>> import numpy as np
>>> from datetime import date
>>> from datetime import date
>>> x = np.array( [(date(2008,3,5), 4800 ), (date(2008,3,15), 4000 ), (date(2008,3,
20), 3500 ), (date(2008,4,5), 3000 ) ] )

有没有简单的方法可以把数据点推测到未来,比如日期(2008,5,1)、日期(2008, 5, 20)等等?我知道可以用数学算法来实现这个。但是我想找一些简单易行的方法。其实我挺喜欢numpy.linalg.solve这个功能的,但它似乎不适合用来推测数据。也许我完全错了。

更具体一点,我正在制作一个燃尽图(这是敏捷开发中的一个术语):'x轴是日期,y轴是待完成的工作量',所以我已经有了完成的冲刺数据,我想可视化一下如果当前情况不变,未来的冲刺会怎样发展。最后,我想预测一下发布日期。所以“待完成的工作量”在燃尽图上总是会下降。我还想得到推测的发布日期:也就是工作量变为零的那一天。

这些都是为了向开发团队展示事情的进展。这里的准确性不是特别重要 :) 开发团队的积极性才是最关键的。这意味着我对非常粗略的推测方法完全没有问题。

4 个回答

3

在这种情况下,使用数学模型是个不错的选择。比如说,如果你只有三个数据点,你根本无法判断趋势会怎么发展(可能是两种不同的抛物线)。

建议你去学一些统计学课程,尝试实现相关的算法。可以看看Wikibooks上的内容。

4

做外推(也就是根据已有数据推测未来数据)有个简单的方法,就是用插值多项式或样条曲线。你可以在scipy.interpolate这个库里找到很多相关的工具,而且使用起来也很简单。你只需要提供一些(x, y)的点,系统就会给你一个可以调用的函数。

不过,正如这个讨论中提到的,如果你没有数据模型,外推的结果可能并不总是有意义,尤其是当你离已有数据点很远的时候。不过,我鼓励你试试scipy.interpolate里的多项式或样条插值,看看你得到的结果是否符合你的需求。

18

推断(外推)很容易就会产生错误的结果;你可以试试这个。其实有很多种不同的推断方式;有些会产生明显的错误结果,有些则不那么明显,还有很多是定义不清的。

alt text

""" extrapolate y,m,d data with scipy UnivariateSpline """
import numpy as np
from scipy.interpolate import UnivariateSpline
    # pydoc scipy.interpolate.UnivariateSpline -- fitpack, unclear
from datetime import date
from pylab import *  # ipython -pylab

__version__ = "denis 23oct"


def daynumber( y,m,d ):
    """ 2005,1,1 -> 0  2006,1,1 -> 365 ... """
    return date( y,m,d ).toordinal() - date( 2005,1,1 ).toordinal()

days, values = np.array([
    (daynumber(2005,1,1), 1.2 ),
    (daynumber(2005,4,1), 1.8 ),
    (daynumber(2005,9,1), 5.3 ),
    (daynumber(2005,10,1), 5.3 )
    ]).T
dayswanted = np.array([ daynumber( year, month, 1 )
        for year in range( 2005, 2006+1 )
        for month in range( 1, 12+1 )])

np.set_printoptions( 1 )  # .1f
print "days:", days
print "values:", values
print "dayswanted:", dayswanted

title( "extrapolation with scipy.interpolate.UnivariateSpline" )
plot( days, values, "o" )
for k in (1,2,3):  # line parabola cubicspline
    extrapolator = UnivariateSpline( days, values, k=k )
    y = extrapolator( dayswanted )
    label = "k=%d" % k
    print label, y
    plot( dayswanted, y, label=label  )  # pylab

legend( loc="lower left" )
grid(True)
savefig( "extrapolate-UnivariateSpline.png", dpi=50 )
show()

补充一下:有一个Scipy的讨论提到,“scipy.interpolate中的FITPACK类的行为比文档所描述的要复杂得多”——我觉得其他软件的文档也是这样。

撰写回答