【Python】使用Python+Prophet 实现时间序列分析

【Python】轻量化编程实战

提高打工人效率系列文章:

第二篇 使用Python+Prophet 实现时间序列分析


前言

提示:这里可以添加本文要记录的大概内容:

创作背景:Prophet是一个由Facebook开发的时间序列分析工具,早期是用来分析网页点击行为规律。在实际工作中,我把它延申应用到分析网约车订单的出行规律中。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Prophet是什么?

Prophet是基于可分解(趋势+季节+节假日)模型的开源库,可以用简单直观的参数进行高精度的时间序列预测,并且支持自定义季节和节假日的影响。
原理:
时间序列模型可分解为三个主要组成部分:趋势,季节性和节假日。
它们按如下公式组合:
Prophet模型采用加法模型
其中:
g(t):用于拟合时间序列中的分段线性增长或逻辑增长等非周期变化。
s(t):周期变化(如:每周/每年的季节性)。
h(t):非规律性的节假日效应(用户造成)。
et:误差项用来反映未在模型中体现的异常变动。

二、为什么出行业务可以使用 时间序列 模型进行分析?

  1. 有至少几个月(最好是一年)的每小时、每天或每周观察的历史数据;
  2. 有多种人类规模级别的较强的季节性趋势:每周的一些天和每年的一些时间;
  3. 有事先知道的以不定期的间隔发生的重要节假日(比如国庆节);

三、程序实现

3.1 导入库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
from fbprophet import Prophet
  1. Prophet库可以通过pip来安装,建议走国内的安装源,更快一些。
  2. Matplotlib需要单独安装中文字符库,否则有些字体会显示成方块。
#字体管理器
from matplotlib import font_manager as rcParams
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
plt.rcParams['axes.unicode_minus']=False   #这两行需要手动设置

3.2 读取并预处理相关数据

分析出行数据规律的话,最好按照分析颗粒度需求来聚合一下,否则数据量实在太大且分散,没有分析价值。

我这里是要看每天24小时之内,每个小时段的用车规律,所以只要按照小时来聚合数据即可。如果要看的是全年每一天的规律,那就按天聚合。

#数据处理
data_bs = pd.read_csv('C:/Users/xxxx/Downloads/xx区分时单量_2021-04-25.csv',header=0,encoding='gbk')

# 按照时段聚合单量的函数
def order_per_hour(data):
    data['撮合成功时间'] = pd.to_datetime(data['撮合成功时间'])
    # 将撮合时间归集到当前小时
    data['订单时段'] = data['撮合成功时间'].map(lambda x:x.replace(minute=0,second=0))
    # 按照每天每个小时聚合
    result = data.groupby(['订单时段'])[['起点区域']].count()
    result.sort_index()
    result.reset_index(inplace=True)
    result.rename(columns={'订单时段':'ds','起点区域':'y'},inplace=True)
    return result

# 获得按小时聚合的数据
result_bs = order_per_hour(data_bs)

3.3 增加非规律性信息

出行规律可能会受到一些非规律性因素的影响,从而会导致在数据上显示出不同寻常的突起。Prophet工具的优点就在于,可以自定义非规律性信息(这些非规律信息必须是跟着时间走的),也就上上面公式中的h(t):非规律性的节假日效应(用户造成)。

我们在出行规律分析中,可以将节假日作为异常信息投喂给模型。

代码示例:

# 建立假期信息
# 对节假日建模
# 将节日看成是一个正态分布,把活动期间当做波峰,lower_window 以及upper_window 的窗口作为扩散
national_holiday = pd.DataFrame({
  'holiday': 'national holiday',
  'ds': pd.to_datetime(['2020-10-01']),
  'lower_window': -1,
  'upper_window': 8,
})
EIIE = pd.DataFrame({
  'holiday': 'EIIE',
  'ds': pd.to_datetime(['2020-11-04']),
  'lower_window': -1,
  'upper_window': 6,
})
christmas = pd.DataFrame({
  'holiday': 'christmas',
  'ds': pd.to_datetime(['2020-12-25']),
  'lower_window': -1,
  'upper_window': 0,
})
# random = pd.DataFrame({
#   'holiday': 'random',
#   'ds': pd.to_datetime(['2020-11-28']),
#   'lower_window': 0,
#   'upper_window': 1,
# })
new_year = pd.DataFrame({
  'holiday': 'new year',
  'ds': pd.to_datetime(['2021-01-01']),
  'lower_window': -1,
  'upper_window': 3,
})
spring_festival = pd.DataFrame({
  'holiday': 'spring festival',
  'ds': pd.to_datetime(['2021-02-11']),
  'lower_window': -2,
  'upper_window': 7,
})
lantern_festival = pd.DataFrame({
  'holiday': 'lantern festival',
  'ds': pd.to_datetime(['2021-02-26']),
  'lower_window': 0,
  'upper_window': 1,
})
easter = pd.DataFrame({
  'holiday': 'easter',
  'ds': pd.to_datetime(['2021-04-04']),
  'lower_window': -2,
  'upper_window': 2,
})
labor_day = pd.DataFrame({
  'holiday': 'labor day',
  'ds': pd.to_datetime(['2021-05-01']),
  'lower_window': -2,
  'upper_window': 5,
})
# 整合holidays信息
holidays = pd.concat((national_holiday,EIIE,christmas, new_year,spring_festival,lantern_festival,easter,labor_day),ignore_index=True)

