时序数据分析-1(疫情对销量影响)

时序数据分析-1(疫情对销量影响)

上海已经被封嗯~ o( ̄▽ ̄)o差不多2个多月了,被封在家久了,对个人影响是巨大的,比如将我由一个价格敏感小民生生变成了价格无感客户。当然对业务的影响也是巨大的,毕竟大公司走社区团购还是比较谨慎,正常渠道又卖不了货。近日,就有业务来问能不能稍微定量的评估此次疫情对sales的影响。

答案是positive的,基本思路非常简单,如果我们能通过历史数据推测出这几个月的销量,然后算下和实际销量的差距,就可以得到high level疫情对sales的影响了。

这里就引入一个分析中比较常见的分析类型,对于时序数据的分析预测。时序数据的分析有非常多方向,算法也是多种多样。这里就简单介绍下回答疫情影响用到的两类算法,以及如何用这两类算法测算疫情对销量的影响:

  • 时序数据分解
  • Arima 预测

受制于篇幅,本文就先介绍时序分解部分。

时序数据相关基本概念

什么是时序数据

时序数据,顾名思义就是数据的序列是有意义的,是不能打乱的。例如销售数据,销量随时间变化的,我们做销量预测,表面上是销量随时间变化的拟合,本质是我们在用过去的销量来预测将来的销量。如何通过建模实现对未来销量的拟合,我们自然而然想到的就是regression的方法,拟合一条销量随时间变化的曲线。这里要注意的一点是假如用过去的数据来做自变量,预测未来时间的数据,我们是不能直接用linear regression的算法的,前些年有实习生直接上ols的回归,其实就说明这位童鞋既不了解linear regression的适用场景,也不了解时序数据的特点。linear regression的基本假设之一(详细的关于linear regression的介绍我们以后有机会再介绍)就是样本观测值之间是相互独立的,不相关。但是时序预测,如果是用过去的数据来预测将来,观测值之间是肯定相关的,比如今天口红的销量和昨天口红的销量是正相关的。我们比较熟悉的时序数据的表达可能是: y t = c + Φ 1 y t − 1 + ϕ 2 y t − 2 + . . . + ϕ p y t − p + ϵ t y_t = c + \Phi_1y_{t-1} + \phi_2y_{t-2} + ... + \phi_py_{t-p} + \epsilon_t yt=c+Φ1yt1+ϕ2yt2+...+ϕpytp+ϵt

其中 y t − 1 y_{t-1} yt1是昨天的销量, y t − p y_{t-p} ytp是p天前的销量, ϵ t \epsilon_t ϵt是白噪声,random值

扯个题外话,我们做拟合前,比较好的习惯是排除本身是自相关的变量,或者做些加工处理,将相应变量转化成non-autocorrelation的变量。做完拟合后,也可以看下残差是不是自相关的,如果残差是自相关的,说明数据中有些pattern模型本身没有抓到。如何判断一个变量是不是自相关的呢,统计上有个Durbin Watson test,一般来说当test值在1.5-2.5之间时,我们就认为变量是不相关的,当test值接近于0,则说明变量是负相关关系,当test值接近于4说明变量是正相关关系。

时序数据分解

时序数据分解(timeseries decomposition)基本思想是认为时序数据是由三部分组成,即趋势(trend)、季节性因素(seasonality)、随机噪声。根据数据的特点,时序的分解会有两类:

  • Additive: 趋势、季节性因素和随机噪声加和在一起,组成时序数据。 y t = T t + S t + R t y_t = T_t + S_t + R_t yt=Tt+St+Rt
  • Multiplicative: 趋势、季节性因素和随机噪声相乘组成时序数据。 y t = T t ∗ S t ∗ R t y_t = T_t * S_t * R_t yt=TtStRt

真实生产中我们遇到的数据,比较复杂的情形可能是某一时间段符合Additive的特点,某些时间段符合Multiplicative的特点。Additive和Multiplicative在数据pattern上的区别是我们看seasonality的强度会不会在不同cycle有变化。

时序的分解在数据分析上可以帮助我们了解历史数据的特点,比如季节性因素强不强,本身trend是什么趋势,异常点发生在哪里等。当然也可以将原始数据分解成几部分,对不同的部分分别做预测,最后组合得到整体的时序预测值。

案例介绍

