机器学习笔记二-----------------Prophet(时间序列模型)的复杂例程笔记及给jupyter添加多个python版本的kernel的方法

一,重要参数的意义说明

1, Prophet()模型参数说明


Prophet()参数说明
growth: ‘linear‘’或’logistic’用来规定线性或逻辑曲线趋势'.(默认‘linear’)

changepoints: 指定潜在改变点,如果不指定,将会自动选择潜在改变点。例如:changepoints=['2014-01-01']指定2014-01-01这一天是潜在的changepoints。(默认None)

n_changepoints: 表示changepoints的数量大小,如果changepoints指定,该传入参数将不会被使用。如果 changepoints不指定,将会从输入的历史数据前80%中选取25个(个数由n_changepoints传入参数决定)潜在改变点。(默认25)

changepoint_range: Proportion of history in which trend changepoints will be estimated. Defaults to 0.8 for the first 80%. Not used if `changepoints` is specified.Not used if input `changepoints` is supplied.估计趋势变化点的历史比例。如果指定了 `changepoints`,则不使用。(默认0.8)

yearly_seasonality: 指定是否分析数据的年季节性,如果为True, 默认取傅里叶项为10,最后会输出,yearly_trend,yearly_upper,yearly_lower等数据。(默认auto)

weekly_seasonality: 指定是否分析数据的周季节性,如果为True,默认取傅里叶项10,最后会输出,weekly_trend,weekly_upper,weekly_lower等数据。(默认auto)

daily_seasonality: 指定是否分析数据的天季节性,如果为True,默认取傅里叶项为10,最后会输出,daily _trend, daily _upper, daily _lower等数据。(默认auto)

holidays: 传入pd.dataframe 格式的数据。这个数据包含有holiday列 (string)和ds(date类型)和可选列lower_window和upper_window来指定该日期的lower_window或者upper_window范围内都被列为假期。lower_window=-2将包括前2天的日期作为假期。(默认None)

seasonality_mode: 'additive' (default) or 'multiplicative'.季节模型。(默认additive)

seasonality_prior_scale: 调节季节性组件的强度。值越大,模型将适应更强的季节性波动,值越小,越抑制季节性波动。(默认10)

holidays_prior_scale:调节节假日模型组件的强度。值越大,该节假日对模型的影响越大,值越小,节假日的影响越小。(默认10)

changepoint_prior_scale: 增长趋势模型的灵活度。调节”changepoint”选择的灵活度,值越大选择的”changepoint”越多,使模型对历史数据的拟合程度变强,然而也增加了过拟合的风险。(默认0.05)

mcmc_samples: If 0, will do MAP estimation.mcmc采样,用于获得预测未来的不确定性。若大于0,将做mcmc样本的全贝叶斯推理,如果为0,将做最大后验估计。(默认0)

interval_width:衡量未来时间内趋势改变的程度。表示预测未来时使用的趋势间隔出现的频率和幅度与历史数据的相似度,值越大越相似。当mcmc_samples = 0时,该参数仅用于增长趋势模型的改变程度,当mcmc_samples > 0时,该参数也包括了季节性趋势改变的程度。(默认0.8)

uncertainty_samples: 用于估计不确定性区间的模拟抽取数。(默认1000)

2、 make_future_dataframe()参数说明


def make_future_dataframe(self, periods, freq='D', include_history=True):

            periods: 向前预测步数

            freq: ’H’、 'D' or 'M'.预测单位小时为’H’,天为’D’,月为’M’

            include_history: 是否包含历史数据的预测,保持默认就好。
 

二,Prophet(时间序列模型)可调节参数示例

1,Prophet 中的自动变化点检测范围

     Prophet 通过首先指定允许速率变化的大量潜在变化点来检测变化点。然后它对速率变化的幅度进行稀疏先验(相当于 L1 正则化)——这本质上意味着 Prophet 有大量可能的地方可以改变速率,但会尽可能少地使用它们。默认情况下,Prophet 指定了 25 个潜在的变化点,它们均匀地放置在时间序列的前 80% 中。使用上节中的第一个例子说明。

     可以使用参数设置潜在变化点的数量n_changepoints,但通过调整正则化可以更好地调整。意义变化点的位置可以通过以下方式可视化:

from prophet.plot import add_changepoints_to_plot
fig = m.plot(forecast)
a = add_changepoints_to_plot(fig.gca(), m, forecast)

  默认情况下,仅为时间序列的前 80% 推断变化点,以便有足够的跑道来预测未来趋势并避免在时间序列结束时过度拟合波动。此默认值适用于许多情况,但不是全部,并且可以使用changepoint_range参数进行更改。python中更改该参数的方法为:

