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

文章目录

  • abstract
  • 可视化
  • 读入数据
    • 简单时序图
    • 季节性时序图
    • 季节性箱线图
    • 趋势箱线图
  • 时序的主要成分
  • statsmodels 安装
  • 周期检验
  • STL算法介绍
  • Homework
    • 简单时序图
    • 季节时序图
    • 季节箱线图
    • 趋势箱线图
    • ACF查看周期
    • STL 检测

abstract

  1. 时间序列可视化
  2. 时间序列的四个主要成分: 趋势,季节性(周期性),外部变量,噪音
  3. 计算时间序列的自相关性系数,根据自相关性系数判断季节性
  4. 掌握STL算法分解时间序列

可视化

读入数据

import pandas as pd
import numpy as np
import matplotlib.pyplot  as plt

# 设置pandas 显示行数和列数
pd.options.display.max_rows = 400
pd.options.display.max_columns = None

# 忽略 warnings
import warnings
warnings.filterwarnings("ignore")
# jupyter notebook 可以安装 nbextensions

df_price = pd.read_csv("stock_price.csv", parse_dates=["date"])
# print(df_price.head(2))
df_sales = pd.read_csv("store_sales.csv", parse_dates=["week"])
# print(df_sales.head(2))

简单时序图

时间-观测值之间的关系

######## 简单时序图
### 股价
company = df_price["company"].drop_duplicates().tolist()
print(company)
for every_company in company:
    data_company = df_price[  df_price["company"]==every_company ].sort_values("date")
    plt.plot( data_company["date"], data_company["price"] ,".-"  )
    plt.xticks(rotation=90)
plt.legend(company)
plt.show()

[深度学习项目] - 时间序列预测 (2)_第1张图片
从简单时序图中,我们可以看到每个公司的上升/下降/持平趋势。 但是因为这是10年的数据,没办法展示短时间内的股价变化情况。因此可以查看更短时间(2年内)的股价变化情况。

###### 阶段性 简单时序图
date_start = "2020-01-01"
date_end = "2021-12-31"

company = df_price[ (df_price["date"]>=date_start) &
                    (df_price["date"]<=date_end)
                        ]["company"].drop_duplicates().tolist()
print(company)
for every_company in company:
    data_company = df_price[  (df_price["company"]==every_company) &
                              (df_price["date"]>=date_start) &
                              (df_price["date"]<=date_end)].sort_values("date")
    plt.plot( data_company["date"], data_company["price"] ,".-"  )
    plt.xticks(rotation=90)
plt.legend(company)
plt.show()

[深度学习项目] - 时间序列预测 (2)_第2张图片
在更短的时间内,我们可以看到股价的尺寸波动情况(噪声)。 另外没有发现明显的周期性。

######## 简单时序图
### 销量
depts = df_sales[ df_sales["store"]==1 ]["dept"].drop_duplicates().tolist()
for every_dept in depts:
    data_dept = df_sales[  (df_sales["store"]==1) &
                           (df_sales["dept"]==every_dept)
                        ].sort_values("week")
    plt.plot( data_dept["week"], data_dept["sales"] ,".-"  )
    plt.xticks(rotation=90)
plt.legend(depts)
plt.title("sales in store 1")
plt.show()

[深度学习项目] - 时间序列预测 (2)_第3张图片

data_sales = df_sales[  (df_sales["store"]==1) & (df_sales["dept"]==1)  ].sort_values("week")
plt.plot( data_sales["week"], data_sales["sales"], ".-" )
plt.xticks(rotation=90)
plt.show()

[深度学习项目] - 时间序列预测 (2)_第4张图片
我们可以看到,门店的每个部门销量是存在明显的周期性的。但是明显的周期性波动 使得销量的长期趋势 展示不够明显。 以及周期性的具体周期数值是多少,也需要进一步统计。另外周期的高峰和低估等数据也需要分析。

季节性时序图

季节时序图用于分析 周期性的一些特征。 在一个周期中,高峰和低估出现的阶段和数值大小。
因为销量的周期就是一年,因此直接按照每年来划分数据,看每年中 销量在每年的不同周的变化。

# 季节性时序图

df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==1) ].sort_values("week")

