【時(shí)間序列】時(shí)間序列建模的時(shí)間戳與時(shí)序特征衍生思路
特征錦囊:時(shí)間序列建模的時(shí)間戳與時(shí)序特征衍生思路
時(shí)間序列模型在我們?nèi)粘9ぷ髦袘?yīng)用的場(chǎng)景還是會(huì)很多的,比如我們?nèi)ヮA(yù)測(cè)未來的銷售單量、預(yù)測(cè)股票價(jià)格、預(yù)測(cè)期貨走勢(shì)、預(yù)測(cè)酒店入住等等,這也是我們必須要掌握時(shí)序建模的原因。而關(guān)于時(shí)間戳以及時(shí)序值的特征衍生,在建模過程中起到的作用是十分巨大的!之前寫過一篇關(guān)于日期特征操作的文章——《關(guān)于日期特征,你想知道操作都在這兒~》,可以先回顧下,里面有關(guān)于日期特征的基礎(chǔ)操作手法。
?? Index
01 時(shí)間序列數(shù)據(jù)類別簡(jiǎn)介
02 時(shí)間戳的衍生思路
03 時(shí)間戳的衍生代碼分享
04 時(shí)序值的衍生思路
05 時(shí)序值的衍生代碼分享
?? 01 時(shí)間序列數(shù)據(jù)類別簡(jiǎn)介
我們就拿經(jīng)典的時(shí)間序列模型來說一下,一般來說數(shù)據(jù)集里的數(shù)據(jù),可以分為3大類。
1)Y值:我們也稱之為時(shí)序值。如下表中的銷量字段;
2)時(shí)間戳:標(biāo)記本條記錄發(fā)生時(shí)間的字段,如下表中的統(tǒng)計(jì)日期字段。oh,對(duì)了如果不是單時(shí)間序列的,比如數(shù)據(jù)集中記錄的是多家店鋪的時(shí)序數(shù)據(jù),需要結(jié)合序列屬性信息,比如店鋪名稱、店鋪所在城市;
3)其他字段:顧名思義。
而我們今天關(guān)注的是時(shí)間戳和時(shí)序值的特征衍生。
?? 02 時(shí)間戳的衍生思路
雖然時(shí)間戳就只有1個(gè)字段,但里面其實(shí)包含的信息量還是很多的,一般來說我們可以從下面幾個(gè)角度來拆解,衍生出一系列的變量。
1)時(shí)間戳本身特征
直接使用Pandas的series提取時(shí)間戳特征,比如說哪年、哪季度、哪月、哪周、哪日、哪時(shí)、哪分、哪秒、年里的第幾天、月里的第幾天、周里的第幾天。
2)0-1特征
一般是與真實(shí)場(chǎng)景結(jié)合來用,比如說工作日、周末、公眾假日(春節(jié)、端午節(jié)、中秋節(jié)等)、X初、X中、X末(X代表年、季度、月、周)、特殊節(jié)日(如運(yùn)營(yíng)暫停、服務(wù)暫停)、日常習(xí)慣叫法(如清晨、上午、中午、下午、傍晚、夜晚、深夜、凌晨),從而可以衍生出:
是否工作日 是否春節(jié) 是否月初 是否服務(wù)期外 是否凌晨 等等等等
3)時(shí)間差特征
一般也是與真實(shí)場(chǎng)景結(jié)合來用,比如說工作日、周末等等,比如:
距離春節(jié)還有N天 距離周末還有N天 舉例下月初還有N天 等等等等
?? 03 時(shí)間戳的衍生代碼分享
首先我們捏造一些數(shù)據(jù),用來測(cè)試代碼。
#?導(dǎo)入相關(guān)庫包
import?pandas?as?pd
import?numpy?as?np
import?datetime
import?time
import?random
from?calendar?import?monthrange?
#?捏造數(shù)據(jù)
df?=?pd.DataFrame(
??????[['零售店01',?'2021-10-01',?'2021-10-01?11:47:34',?'1993-11-03',?'深圳',?100],
???????['零售店01',?'2021-10-02',?'2021-10-02?12:47:34',?'1993-11-04',?'深圳',?120],
???????['零售店01',?'2021-10-03',?'2021-10-03?11:47:34',?'1993-10-03',?'深圳',?140],
???????['零售店01',?'2021-10-04',?'2021-10-04?08:47:34',?'1993-02-03',?'深圳',?170],
???????['零售店01',?'2021-10-05',?'2021-10-05?11:47:34',?'1993-02-03',?'深圳',?190],
???????['零售店01',?'2021-10-06',?'2021-10-06?15:47:34',?'1993-04-03',?'深圳',?10],
???????['零售店01',?'2021-10-07',?'2021-10-07?17:47:34',?'1993-02-03',?'深圳',?20],
???????['零售店01',?'2021-10-08',?'2021-10-08?19:47:34',?'1993-06-03',?'深圳',?420],
???????['零售店01',?'2021-10-09',?'2021-10-09?11:47:34',?'1993-03-03',?'深圳',?230],
???????['零售店01',?'2021-10-10',?'2021-10-10?20:47:34',?'1993-02-20',?'深圳',?80]
??????]
??????,columns=['店鋪名稱',?'統(tǒng)計(jì)日期',?'大促開始時(shí)間',?'店長(zhǎng)出生日期',?'店鋪所在城市',?'銷量'])
df.head()

