当前位置: 首页 > news >正文

[深度学习项目] - 时间序列预测 (4)

Prophet 算法

  • 只需要有基本的建模知识即可
  • 有较强的可解释性和可视化支持
  • 能作为大部分时间序列预测的benchmark

模型结构: 关于时间的广义线性模型
y ( t ) = g ( t ) + s ( t ) + h ( t ) + ϵ t y(t)=g(t)+s(t)+h(t)+\epsilon_t y(t)=g(t)+s(t)+h(t)+ϵt
其中,

  • g(t)表示趋势 trend,用分段线性函数 或者 逻辑斯蒂增长 (逻辑斯蒂增长 相对于 线性 会有上下界限) 函数拟合。
    g ( t ) = C 1 + e − k ( t − m ) g(t)=\frac{C}{1+e^{-k(t-m)}} g(t)=1+ek(tm)C , C 表示上界 ; k表示增长/下降快慢; m表示增长/下降 最快的点。
    用户需要给出 C 和 分段的段数。

  • s(t)表示季节性 seasonality, 用傅里叶级数拟合。可以叠加多个季节性, 比如 weekly, yearly。 s = s 1 + s 2 s=s_1+s_2 s=s1+s2
    s ( t ) = ∑ n = 1 N [ a n c o s ( 2 π n t T ) + b n s i n ( 2 π n t T ) ] s(t)=\sum_{n=1}^N [a_ncos(\frac{2\pi nt}{T})+b_n sin(\frac{2\pi n t}{T})] s(t)=n=1N[ancos(T2πnt)+bnsin(T2πnt)], T 表示周期长度 , N表示阶数。 T表示了数据的周期性; N 表示了采用的傅里叶级数的最高阶数。 N越大,曲线本身的波动也越大,也越容易造成过拟合。

  • h(t)表示外部变量的影响 regressor,采用线性函数拟合。可以叠加多个外部变量,如节假日,温度,活动。
    h = w 1 h 1 + w 2 h 2 + … h=w_1 h_1 +w_2 h_2 +\dots h=w1h1+w2h2+ h(t)可以是连续变量,也可以是0-1量。

  • ϵ t \epsilon_t ϵt表示模型残差,表示不可知的外部变量造成的影响。

import pandas as pd
import prophet
import matplotlib.pyplot as plt

df_sales = pd.read_csv("store_sales.csv",parse_dates=["week"])
df_prom = pd.read_csv("promotion_data.csv",parse_dates=["week"])
# print(df_sales.head(2))
# print(df_prom.head(2))

df_all = pd.merge(df_sales, df_prom, how="left")
df_all.fillna(0,inplace=True)

dept = 1

df_train = df_all[ (df_all["week"]<="2012-07-30")&
                   (df_all["store"]==1)&
                   (df_all["dept"]==dept)]
df_train.rename(columns={"week":"ds","sales":"y"},inplace=True)

df_test = df_all[ (df_all["week"]<="2012-08-06")&
                   (df_all["store"]==1)&
                   (df_all["dept"]==dept)]
df_test.rename(columns={"week":"ds","sales":"y"},inplace=True)


###### 年周期性
m = prophet.Prophet(yearly_seasonality=True)

####### add regressor
m.add_regressor("promotion_sales")

#####  TRAIN
m.fit(df_train)

######  fit previous data
df_fit = m.predict(df_train)

###### visualize
fig1 = m.plot_components(df_fit)
fig2 = m.plot(df_fit)
plt.show()

trend period regressor

prophet prediction
prophet 只能预测线性模型。

机器学习预测 (LightGBM)

  1. 通过滑动窗口获取 训练集,验证机,测试集
  2. 构建特征: 将最原始的特征 [ y 1 , x 1 , y 2 , x 2 , … , x T , y T , x T + 1 , x T + 2 , … , x T + h ] [y_1,x_1,y_2,x_2,\dots,x_T,y_T,x_{T+1},x_{T+2},\dots,x_{T+h}] [y1,x1,y2,x2,,xT,yT,xT+1,xT+2,,xT+h] 进行处理
  • 将过去一段时间的特征进行聚合: 平均值,标准差,最大值,最小值 等等
  • 特定时间点的取值: 上一个时间点的x/y , 上一个周期的x/y, …
  • 时间序列的复合特征: 自相关性系数,STL分解的结果,差分
import pandas as pd
import prophet
import matplotlib.pyplot as plt