df_year = df_salse1_1["week"].dt.year.unique().tolist()
df_salse1_1["week_of_year"] = df_salse1_1["week"].dt.weekofyear
df_salse1_1["year"] = df_salse1_1["week"].dt.year

print(df_year)
for every_year in df_year:
    data_year = df_salse1_1[ df_salse1_1["year"] ==every_year ]
    plt.plot( data_year["week_of_year"], data_year["sales"],".-" )
plt.legend( df_year )
plt.show()

[深度学习项目] - 时间序列预测 (2)_第5张图片
可以看到在 第19周 到 43周 都是销售的低谷。 而第8周,第12周,第43周会出现销售的短时间高峰。 而且 第12周的高峰有一定对的错开,说明可能与一些外部因素(过年时间,节气,促销活动等有关,得到一些有影响性的外部变量)。

季节性箱线图

# 季节性箱线图

df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==1) ].sort_values("week")

df_year = df_salse1_1["week"].dt.year.unique().tolist()
df_salse1_1["week_of_year"] = df_salse1_1["week"].dt.weekofyear
data_boxplot = df_salse1_1.groupby( ["week_of_year"] ).agg(list).reset_index()
# print(data_boxplot["sales"].values )
plt.boxplot(  data_boxplot["sales"].values, labels=data_boxplot["week_of_year"].values  )
plt.show()

[深度学习项目] - 时间序列预测 (2)_第6张图片
均值,最大值,最小值,二十五分位数,七十五分位数。

趋势箱线图

# 趋势箱线图
df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==1) ].sort_values("week")
df_salse1_1["year"] = df_salse1_1["week"].dt.year
df_salse1_1["week_of_year"] = df_salse1_1["week"].dt.weekofyear

data_boxplot = df_salse1_1[  (df_salse1_1["week_of_year"]>=19)&
                             (df_salse1_1["week_of_year"]<=43)]

data_boxplot = data_boxplot.groupby( ["year"] )["sales"].agg(list).reset_index()
plt.boxplot( data_boxplot["sales"].values, labels=data_boxplot["year"].values )
plt.show()

[深度学习项目] - 时间序列预测 (2)_第7张图片
我们只使用 第19周到43周的数据,这样子可以反应 销售低估时期,不同年的趋势。

时序的主要成分

[深度学习项目] - 时间序列预测 (2)_第8张图片

statsmodels 安装

statsmodels

周期检验

自相关系数检验(ACF) 【具体内容待查找】
r h = C o r ( X t , X t + h ) , e v e r y   t r_h=Cor(X_t,X_{t+h}),every\ t rh=Cor(Xt,Xt+h),every t

C o r ( X t , X t + h ) = E [ ( X t − μ t ) ( X t + h − μ t + h ) ]   σ ( X t ) σ ( X t + h ) Cor(X_t,X_{t+h})=\frac{E[ (X_t - \mu_{t})(X_{t+h}-\mu_{t+h}) ]}{\ \sigma(X_t)\sigma(X_{t+h}) } Cor(Xt,Xt+h)= σ(Xt)σ(Xt+h)E[(Xtμt)(Xt+hμt+h)]

当我们改变h,用于计算不同的h下 序列 X t X_t Xt与序列 X t + h X_{t+h} Xt+h之间的相关性。 如果在时间T下存在周期性,那么在 T , 2 T , … , n T T,2T,\dots,nT T,2T,,nT下都存在周期性, 都会有较强的相关性系数。

因此,只有 T , 2 T , … , n T T,2T,\dots,nT T,2T,,nT下都存在 较高的 相关性系数,那么才能说明 周期性是T。

# ACF检验
from statsmodels.graphics.tsaplots import plot_acf
df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==1) ].sort_values("week")
plot_acf( df_salse1_1["sales"],lags=140 )
plt.show()

[深度学习项目] - 时间序列预测 (2)_第9张图片

STL算法介绍

STL: “Seasonal and Trend decomposition using Loess”
将时间序列分解成季节性,趋势项,剩余项
剩余项使用线性,非线性回归的方式拆解为 外部变量的影响与残差。

from statsmodels.tsa.seasonal import STL
stl = STL( df_salse1_1["sales"].values, period=52 )
res = stl.fit()
res.plot()
plt.show()

