WEBKT

Python Prophet 时间序列预测实战:从原理到调优

7 0 0 0

什么是 Prophet?

为什么选择 Prophet?

Prophet 的核心原理

Prophet 实战:预测网站访问量

1. 数据准备

2. 模型训练

3. 预测

4. 结果可视化

5. 模型调优

6. 处理异常值

总结

最近几年,时间序列预测火了起来。你是不是也经常遇到这样的场景:需要预测未来一段时间的销售额、用户增长数,或者网站流量?别担心,今天咱们就来聊聊 Facebook 开源的时间序列预测神器——Prophet。

什么是 Prophet?

Prophet 是 Facebook(现在叫 Meta 了)核心数据科学团队开发的开源时间序列预测库,专为具有明显季节性和趋势性的业务数据而设计。它基于加法模型(Additive Model),将时间序列分解为趋势、季节性和节假日效应等多个组成部分,能够很好地处理缺失值和异常值,并且对参数调整不敏感,上手非常容易。

简单来说,Prophet 就像一个经验丰富的“算命先生”,它能根据你过去的数据,“推算”出未来的走势。当然,它不是真的算命,而是基于统计学和机器学习的原理。

为什么选择 Prophet?

与其他时间序列预测方法(如 ARIMA、LSTM 等)相比,Prophet 有以下几个显著优势:

  1. 易用性:Prophet 的 API 设计非常简洁,几行代码就能完成模型的训练和预测。即使你对时间序列预测不熟悉,也能快速上手。
  2. 自动处理:Prophet 能够自动检测季节性、趋势变化点,并处理缺失值和异常值,省去了大量数据预处理的工作。
  3. 可解释性:Prophet 将时间序列分解为多个组成部分,方便你理解每个部分对预测结果的影响。
  4. 灵活性:Prophet 提供了丰富的参数设置,可以根据实际情况调整模型的行为。

Prophet 的核心原理

Prophet 的核心是一个加法模型,它将时间序列数据 y(t) 分解为以下几个部分:

  • 趋势项 g(t):表示时间序列的长期变化趋势。Prophet 提供了两种趋势模型:

    • 饱和增长模型(Saturating Growth Model):适用于具有自然上限的时间序列,例如人口增长、用户增长等。其公式为:
    g(t) = C / (1 + exp(-k(t - m)))
    

    其中,C 是承载量(Carrying Capacity,即上限),k 是增长率,m 是偏移量。

    • 分段线性模型(Piecewise Linear Model):适用于没有自然上限的时间序列,例如销售额、网站流量等。其公式为:
    g(t) = (k + a(t) * δ) * t + (m + a(t) * γ)
    
    其中,k 是增长率,δ 是增长率的变化量,m 是偏移量,γ 用于使函数连续。
    
  • 季节项 s(t):表示时间序列的周期性变化,例如每周、每年等。Prophet 使用傅里叶级数(Fourier Series)来模拟季节性:

    s(t) = Σ[n=1 to N] (an * cos(2πnt/P) + bn * sin(2πnt/P))
    

    其中,P 是周期(例如,对于年度季节性,P=365.25),N 是傅里叶级数的阶数。

  • 节假日项 h(t):表示节假日等不规则事件对时间序列的影响。Prophet 允许你指定一个节假日列表,并为每个节假日设置一个影响因子。

  • 误差项 εt:表示模型无法解释的随机波动。

最终,Prophet 模型可以表示为:

 y(t) = g(t) + s(t) + h(t) + εt

Prophet 实战:预测网站访问量

说了这么多理论,咱们来点实际的。假设我们有一个网站,需要预测未来 30 天的每日访问量。我们已经收集了过去两年的历史数据,数据格式如下:

ds,y
2021-01-01,100
2021-01-02,105
...
2022-12-31,200

其中,ds 列是日期,y 列是当日访问量。

1. 数据准备

首先,我们需要将数据读取到 Pandas DataFrame 中:

import pandas as pd
df = pd.read_csv('website_traffic.csv')
df['ds'] = pd.to_datetime(df['ds'])

2. 模型训练

接下来,我们使用 Prophet 来训练模型:

