近日,Facebook 宣布开源了一个可以通过 Python 和 R 语言使用的预测工具 Prophet。以下是 Facebook 研究博客对该工具的介绍。
预测(forecasting)是一个数据科学问题,也是很多组织机构内许多活动的核心。比如说,像 Facebook 这样的大型组织必须进行能力规划(capacity planning)以有效地分配稀缺资源和目标配置,以便能基于基准对业绩表现进行测量。不管是对于机器还是对于分析师而言,得出高质量的预测都并非易事。我们已经在创建各种各样的业务预测(business forecasts)的实践中观察到了两大主要主题:
完全自动化的预测技术可能会很脆弱,而且往往非常不灵活,不能整合有用的假设或启发。
能够产生高质量预测的分析师相当少,因为预测是一种需要大量经验的数据科学领域的专业技能。
这两个主题会导致一个结果:对高质量预测的需求往往超出分析师能够得出的预测速度。这个情况是我们创造 Prophet 的动力:我们想要让专家和非专家都能轻松地做出高质量的预测来满足自身的需求。
对于「规模(scale)」的通常考虑涉及到计算和存储,但这些都不是预测的核心问题。我们发现预测大量时间序列(time series)的计算和基础设施问题是相对简单的——通常这些拟合过程可以很容易地并行化,而预测本身也能容易地被存储在 MySQL 这样的关系数据库或 Hive 这样的数据仓库中。据我们观察,「规模」在实践中面临的问题涉及的是由多种预测问题所引入的复杂性(complexity)和在得出预测后如何在大量预测结果中构建信任(trust)。Prophet 已经成为了 Facebook 创建大量可信预测的能力的关键组成部分,这些预测可被用于决策制定甚至用在产品功能中。
Prophet 有什么用?
并非所有的预测问题都可以通过同一种程序(procedure)解决。Prophet 是为我们在 Facebook 所遇到的业务预测任务而优化的,这些任务通常具有以下特点:
对于历史在至少几个月(最好是一年)的每小时、每天或每周的观察
强大的多次的「人类规模级」的季节性:每周的一些天和每年的一些时候
事先知道的以不定期的间隔发生的重要节假日(如,超级碗)
合理数量的缺失的观察或大量异常
历史趋势改变,比如因为产品发布或记录变化
非线性增长曲线的趋势,其中有的趋势达到了自然极限或饱和
我们发现默认设置的 Prophet 能产生往往和经验丰富的预测师得到的一样准确的预测,而所花费的工作却更少。使用 Prophet,如果该预测不令人满意,你也不用局限于一个完全自动化的程序——即使一个没有接受过任何时间序列方法训练的分析师也能够使用各种各样的可轻松解读的参数来改进或调整预测。我们已经发现:通过在特定案例上将自动化预测和分析师参与的预测(analyst-in-the-loop forecasts)结合到一起,它有可能可适用于非常大范围的业务用例。下图给出了我们发现的可以大规模使用的预测过程:
对于该预测过程的建模阶段,目前仅有有限数量的工具可用。Rob Hyndman 的出色的预测 R 语言的预测软件包(http://robjhyndman.com/software/forecast/)可能是目前最受欢迎的选择,而且谷歌和 Twitter 也都分别发布了带有更加特定的时间序列功能的软件包——CausalImpact(https://google.github.io/CausalImpact/)和 AnomalyDetection(https://github.com/twitter/AnomalyDetection)。就我们所知,在使用 Python 的预测上,还少有开源的软件包可用。
我们常常在许多设置中使用 Prophet 作为预测(forecast)软件包的替代,因为其有如下两个主要优点:
Prophet 让我们可以更加简单直接地创建合理且准确的预测。该预测包包含了许多不同的预测技术(比如 ARIMA、指数平滑等),其中每一个都有它们自己的长处、短处和调整参数。我们发现错误的模型或参数选择往往会导致糟糕的结果,而在这样的选择阵列下,即使是经验丰富的分析师也不太可能能够有效地选择出正确的模型和参数。
Prophet 预测可以通过对非专家而言很直观的方式进行自定义。有关于季节性的平滑参数让你能调整与历史周期之间的接近程度,以及关于趋势的平滑参数让你能调整跟随历史趋势变化的激进程度。对于增长曲线而言,你可以手动设定「capacity」或增长曲线的上限,这能让你注入关于你预测的增长或下降情况的先验信息。最后,你还可以为模型指定没有规律的节假日,比如超级碗、感恩节和黑色星期五的日期。
Prophet 如何工作
本质上讲,Prophet 程序是一个可加性回归模型(additive regression model),它包含 4 个主要组件:
分段线性或者 logistic 增长曲线趋势。通过从数据中选择变化点,Prophet 自动探测趋势变化。
使用傅立叶级数建模每年的季节分量。
使用虚变量(dummy variables)的每周的季节分量。
用户提供的重要节假日列表。
例如,下面是一个特征预测:使用 wikipediatrend 包(https://cran.r-project.org/web/packages/wikipediatrend/index.html)下载的 Peyton Manning 的维基百科页面的查看数量的日志。由于 Peyton Manning 是一名美式橄榄球运动员,你可以看到他每年季节性的重要程度变化,同时每周的周期性也明显存在。最后你看到特定事件(比如他参加的季后赛)也可能被建模了。
Prophet 将提供一个组分图,用图形描述它所拟合的模型:
这个组分图更加清晰地展示了与浏览 Peyton Manning 的网页(橄榄球常规赛与季后赛)相关的每年的季节性,以及每周的季节性:(星期日和星期一)比赛当天和比赛之后有更多的访问。你也可以注意到趋势组件自他最近退休以来的下行调整。
Prophet 的重要思想是:通过更好地灵活拟合趋势组分,我们可以更精确地建模季节性,并且有更准确的预测结果。对于这个任务我们更喜欢使用非常灵活的回归模型(有一点像曲线拟合)而不是传统的时序模型,因为前者可以使我们建模更灵活,更容易拟合模型,更优雅地处理丢失数据或离群值。
通过模拟时间序的未来趋势变化,Prophet 默认地会为趋势组分提供不确定的间隔。如果你希望对未来季节性或假期影响的不确定性进行建模,你可以运行数百个 HMC 迭代(花费几分钟),你的预测就将会包括季节性不确定评估。
我们使用 Stan(http://mc-stan.org/)调整 Prophet 模型,并在 Stan 的概率编程语言中实现了 Prophet 流程的核心部分。Stan 对参数的 MAP 优化有着极快的速度( 1 秒),让我们可以选择使用 Hamiltonian Monte Carlo 算法评估不确定的参数,也使得我们能够在多种接口语言上重复使用该拟合程序。目前,我们提供了 Python 和 R 语言的 Prophet 实现。它们有着几乎相同的特征,而且通过提供这两种实现,我们希望该预测方法能够在数据科学社区有更广泛的用途。
本文来自开源中国社区 [http://www.oschina.net]