import lightgbm as lgb
from lightgbm.sklearn import LGBMRegressor

df_sales = pd.read_csv("store_sales.csv",parse_dates=["week"])
df_prom = pd.read_csv("promotion_data.csv",parse_dates=["week"])
# print(df_sales.head(2))
# print(df_prom.head(2))
#
df_all = pd.merge(df_sales, df_prom, how="left")
df_all.fillna(0,inplace=True)


#### lightgbm
df_samples = df_all[ (df_all["store"]==1)&
                     (df_all["dept"]==1)].sort_values("week")

###  construct features
feature_cols = []

### first feature:  last week
df_samples["sales_lw"] = df_samples["sales"].shift(1)
df_samples["promotion_lw"] = df_samples["promotion_sales"].shift(1)

feature_cols = feature_cols + ["sales_lw", "promotion_lw"]

#### second features:  last year
df_samples["sales_ly"] = df_samples["sales"].shift(52)
df_samples["promotion_ly"] = df_samples["promotion_sales"].shift(52)

feature_cols += ["sales_ly","promotion_ly"]

#### third features:  variances waiting for prediction
feature_cols = feature_cols + ["promotion_sales"]

#### keep the data that is not nan
for col in feature_cols:
    df_samples = df_samples[ ~df_samples[col].isna() ]

######### construct train data and test data
x_train = df_samples[df_samples["week"]<="2012-07-30"][feature_cols].values
y_train = df_samples[df_samples["week"]<="2012-07-30"]["sales"].values

x_test = df_samples[df_samples["week"]=="2012-08-06"][feature_cols].values
y_test = df_samples[df_samples["week"]=="2012-08-06"]["sales"].values

model = LGBMRegressor()
model.fit(x_train,y_train)

#### prediction
y_pred = model.predict(x_test)

print("actual data:",y_test)
print("prediction:",y_pred)

>>>16119.92
>>>16165.25781465

不同算法区别

特点ETSARIMAProphetLightGBM
是否适合短的时间序列YNNN
是否可解释YYYN
是否支持多条序列批量预测NNNY,多条线可以在一个model中
是否支持外部变量NNY,但只是线性变量Y

homework

使用Prophet 和 LightGBM算法 完成 之后所有时间的预测。

prophet

df_sales = pd.read_csv("store_sales.csv",parse_dates=["week"])
df_prom = pd.read_csv("promotion_data.csv",parse_dates=["week"])
# print(df_sales.head(2))
# print(df_prom.head(2))
#
df_all = pd.merge(df_sales, df_prom, how="left")
df_all.fillna(0,inplace=True)
#
dept = 1

print(df_all[ (df_all["store"]==1)&
        (df_all["dept"]==dept)] .sort_values(["week"]).tail(3))

test_date_begin = pd.to_datetime("2012-07-30")
test_date_end = pd.to_datetime("2012-10-22")

test_date = df_all[ (df_all["week"]>=test_date_begin)&
                    (df_all["week"]<=test_date_end)]["week"].unique()

predict_result = []
actual_result = []

print("total prediction num:", len(test_date))
print(test_date)



for i, every_test_date in enumerate(test_date):

    print("predicting: {}".format(i))

    df_train = df_all[ (df_all["week"]<every_test_date)&
                       (df_all["store"]==1)&
                       (df_all["dept"]==dept)]
    df_train.rename(columns={"week":"ds","sales":"y"},inplace=True)


    actual_result.append( df_all[(df_all["week"]==every_test_date)&
                                 (df_all["store"]==1)&
                                 (df_all["dept"]==dept)]["sales"].values[-1] )
    # print(actual_result[-1])

    df_test = df_all[ (df_all["week"]==every_test_date)&
                       (df_all["store"]==1)&
                       (df_all["dept"]==dept)]
    df_test.rename(columns={"week":"ds","sales":"y"},inplace=True)

    m = prophet.Prophet(yearly_seasonality=True)
    m.add_regressor("promotion_sales")
    m.fit(df_train)

    df_predict = m.predict(df_test)
    predict_result.append(df_predict["yhat"].values[0])
    # print(predict_result[-1])


plt.plot(test_date,predict_result,label="prediction")
plt.plot(test_date,actual_result,label="actual")
plt.legend()
plt.xticks(rotation=90)
plt.show()

在这里插入图片描述