m = Prophet(changepoint_range=0.9)

备注:

   由于pycharm 对该算法的可视化显示很差,所以需要在linux下安装jupyter,并使其支持多个虚拟环境,可以借鉴以下的教程进行配置

给jupyter添加多个python版本的kernel_千秋莫负-CSDN博客_ipykernel python版本

估计趋势变化点的历史比例。如果指定了 `changepoints`,则不使用。(默认0.8)

2,调整趋势灵活性

如果趋势变化过拟合(灵活性太大)或欠拟合(灵活性不够),可以使用输入参数调整稀疏先验的强度changepoint_prior_scale。默认情况下,此参数设置为 0.05。增加它将使趋势更加灵活:

m = Prophet(changepoint_prior_scale=0.5)
forecast = m.fit(df).predict(future)
fig = m.plot(forecast)

可通过 forecast 数据框,来展示节假日效应:

# 看一下假期的最后10行数据
forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][
        ['ds', 'playoff', 'superbowl']][-10:]

三,季节性,假期效果和回归量

1, 对假期和特征事件建模

1.1 自定义指定日期的方法

    如果需要专门对节假日或者其它的事件进行建模,你就必须得为此创建一个新的dataframe,其中包含两列(节假日 holiday 和日期戳 ds ),每行分别记录了每个出现的节假日。这个数据框必须包含所有出现的节假日,不仅是历史数据集中还是待预测的时期中的。如果这些节假日并没有在待预测的时期中被注明, Prophet 也会利用历史数据对它们建模,但预测未来时却不会使用这些模型来预测。

注:也就是说,在待预测的日期里,我们也必须指定所有出现的节假日。

    你可以在这个数据框基础上再新建两列 lower_window 和 upper_window ,从而将节假日的时间扩展成一个区间 [ lower_window , upper_window ] 。举例来说,如果想将平安夜也加入到 “圣诞节” 里,就设置 lower_window = -1 , upper_window = 0 ;如果想将黑色星期五加入到 “感恩节” 里【感恩节的第二天是黑色星期五】,就设置 lower_window = 0 , upper_window = 1 。

下面我们创建一个数据框,其中包含了所有佩顿 · 曼宁参加过的决赛日期:
 

#季后赛
playoffs = pd.DataFrame({
  'holiday': 'playoff',
  'ds': pd.to_datetime(['2008-01-13', '2009-01-03', '2010-01-16',
                        '2010-01-24', '2010-02-07', '2011-01-08',
                        '2013-01-12', '2014-01-12', '2014-01-19',
                        '2014-02-02', '2015-01-11', '2016-01-17',
                        '2016-01-24', '2016-02-07']),
  'lower_window': 0,
  'upper_window': 1,
})
#超级碗
superbowls = pd.DataFrame({
  'holiday': 'superbowl',
  'ds': pd.to_datetime(['2010-02-07', '2014-02-02', '2016-02-07']),
  'lower_window': 0,
  'upper_window': 1,
})
#节日是两个的节假日的叠加
holidays = pd.concat((playoffs, superbowls))

    上述代码中,我们将超级碗的日期既记录在了决赛的日期数据框中,也记录在了超级碗的日期数据框中。这就会造成超级碗日期的效应会在决赛日期的作用下叠加两次。(意味着两个强效应的叠加)

    节日效果可以在forecast数据框中看到。使用下述代码

forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][
        ['ds', 'playoff', 'superbowl']][-10:]

    一旦这个数据框创建好了,就可以通过传入 holidays 参数使得在预测时考虑上节假日效应。这里我们仍以第一部分中佩顿 · 曼宁的数据为例:

import pandas as pd
import numpy as np
from fbprophet import Prophet
df = pd.read_csv('example_wp_log_peyton_manning.csv')
#专门对节假日或者其它的事件进行建模,你就必须得为此创建一个新的dataframe
#其中包含两列(节假日 holiday 和日期戳 ds )
#季后赛
playoffs = pd.DataFrame({
  'holiday': 'playoff',
  'ds': pd.to_datetime(['2008-01-13', '2009-01-03', '2010-01-16',
                        '2010-01-24', '2010-02-07', '2011-01-08',
                        '2013-01-12', '2014-01-12', '2014-01-19',
                        '2014-02-02', '2015-01-11', '2016-01-17',
                        '2016-01-24', '2016-02-07']),
  'lower_window': 0,
  'upper_window': 1,
})
#超级碗
superbowls = pd.DataFrame({
  'holiday': 'superbowl',
  'ds': pd.to_datetime(['2010-02-07', '2014-02-02', '2016-02-07']),
  'lower_window': 0,
  'upper_window': 1,
})
holidays = pd.concat((playoffs, superbowls))#季后赛和超级碗比赛特别日期