我们是要high level的分析下疫情对销量的影响,解构成模型问题,其实是根据历史销量,测算疫情期间不考虑covid发生,本身销量是多少,与实际发生差值是多少。销量数据一般拿到的是daily的数据,但是daily的数据波动性太大,并且我们不需要输出daily的预测结果,同时考虑到我们能拿到的历史数据时间跨度,我们数据准备的时候就需要把daily的数据向上汇总到weekly的数据。数据预处理的工作有很多,包括处理缺失,因为各种各样的原因,可能原始数据某些周的数据就缺失了,对于时序数据,我们需要连续的序列。我们这里就只展示下daily到weekly的汇总code。当然,这里展示的数据都是mock的

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
from scipy.stats import pearsonr
#显示所有列
pd.set_option('display.max_columns', None)
#显示所有行
pd.set_option('display.max_rows', None)
#设置value的显示长度为100,默认为50
pd.set_option('max_colwidth',100)
import datetime as dt
from statsmodels.tsa.seasonal import STL
import numpy as np
sns.set_style('darkgrid',{'axes.facecolor':'.9'})

数据预处理

将daily的数据group到weekly level.

def week_df(df):
    df_result = df.set_index('business_date').resample('W').apply(
    {
        'city_name':'first',
        'sales_tc':'sum',
        'sales_rns':'sum',
        'newConfirm':'sum',
        'weekofyear':'first'
    }
    )
    return df_result
df_netsales_weekly_ = df_netsales.groupby(by='city_name',as_index=False).apply(week_df)

利用STL将预处理后的数据分解为trend,seasonality,residual

covid_gz = df_gz.set_index('business_date')['newConfirm']
# covid_gz = np.log(covid_gz+0.1)
df_gz_stl = df_gz.set_index('business_date')['sales_tc']
# df_gz_stl = np.log(df_gz_stl+0.1)
stl_gz = STL(df_gz_stl)
result = stl_gz.fit()
seasonal,trend,resid = result.seasonal,result.trend,result.resid
fig = plt.figure(figsize=(15,8))
ax1 = fig.add_subplot(111)
ax1.plot(resid,label='resid')
ax1.legend()
ax2 = ax1.twinx()
ax2.plot(covid_gz,'r',label='covid')
ax2.legend()
plt.title('seasonal+resid vs covid',fontsize=16)

在这里插入图片描述

因为疫情的发生是没有固定pattern的,疫情对销量的影响一定是包含在残差里。上图可以看到,当确诊人数有波峰的时候,销量是骤降的
fig = plt.figure(figsize=(15,18))

plt.subplot(5,1,1)
plt.plot(df_gz_stl,label='original')
plt.plot(trend+seasonal,'r',label='seasonal+trend')
plt.legend()
plt.title('Original Series',fontsize=16)

plt.subplot(5,1,3)
plt.plot(trend)
plt.title('trend',fontsize=16)

# plt.subplot(5,1,3)
# plt.plot(seasonal+resid)
# plt.title('seasonal+resid vs covid',fontsize=16)

plt.subplot(5,1,4)
plt.plot(seasonal)
plt.title('seasonal',fontsize=16)

plt.subplot(5,1,2)
plt.plot(resid)
plt.title('resid',fontsize=16)

fig.tight_layout()#调整整体空白
plt.subplots_adjust(wspace =1, hspace =0.5)#调整子图间距

在这里插入图片描述

上图可以看到三点信息:
  • 残差是不符合高斯分布的,说明里面由信息没有被模型捕捉到。也说明如果要精确预测销量的话,需要对残差进一步分析。
  • trend可以看到趋势是比较明显的,按照我们对问题的分解,其实下一步就是对trend本身进行进一步的预测。
  • seasonality的话可以看到,基本是以年为周期,变化是比较固定的。
上面两个分析,其实可以支撑我们的假设了,疫情对销量的影响是包含在残差中的,我们其实要看疫情没发生时的销量,可以将trend通过模型进行预测,然后叠加seasonality的影响来实现。
下次再分享下trend的预测怎么实现
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Prometheus时序数据库提供了强大的Promql查询语言来满足我们的查询需求。在查询数据之前,我们需要先插入数据到Prometheus中。在之前的博客中,详细介绍了Prometheus数据的插入过程\[1\]。而在查询数据时,我们可以使用Promql来进行查询。Promql是一种灵活的查询语言,可以根据我们的需求进行千变万化的查询\[2\]。 在进行查询时,Prometheus会根据指定的时间窗口来过滤数据,默认的时间窗口是5分钟,可以通过启动参数来进行设置\[3\]。这样可以确保我们只获取到指定时间范围内的数据,而不会包含过去或未来的数据。 总结来说,Prometheus时序数据库通过Promql查询语言来满足我们的查询需求,并通过时间窗口来过滤数据,确保我们获取到的数据符合我们的要求。 #### 引用[.reference_title] - *1* [Prometheus时序数据库-数据的查询](https://blog.csdn.net/weixin_55416758/article/details/115350199)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Prometheus时序数据库-报警的计算 及 Prometheus时序数据库-数据的查询](https://blog.csdn.net/m0_67322837/article/details/125004715)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值