#### lightgbm
df_sales = pd.read_csv("store_sales.csv",parse_dates=["week"])
df_prom = pd.read_csv("promotion_data.csv",parse_dates=["week"])
# print(df_sales.head(2))
# print(df_prom.head(2))
#
df_all = pd.merge(df_sales, df_prom, how="left")
df_all.fillna(0,inplace=True)

test_date_begin = pd.to_datetime("2012-07-30")
test_date_end = pd.to_datetime("2012-10-22")

dept = 1

df_samples = df_all[ (df_all["store"]==1)&
                     (df_all["dept"]==dept)].sort_values("week")

###  construct features
feature_cols = []

### first feature:  last week
df_samples["sales_lw"] = df_samples["sales"].shift(1)
df_samples["promotion_lw"] = df_samples["promotion_sales"].shift(1)

feature_cols = feature_cols + ["sales_lw", "promotion_lw"]

#### second features:  last year
df_samples["sales_ly"] = df_samples["sales"].shift(52)
df_samples["promotion_ly"] = df_samples["promotion_sales"].shift(52)

feature_cols += ["sales_ly","promotion_ly"]

#### third features:  variances waiting for prediction
feature_cols = feature_cols + ["promotion_sales"]

#### keep the data that is not nan
for col in feature_cols:
    df_samples = df_samples[ ~df_samples[col].isna() ]

######### construct train data and test data
test_date = df_all[ (df_all["week"]>=test_date_begin)&
                    (df_all["week"]<=test_date_end)]["week"].unique()

predict_result = []
actual_result = []

for i,every_test_date in enumerate(test_date):

    x_train = df_samples[df_samples["week"]<every_test_date][feature_cols].values
    y_train = df_samples[df_samples["week"]<every_test_date]["sales"].values

    x_test = df_samples[df_samples["week"]==every_test_date][feature_cols].values
    y_test = df_samples[df_samples["week"]==every_test_date]["sales"].values

    from lightgbm.sklearn import LGBMRegressor
    model = LGBMRegressor()
    model.fit(x_train,y_train)

    #### prediction
    y_pred = model.predict(x_test)

    predict_result.append(y_pred[0])
    actual_result.append(y_test[0])

print("actual data:",actual_result)
print("prediction:",predict_result)

plt.plot(test_date,predict_result,label="prediction")
plt.plot(test_date,actual_result,label="actual")
plt.legend()
plt.xticks(rotation=90)
plt.show()

在这里插入图片描述

相关文章:

  • MaxViT实战:使用MaxViT实现图像分类任务(一)
  • 【Golang开发面经】米哈游(一轮游)
  • 【Liunx常用命令】回顾下Linux常用命令
  • .net快速开发框架源码分享
  • 【jQuery动画】停止动画、淡入淡出、自定义动画
  • 【操作系统】进程和线程基础
  • 替换空格问题
  • OpenCV-滤波矩阵(java版)
  • 前端性能优化 - 华为面试题
  • netsh命令设置IP地址/DNS服务器地址(域设置)
  • 【Python 小白到精通 | 课程笔记】第三章:数据处理就像侦探游戏(函数和包)
  • 以太坊未来⼗年的的破局之路:区块链模块化+合并成功后,以太坊交易者需要读懂这些数据
  • 使用Vue和SpringBoot开发实验室耗材智能运维系统
  • kubernetes(9)集群安全机制
  • Google Earth Engine (GEE) ——加载2015年乌干达MODIS的LST并绘制时序图
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • Angular数据绑定机制
  • JavaScript创建对象的四种方式
  • magento2项目上线注意事项
  • Odoo domain写法及运用
  • ReactNative开发常用的三方模块
  • redis学习笔记(三):列表、集合、有序集合
  • RxJS: 简单入门
  • ubuntu 下nginx安装 并支持https协议
  • vue的全局变量和全局拦截请求器
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 后端_ThinkPHP5
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 来,膜拜下android roadmap,强大的执行力
  • 如何合理的规划jvm性能调优
  • 我感觉这是史上最牛的防sql注入方法类
  • 新书推荐|Windows黑客编程技术详解
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • k8s使用glusterfs实现动态持久化存储
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​Spring Boot 分片上传文件
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #162 (Div. 2)
  • #HarmonyOS:基础语法
  • #pragma 指令
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (LeetCode C++)盛最多水的容器
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (六)Hibernate的二级缓存
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (未解决)macOS matplotlib 中文是方框
  • .NET CLR基本术语
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .NET WebClient 类下载部分文件会错误?可能是解压缩的锅
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .net 简单实现MD5