m = Prophet(holidays=holidays)#指定节假日参数,其它参数以默认值进行训练
m.fit(df)#对过去数据进行训练
future = m.make_future_dataframe(freq='D',periods=365)#建立数据预测框架,数据粒度为天,预测步长为一年
forecast =m.predict(future)
print(forecast)
m.plot(forecast).show()#绘制预测效果图
m.plot_components(forecast).show()#绘制成分趋势图

可以使用 plot_forecast_component(从fbprophet.plot导入)来画出独立的节假日的成分。类似如下代码,下面的代码专门查看超级碗的成分:

from fbprophet.plot import plot_forecast_component
m.plot_forecast_component(forecast, 'superbowl')

 

1.2,内置国家法定节日的方法

  add_country_holidays您可以使用方法 (Python) 使用内置的特定国家/地区假期集合。holidays指定国家/地区的名称,然后除了通过上述参数指定的任何假期外,还将包括该国家/地区的主要假期:

# Python
m = Prophet(holidays=holidays)
m.add_country_holidays(country_name='US')
#df是数据
m.fit(df)

如果想查看有哪些节假日,可以 通过查看模型的train_holiday_names,执行的语句为:

m.train_holiday_names

    每个国家的假期由holidaysPython 包提供。可用国家/地区列表和要使用的国家/地区名称可在其页面上找到:https://github.com/dr-prodigy/python-holidays。除了这些国家/地区,Prophet 还包括以下国家/地区的假期:巴西 (BR)、印度尼西亚 (ID)、印度 (IN)、马来西亚 (MY)、越南 (VN)、泰国 (TH)、菲律宾 (PH)、巴基斯坦 ( PK)、孟加拉国 (BD)、埃及 (EG)、中国 (CN) 和俄罗斯 (RU)、韩国 (KR)、白俄罗斯 (BY) 和阿拉伯联合酋长国 (AE)。

执行以下语句,就可以看到该模型算法库中对应的中国的节假日

import pandas as pd
import numpy as np
from fbprophet import Prophet
df = pd.read_csv('example_wp_log_peyton_manning.csv')

holidays = pd.DataFrame({
  'holiday': 'playoff',
  'ds': pd.to_datetime(['2008-01-13', '2009-01-03', '2010-01-16',
                        '2010-01-24', '2010-02-07', '2011-01-08',
                        '2013-01-12', '2014-01-12', '2014-01-19',
                        '2014-02-02', '2015-01-11', '2016-01-17',
                        '2016-01-24', '2016-02-07']),
  'lower_window': 0,
  'upper_window': 1,
})

m = Prophet(holidays=holidays)
m.add_country_holidays(country_name='CN')
#df是数据
m.fit(df)
print(m.train_holiday_names)


      在 Python 中,大多数假期都是确定性计算的,因此适用于任何日期范围;如果日期超出该国家/地区支持的范围,将发出警告。 如果需要更宽的日期范围,可以使用此脚本将该文件替换为不同的日期范围:https://github.com/facebook/prophet/blob/main/python/scripts/generate_holidays_file.py。

    使用中国的节假日进行预测,得到的结果如下图所示:

2,季节性的傅里叶顺序 

2.1 使用参数调节的方法增强季节性的影响

设置的方法。通过更改yearly_seasonality参数的设置。   m = Prophet(yearly_seasonality=20)

     季节性是用部分傅里叶和估计的。说明部分傅里叶和如何近似于一个线性周期信号。部分和(order)中的项数是一个参数,它决定了季节性的变化有多快。为了说明这一点, 我们仍似乎用第一部分中佩顿 · 曼宁的数据。每年季节性的默认傅立叶级数是10,这就产生了这样的拟合:

import pandas as pd
import matplotlib.pyplot as plt
from fbprophet import Prophet
from prophet.plot import plot_plotly, plot_components_plotly
import time
from fbprophet.plot import plot_yearly

#数据的读入,输入的数据的时间是从2007年12月10号到2016年1月20日
#一共是2905天
df = pd.read_csv('example_wp_log_peyton_manning.csv')
# new_df = df[0:2896]
print(df)
#使用原始的进行拟合,通过对一个 Prophet 对象进行实例化来拟合模型
#调用拟合模型进行拟合
m = Prophet().fit(df)
a = plot_yearly(m)




      默认值10通常是合适的,但是当季节性需要适应更高频率的变化时,它们可以增加,并且通常不那么平滑。在实例化模型时,可以为每个内置季节性指定傅立叶级数,这里增加到20: 