from prophet import Prophet
# 创建 Prophet 模型实例
m = Prophet()
# 拟合模型
m.fit(df)

就这么简单!Prophet 会自动检测季节性和趋势,并处理缺失值。

3. 预测

现在,我们可以使用训练好的模型来预测未来 30 天的访问量:

# 创建未来 30 天的日期 DataFrame
future = m.make_future_dataframe(periods=30)
# 进行预测
forecast = m.predict(future)
# 查看预测结果
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())

forecast DataFrame 包含了预测结果,其中:

  • ds:日期
  • yhat:预测值
  • yhat_lower:预测值的下限
  • yhat_upper:预测值的上限

4. 结果可视化

Prophet 提供了方便的可视化工具,可以帮助我们更好地理解预测结果:

from prophet.plot import plot_plotly, plot_components_plotly
plot_plotly(m, forecast)

这将绘制出预测值和实际值的对比图,以及趋势、季节性等分量图。

plot_components_plotly(m, forecast)

5. 模型调优

Prophet 提供了许多参数来调整模型的行为,以下是一些常用的参数:

  • growth:趋势模型类型,可以是 'linear'(线性)或 'logistic'(逻辑斯蒂)。如果设置为 'logistic',需要指定 cap 列(承载量)。
  • changepoints:趋势变化点列表。如果不指定,Prophet 会自动检测。
  • n_changepoints:自动检测的趋势变化点数量,默认为 25。
  • changepoint_prior_scale:趋势变化点灵活度,值越大,模型对趋势变化的响应越灵敏。默认为 0.05。
  • seasonality_mode:季节性模式,可以是 'additive'(加法)或 'multiplicative'(乘法)。默认为 'additive'
  • seasonality_prior_scale:季节性强度,值越大,季节性影响越大。默认为 10。
  • holidays:节假日 DataFrame。需要包含 ds(日期)和 holiday(节假日名称)两列。
  • holidays_prior_scale:节假日影响强度,值越大,节假日影响越大。默认为 10。

例如,如果我们想增加趋势变化点的灵活度,并指定春节为节假日,可以这样设置:

# 创建节假日 DataFrame
holidays = pd.DataFrame({
'holiday': 'Spring Festival',
'ds': pd.to_datetime(['2021-02-12', '2022-02-01']),
'lower_window': -1,
'upper_window': 7,
})
# 创建 Prophet 模型实例,并设置参数
m = Prophet(
changepoint_prior_scale=0.1,
holidays=holidays,
holidays_prior_scale=20
)
m.fit(df)

6. 处理异常值

Prophet 对异常值比较敏感,可能会影响预测结果。我们可以通过以下两种方法处理异常值:

  • 删除异常值:直接从数据中删除异常值。
  • 替换异常值:将异常值替换为合理的值,例如均值、中位数等。

具体采用哪种方法,需要根据实际情况决定。

# 假设 2021-05-01 的访问量是异常值
# 方法一:删除异常值
df = df[df['ds'] != '2021-05-01']
# 方法二:替换异常值
df.loc[df['ds'] == '2021-05-01', 'y'] = df['y'].mean()

总结

Prophet 是一个强大且易用的时间序列预测工具,特别适合具有明显季节性和趋势性的业务数据。通过本文的介绍,相信你已经掌握了 Prophet 的基本用法和调优技巧。赶快用它来预测你关心的数据吧!

但是,请记住,Prophet 并不是万能的,它也有自己的局限性。例如,它不适合预测没有明显规律的时间序列,也不适合预测长期趋势。在使用 Prophet 时,需要根据实际情况选择合适的模型和参数,并结合其他方法进行综合分析。

最后再多说几句,虽然现在有很多AutoML工具可以自动完成建模和调参,但我还是强烈建议你亲自上手试试Prophet。只有真正理解了它的原理和参数,才能更好地应用它,并解决实际问题。就像开车一样,即使有了自动驾驶,你还是需要了解基本的驾驶知识,才能应对各种路况。

希望这篇文章能帮助你更好地使用Prophet,如果你有任何问题或想法,欢迎在评论区留言讨论!

技术老司机 时间序列预测ProphetPython

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/8793