1)時(shí)間戳本身特征
這個(gè)就是提取datetime本身的實(shí)體特征,利用Pandas的Series方法即可。
#?原先屬于字符串,轉(zhuǎn)datetime
df['datetime64']?=?pd.to_datetime(df['統(tǒng)計(jì)日期'])
df['year']?=?df['datetime64'].dt.year
df['quarter']?=?df['datetime64'].dt.quarter
df['month']?=?df['datetime64'].dt.month
df['week']?=?df['datetime64'].dt.week
df['day']?=?df['datetime64'].dt.day
df['hour']?=?df['datetime64'].dt.hour
df['minute']?=?df['datetime64'].dt.minute
df['second']?=?df['datetime64'].dt.second
df['weekday']?=?df['datetime64'].dt.weekday
df['weekofyear']?=?df['datetime64'].dt.weekofyear
df['dayofyear']?=?df['datetime64'].dt.dayofyear
df['dayofweek']?=?df['datetime64'].dt.dayofweek
2)0-1特征
這里我們需要引入一些關(guān)于真實(shí)場(chǎng)景的日期來結(jié)合著判斷是否。
df['is_work_day']?=?np.where(df['dayofweek'].isin([5,6]),?0,?1)?#?是否工作日
df['is_month_start']?=?np.where(df['datetime64'].dt.is_month_start,?1,?0)
df['is_month_end']?=?np.where(df['datetime64'].dt.is_month_end,?1,?0)
#?特殊日子/公眾假日
special_day?=?['2021-10-01','2021-10-02']
df['is_special_day']?=?np.where(df['統(tǒng)計(jì)日期'].isin(special_day),?1,?0)
#?是否凌晨
df['is_before_dawn']?=?np.where(df['hour'].isin([0,1,2,3]),?1,?0)
3)時(shí)間差特征
#?獲取前一天日期
df['yesterday']?=?df['datetime64']?-?datetime.timedelta(days=1)
#?日期差計(jì)算(天)
df['day_dif']?=?(df['datetime64']?-?df['yesterday']).dt.days
#?日期差計(jì)算(小時(shí))
df['hour_dif']?=?(df['datetime64']?-?df['yesterday']).values/np.timedelta64(1,?'h')?#?換成?D?則為?天

?? 04 時(shí)序值的衍生思路
本例中的時(shí)序值是銷量字段,一般我們?cè)趯?duì)時(shí)序值進(jìn)行操作前,需要對(duì)數(shù)據(jù)的時(shí)序進(jìn)行排序和補(bǔ)全,然后才開始操作,時(shí)序值的特征衍生主要有幾個(gè)角度。
1)時(shí)間滑動(dòng)窗口統(tǒng)計(jì)
基于某段時(shí)間窗,統(tǒng)計(jì)數(shù)據(jù)情況,也叫做Rolling Window Statistics,統(tǒng)計(jì)的方式一般有min/max/mean/median/std/sum等,比如我們選擇滑動(dòng)窗口為7天,那么可以衍生的變量分別是:過去7天內(nèi)銷量最小值/最大值/均值/中位數(shù)/方差/之和。
在使用此類特征的時(shí)候,要注意一下多步預(yù)測(cè)的問題。
2)lag滯后值
lag可以理解為向前滑動(dòng)時(shí)間,比如lag1表示向前滑動(dòng)1天,即取T-1的時(shí)序值作為當(dāng)前時(shí)序的變量。
?? 05 時(shí)序值的衍生代碼分享
1)時(shí)間滑動(dòng)窗口統(tǒng)計(jì)
因?yàn)榉椒ń凶?code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">Rolling Window Statistics,所以代碼里關(guān)于這塊的實(shí)現(xiàn)也有1個(gè)叫rolling的方法,這個(gè)方法在時(shí)序建模中很好用,后面單獨(dú)一篇文章講下。
df?=?df.loc[:,['店鋪名稱',?'統(tǒng)計(jì)日期','銷量']]
df['date']?=?pd.to_datetime(df['統(tǒng)計(jì)日期'])
#?時(shí)序值特征衍生前記得排序
df.sort_values(['店鋪名稱',?'統(tǒng)計(jì)日期'],?ascending=[True,True],?inplace=True)
#?衍生時(shí)間滑動(dòng)窗口統(tǒng)計(jì)變量
f_min?=?lambda?x:?x.rolling(window=3,?min_periods=1).min()
f_max?=?lambda?x:?x.rolling(window=3,?min_periods=1).max()
f_mean?=?lambda?x:?x.rolling(window=3,?min_periods=1).mean()
f_std?=?lambda?x:?x.rolling(window=3,?min_periods=1).std()
f_median=lambda?x:?x.rolling(window=3,?min_periods=1).median()
function_list?=?[f_min,?f_max,?f_mean,?f_std,f_median]
function_name?=?['min',?'max',?'mean',?'std','median']
for?i?in?range(len(function_list)):
????df[('stat_%s'?%?function_name[i])]?=?df.sort_values('統(tǒng)計(jì)日期',?ascending=True).groupby(['店鋪名稱'])['銷量'].apply(function_list[i])
2)lag滯后值
#?衍生lag變量
for?i?in?[1,2,3]:
????df["lag_{}".format(i)]?=?df['銷量'].shift(i)

?? Reference
[1] 一度讓我懷疑人生的時(shí)間戳特征處理技巧。
https://mp.weixin.qq.com/s/dUdGhWY8l77f1TiPsnjMQA
[2] 時(shí)間序列樹模型特征工程匯總
https://blog.csdn.net/fitzgerald0/article/details/104029842
[3] 時(shí)間序列的多步預(yù)測(cè)方法總結(jié)
https://zhuanlan.zhihu.com/p/390093091
[4] 時(shí)間序列數(shù)據(jù)的特征工程總結(jié)
https://zhuanlan.zhihu.com/p/388551117
[5] Pandas Series dt
https://pandas.pydata.org/docs/reference/api/pandas.Series.dt.date.html
往期精彩回顧