import pandas as pd
import matplotlib.pyplot as plt
from fbprophet import Prophet
from prophet.plot import plot_plotly, plot_components_plotly
import time
from fbprophet.plot import plot_yearly

#数据的读入,输入的数据的时间是从2007年12月10号到2016年1月20日
#一共是2905天
df = pd.read_csv('example_wp_log_peyton_manning.csv')
# new_df = df[0:2896]
print(df)
#使用原始的进行拟合,通过对一个 Prophet 对象进行实例化来拟合模型
#调用拟合模型进行拟合
m = Prophet(yearly_seasonality=20).fit(df)
a = plot_yearly(m)



 从图像上显示,可以看到和参数为10的时候,平滑度已经发生了变化

    可以看到,曲线更加的多变了。增加傅立叶项的数量可以使季节性适应更快的变化周期,但也可能导致过度拟合:N个傅立叶项对应于用于建模周期的2N个变量。

2.2 自定义季节性

主要是使用add_seasality方法添加其它季节性(如每月、每季、每小时)

       如果时间序列超过两个周期,Prophet将默认适合每周和每年的季节性。对于子日(sub-daily )时间序列,它也将适合每日的季节性。在Python中,可以使用add_seasality方法添加其它季节性(如每月、每季、每小时)。

    这个函数的输入是一个名字,季节性的周期,以及季节性的傅里叶order

  【m.add_seasonality(name='monthly', period=30.5, fourier_order=5)

   作为参考,默认情况下,Prophet为周季节性设定的傅立叶order为3,为年季节性设定的为10。add_seasality的一个可选输入是该季节性组件的先验规模。

     作为一个例子,我们仍使用佩顿 · 曼宁的数据,但是用每月的季节性替换每周的季节性。每月的季节性将出现在组件图中:
 

import pandas as pd
import matplotlib.pyplot as plt
from fbprophet import Prophet
from prophet.plot import plot_plotly, plot_components_plotly
import time
from fbprophet.plot import plot_yearly

#数据的读入,输入的数据的时间是从2007年12月10号到2016年1月20日
#一共是2905天
df = pd.read_csv('example_wp_log_peyton_manning.csv')
# new_df = df[0:2896]
print(df)
#使用原始的进行拟合,通过对一个 Prophet 对象进行实例化来拟合模型
#调用拟合模型进行拟合
m = Prophet(weekly_seasonality=False)
m.add_seasonality(name='monthly', period=30.5, fourier_order=5)
m.fit(df)

future = m.make_future_dataframe(periods=366)
#设定将来预测数据的类型

forecast = m.predict(future)
fig = m.plot_components(forecast)
fig.show()

2.3 取决于其他因素的季节性(将周预测考虑上淡季和旺季的区分)

    在某些情况下,季节性可能取决于其他因素,例如夏季的每周季节性模式与一年中的其他时间不同,或者周末与工作日不同的每日季节性模式。这些类型的季节性可以使用条件季节性进行建模。

    以Peyton Manning 示例。默认的每周季节性假设全年每周季节性的模式是相同的,但我们预计每周季节性的模式在旺季(每周日都有比赛)和淡季是不同的。我们可以使用条件季节性来构建单独的旺季和淡季每周季节性。

首先,我们在数据框中添加一个布尔列,指示每个日期是在旺季还是淡季:

#定义的时间在小于2月或者是大于8月
def is_nfl_season(ds):
    date = pd.to_datetime(ds)
    return (date.month > 8 or date.month < 2)

df['on_season'] = df['ds'].apply(is_nfl_season)
df['off_season'] = ~df['ds'].apply(is_nfl_season)

然后我们禁用内置的每周季节性并将其替换为两个将这些列指定为条件的每周季节性。这意味着季节性将仅应用于该condition_name列所在的日期True。我们还必须将该列添加到future我们正在为其进行预测的数据框中。总的代码如下:

import pandas as pd
import matplotlib.pyplot as plt
from fbprophet import Prophet
from prophet.plot import plot_plotly, plot_components_plotly
import time
from fbprophet.plot import plot_yearly

#自定义一个函数,添加一个布尔列,指示每个日期是在旺季还是淡季
def is_nfl_season(ds):
    date = pd.to_datetime(ds)
    return (date.month > 8 or date.month < 2)



