Python Prophet 时间序列预测实战:从原理到调优
什么是 Prophet?
为什么选择 Prophet?
Prophet 的核心原理
Prophet 实战:预测网站访问量
1. 数据准备
2. 模型训练
3. 预测
4. 结果可视化
5. 模型调优
6. 处理异常值
总结
最近几年,时间序列预测火了起来。你是不是也经常遇到这样的场景:需要预测未来一段时间的销售额、用户增长数,或者网站流量?别担心,今天咱们就来聊聊 Facebook 开源的时间序列预测神器——Prophet。
什么是 Prophet?
Prophet 是 Facebook(现在叫 Meta 了)核心数据科学团队开发的开源时间序列预测库,专为具有明显季节性和趋势性的业务数据而设计。它基于加法模型(Additive Model),将时间序列分解为趋势、季节性和节假日效应等多个组成部分,能够很好地处理缺失值和异常值,并且对参数调整不敏感,上手非常容易。
简单来说,Prophet 就像一个经验丰富的“算命先生”,它能根据你过去的数据,“推算”出未来的走势。当然,它不是真的算命,而是基于统计学和机器学习的原理。
为什么选择 Prophet?
与其他时间序列预测方法(如 ARIMA、LSTM 等)相比,Prophet 有以下几个显著优势:
- 易用性:Prophet 的 API 设计非常简洁,几行代码就能完成模型的训练和预测。即使你对时间序列预测不熟悉,也能快速上手。
- 自动处理:Prophet 能够自动检测季节性、趋势变化点,并处理缺失值和异常值,省去了大量数据预处理的工作。
- 可解释性:Prophet 将时间序列分解为多个组成部分,方便你理解每个部分对预测结果的影响。
- 灵活性: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,如果你有任何问题或想法,欢迎在评论区留言讨论!