#res.trend
#res.seasonal
#res.residual

[深度学习项目] - 时间序列预测 (2)_第10张图片
我们可以看到,趋势项和之前的 趋势箱线图较为相似; 季节性中的周期性:在年初和年末都是有高峰期,在年中是低谷期。
但是实际上 周期性是由于 外部变量(促销互动等)造成的,实际上也是残差中的一部分。

Homework

[深度学习项目] - 时间序列预测 (2)_第11张图片

简单时序图

data_sales = df_sales[  (df_sales["store"]==1) & (df_sales["dept"]==9)  ].sort_values("week")
plt.plot( data_sales["week"], data_sales["sales"], ".-" )
plt.xticks(rotation=90)
plt.show()

[深度学习项目] - 时间序列预测 (2)_第12张图片

季节时序图

df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==9) ].sort_values("week")

df_year = df_salse1_1["week"].dt.year.unique().tolist()
df_salse1_1["week_of_year"] = df_salse1_1["week"].dt.weekofyear
df_salse1_1["year"] = df_salse1_1["week"].dt.year

# print(df_year)
for every_year in df_year:
    data_year = df_salse1_1[ df_salse1_1["year"] ==every_year ]
    plt.plot( data_year["week_of_year"], data_year["sales"],".-" )
plt.legend( df_year )
plt.show()

[深度学习项目] - 时间序列预测 (2)_第13张图片
可以看到 还是每年会存在 周期性的重叠。 但和1-1有较大的区别。 1-9中每年的起伏波动比较大。第35周至54周每周都波动剧烈。

季节箱线图

df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==9) ].sort_values("week")

df_year = df_salse1_1["week"].dt.year.unique().tolist()
df_salse1_1["week_of_year"] = df_salse1_1["week"].dt.weekofyear
data_boxplot = df_salse1_1.groupby( ["week_of_year"] ).agg(list).reset_index()
# print(data_boxplot["sales"].values )
plt.boxplot(  data_boxplot["sales"].values, labels=data_boxplot["week_of_year"].values  )
plt.xticks(rotation=90)
plt.show()

[深度学习项目] - 时间序列预测 (2)_第14张图片
可以看到 大部分时间的方差较小,说明每年的相同时间差别不是很大;但具体上升还是下降,可以根据 趋势箱线图查看。

趋势箱线图

df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==9) ].sort_values("week")
df_salse1_1["year"] = df_salse1_1["week"].dt.year
df_salse1_1["week_of_year"] = df_salse1_1["week"].dt.weekofyear
data_boxplot = df_salse1_1

data_boxplot = data_boxplot.groupby( ["year"] )["sales"].agg(list).reset_index()
plt.boxplot( data_boxplot["sales"].values, labels=data_boxplot["year"].values )
plt.show()

[深度学习项目] - 时间序列预测 (2)_第15张图片

可以看到 2010年到2011年稍有增长,2012年上涨幅度较大。

ACF查看周期

df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==9) ].sort_values("week")
plot_acf( df_salse1_1["sales"],lags=140 )
plt.show()

[深度学习项目] - 时间序列预测 (2)_第16张图片
从ACF可以看到,每个26周,都会有加大的波动。但是在最后一个时刻130周,ACF较低。同时每半年进行 季节性时序图和箱线图分析,方差较大。 因此认为周期为一年比较恰当。

STL 检测

df_salse1_1 = df_sales[ (df_sales["store"]==1)&
                        (df_sales["dept"]==9) ].sort_values("week")
stl = STL( df_salse1_1["sales"].values, period=52 )
res = stl.fit()
res.plot()
plt.show()

[深度学习项目] - 时间序列预测 (2)_第17张图片
我们可以看到 整体趋势和 趋势箱线图一致。 对于季节性趋势,每年存在周期性。另外每一年内 前半部分趋势较为平缓,后半部分波动较大。
同时根据残差图,我们可以看到 在第二年中 方差波动最大,说明三年中存在 外部变量波动较为剧烈。
同时周期中 存在一些外部变量 影响每年内的变化。

你可能感兴趣的:(项目学习,深度学习,python,pandas)