#数据的读入,输入的数据的时间是从2007年12月10号到2016年1月20日
#一共是2905天
df = pd.read_csv('example_wp_log_peyton_manning.csv')
#给数据增加了两个属性,是淡季还是旺季
df['on_season'] = df['ds'].apply(is_nfl_season)
df['off_season'] = ~df['ds'].apply(is_nfl_season)
print(df)

#使用原始的进行拟合,通过对一个 Prophet 对象进行实例化来拟合模型
#调用拟合模型进行拟合
m = Prophet(weekly_seasonality=False)
m.add_seasonality(name='weekly_on_season', period=7, fourier_order=3, condition_name='on_season')
m.add_seasonality(name='weekly_off_season', period=7, fourier_order=3, condition_name='off_season')
m.fit(df)

#预测数据的设置
future = m.make_future_dataframe(periods=366)
future['on_season'] = future['ds'].apply(is_nfl_season)
future['off_season'] = ~future['ds'].apply(is_nfl_season)
forecast =m.predict(future)
fig = m.plot_components(forecast)
fig.show()

       现在,这两种季节性都显示在上面的分量图中。我们可以看到,在每周日打比赛的旺季,周日和周一都有大幅增加,而在淡季则完全没有。

2.4 对节假日和季节性设定先验规模

        如果发现节假日效应被过度拟合了,通过设置参数 holidays_prior_scale 可以调整它们的先验规模来使之平滑,默认下该值取 10 。减少这个参数会降低假期效果:

m = Prophet(holidays=holidays, holidays_prior_scale=0.05).fit(df)

和之前相比,节假日效应的规模被减弱了,特别是对观测值较少的超级碗而言。类似的,还有一个 seasonality_prior_scale 参数可以用来调整模型对于季节性的拟合程度。 

可以通过在节假日的dataframe中包含一个列prior_scale来单独设置先验规模。独立的季节性的先验规模可以作为add_seasonality的参数传递。例如,可以使用以下方法设置每周季节性的先验规模:
 

m = Prophet()
m.add_seasonality(
    name='weekly', period=7, fourier_order=3, prior_scale=0.1)

2.5 附加的回归量

     可以使用add_regressor方法将附加的回归量添加到模型的线性部分。包含回归值的列需要同时出现在拟合数据格式(fit)和预测数据格式(predict)中。例如,我们可以在NFL赛季的周日添加附加的效果。在成分图上,这种效果会出现在“extra_regre_”图中,这样可以增加一个预测结果,如图的最后一张所示:

 完成的代码为:

import pandas as pd
import matplotlib.pyplot as plt
from fbprophet import Prophet
from prophet.plot import plot_plotly, plot_components_plotly
import time
from fbprophet.plot import plot_yearly


#自定义一个函数,添加一个布尔列 判断是否是NFL赛季的周日
def nfl_sunday(ds):
    date = pd.to_datetime(ds)
    if date.weekday() == 6 and (date.month > 8 or date.month < 2):
        return 1
    else:
        return 0

#数据的读入,输入的数据的时间是从2007年12月10号到2016年1月20日
#一共是2905天
df = pd.read_csv('example_wp_log_peyton_manning.csv')
#添加上一个周日的效果
df['nfl_sunday'] = df['ds'].apply(nfl_sunday)
m = Prophet()
#加入一个回归
m.add_regressor('nfl_sunday')
m.fit(df)
#同样在要预测的数据上也要加入该效果
future = m.make_future_dataframe(periods=366)
future['nfl_sunday'] = future['ds'].apply(nfl_sunday)
forecast = m.predict(future)
fig = m.plot_components(forecast)
fig.show()
NFL 周日也可以使用上述“假期”界面通过创建过去和未来 NFL 周日的列表来处理。该add_regressor函数为定义额外的线性回归器提供了一个更通用的接口,特别是不要求回归器是二元指标。另一个时间序列可以用作回归量,尽管必须知道它的未来值。

add_regressor函数具有可选的参数,用于指定先验规模(默认情况下使用节假日先验规模),和指定是否标准化回归量。help(Prophet.add_regressor)可以查看相关参数。

附加的回归量必须要知道历史和未来的日期。因此,它要么是已知未来值(比如nfl_sunday),要么是其他地方已经单独预测出的结果。如果回归量在整个历史中都是不变的,则Prophet会引发一个错误,因为没有任何东西可以fit它。

附加的回归量被放在模型的线性分量中,所以依赖于附加的回归量时间序列作为底层模型的加法或乘法因子。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值