3.4 建模

调用Prophet的标准模型接口即可。其实Prophet模型跟大多数机器学习模型一样,都可以进行学习后的预测。但是在分析历史的出行规律中,预测本身意义不大,尤其是它的预测结果对于实际操作的参考价值一般。

代码示例:

# xx区分时段订单分析

# xx数据建模
# 建模
m_bs = Prophet(holidays=holidays)
# 学习
m_bs.fit(result_bs)
# 训练
future_bs = m_bs.make_future_dataframe(periods=120, freq='H')
# 预测
forecast_bs = m_bs.predict(future_bs)
trend_bs = forecast_bs['trend']

3.5 可视化

利用Matplotlib对模型结果进行可视化展示。Matplotlib的使用方法我就不多赘述了,需要了解的可以在CSDN自行学习。

代码示例1:

# 用plot图展示预测趋势

plt.style.use('seaborn')
fig1,ax1 = plt.subplots(figsize=(15,10))
ax1.plot(forecast_bs['ds'],trend_bs,linestyle='--', label='trend_bs')
ax1.plot(forecast_hp['ds'],trend_hp,linestyle='-.', label='trend_hp')
ax1.plot(forecast_pd['ds'],trend_pd,linestyle='-', label='trend_pd')
ax1.legend()

在这里插入图片描述
代码示例2:

# 用plot图展示了节假日因素的影响程度

plt.style.use('seaborn')
fig2,ax2 = plt.subplots(figsize=(15,10))
ax2.plot(forecast_bs['ds'],forecast_bs['holidays'],linestyle='--',color='red', label='trend_bs')
ax2.plot(forecast_hp['ds'],forecast_hp['holidays'],linestyle='-.',color='green', label='trend_hp')
ax2.plot(forecast_pd['ds'],forecast_pd['holidays'],linestyle='-',color='blue', label='trend_pd')
ax2.legend()

在这里插入图片描述

3.6 延申应用

  1. 将数据按照年度取样,并按照天来聚合的话,可以用于分析全年的出行规律。

代码示例:

# 拟合模型
model = Prophet(weekly_seasonality=True)
model.fit(daily_total)

# 构建待预测日期数据框,periods = 365 代表除历史数据的日期外再往后推 365 天
future = model.make_future_dataframe(periods=30)
#print(future.tail())

# 预测数据集
forecast = model.predict(future)
#print(forecast.columns)
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())

# 展示预测结果
model.plot(forecast)
plt.show()

在这里插入图片描述
2. 还可以进行预测成分分析,并可以统计出周维度的规律信息。

代码示例:

# 预测的成分分析绘图,展示预测中的趋势、周效应
model.plot_components(forecast)
print(forecast.columns)

在这里插入图片描述

  1. 还可以在周-季节维度进行分析(默认采用weekly_seasonality)
# 默认采用weekly_seasonality进行周期性分析
m = Prophet(holidays=holidays)
m.fit(daily_total)
future = m.make_future_dataframe(periods=10)
forecast = m.predict(future)
# 可对比增加holiday因素以后,预测模型前后拟合的程度差别
m.plot(forecast)
# 预测的成分分析绘图,展示预测中的趋势、周效应和年度效应
m.plot_components(forecast)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 也可以在月-季节维度进行分析。
    代码示例:
# 也可以采用monthly_seasonality进行周期性分析

m = Prophet(holidays=holidays,weekly_seasonality=False)
m.add_seasonality(name='monthly', period=30.5, fourier_order=7)
m.fit(daily_total)
future = m.make_future_dataframe(periods=10)
forecast = m.predict(future)
# 可对比增加holiday因素以后,预测模型前后拟合的程度差别
# 预测的成分分析绘图,展示预测中的趋势、月效应和年度效应
m.plot_components(forecast)

在这里插入图片描述
在这里插入图片描述

  1. 可以使用 plot_forecast_component(从fbprophet.plot导入)来画出独立的节假日的成分。
from prophet.plot import plot_forecast_component
plot_forecast_component(m,forecast, 'labor day')

在这里插入图片描述

  1. 在图形中显示显著的突变点的位置。
from fbprophet.plot import add_changepoints_to_plot
fig = m.plot(forecast)
a = add_changepoints_to_plot(fig.gca(), m, forecast)

在这里插入图片描述
也可以手动指定突变点的位置。

# 手动指定突变点的位置
m = Prophet(changepoints=['2020-12-31'],weekly_seasonality=True)
m.fit(daily_total)
future = m.make_future_dataframe(periods=30)
forecast = m.predict(future)
m.plot(forecast)

总结

以上就是今天要讲的内容,本文仅仅简单介绍了python+Prophet 实现用时间序列模型分析出行规律的方法,更多的应用场景还需要大家自己探索和实践。

记住:
能看懂多少不重要,勇敢的迈出第一步才是最重要的。打工人,加油!

  • 37
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值