91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

時間序列分析和預(yù)測基礎(chǔ)理論知識

數(shù)據(jù)分析與開發(fā) ? 來源:機器學習研習院 ? 作者:小猴子 ? 2022-03-16 14:05 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

今天給大家?guī)硪黄獙崙?zhàn)案例,本案例旨在運用之前學習的時間序列分析和預(yù)測基礎(chǔ)理論知識,用一個基于交通數(shù)據(jù)的實際案例數(shù)據(jù)演示這些方法是如何被應(yīng)用的。

本文主要內(nèi)容

★ 首先使用探索性數(shù)據(jù)分析,從不同時間維度探索分析交通系統(tǒng)乘客數(shù)量。

★ 創(chuàng)建一個函數(shù)來檢查時間序列數(shù)據(jù)的平穩(wěn)性,通過一階差分將非平穩(wěn)性數(shù)據(jù)轉(zhuǎn)化為平穩(wěn)性數(shù)據(jù)。

★ 然后將數(shù)據(jù)分為訓(xùn)練集和驗證集,簡單介紹了并應(yīng)用多個時間序列預(yù)測技術(shù),如樸素法、移動平均方法、簡單指數(shù)平滑、霍爾特線性趨勢法、霍爾特-溫特法、ARIMA和SARIMAX模型。

★ 最后使用SARIMAX模型預(yù)測未來7個月的流量,因為它有最小的RMSE。如下圖所示,藍色線是訓(xùn)練數(shù)據(jù),黃色線是驗證數(shù)據(jù),紅色是使用SARIMAX模型預(yù)測的數(shù)據(jù)。

8e6ef822-a3e7-11ec-952b-dac502259ad0.png

雖然擬合最好的SARIMAX模型,但似乎也沒那么棒,當然會有更好的方法來預(yù)測該數(shù)據(jù)。而本文重點是介紹這些基于統(tǒng)計學的經(jīng)典時間序列預(yù)測技術(shù)在實際案例中的應(yīng)用。

8e811d36-a3e7-11ec-952b-dac502259ad0.png

導(dǎo)入相關(guān)模塊

importpandasaspd
importnumpyasnp
importmatplotlib.pyplotasplt
fromdatetimeimportdatetime
frompandasimportSeries
fromsklearn.metricsimportmean_squared_error
frommathimportsqrt
fromstatsmodels.tsa.seasonalimportseasonal_decompose
importstatsmodels
importstatsmodels.apiassm
fromstatsmodels.tsa.arima_modelimportARIMA

數(shù)據(jù)集準備

去直接讀取用pandas讀取csv文本文件,并拷貝一份以備用。

train=pd.read_csv("Train.csv")
test=pd.read_csv("Test.csv")

train_org=train.copy()
test_org=test.copy()

查看數(shù)據(jù)的列名

train.columns,test.columns
(Index(['ID', 'Datetime', 'Count'], dtype='object'),
 Index(['ID', 'Datetime'], dtype='object'))

查看數(shù)據(jù)類型

train.dtypes,test.dtypes
(ID           int64
 Datetime    object
 Count        int64
 dtype: object,
 ID           int64
 Datetime    object
 dtype: object)

查看數(shù)據(jù)大小

test.shape,train.shape
((5112, 2), (18288, 3))

查看數(shù)據(jù)樣貌

train.head()
8ee61df8-a3e7-11ec-952b-dac502259ad0.png

解析日期格式

train['Datetime']=pd.to_datetime(train.Datetime,format='%d-%m-%Y%H:%M')
test['Datetime']=pd.to_datetime(test.Datetime,format='%d-%m-%Y%H:%M')
test_org['Datetime']=pd.to_datetime(test_org.Datetime,format='%d-%m-%Y%H:%M')
train_org['Datetime']=pd.to_datetime(train_org.Datetime,format='%d-%m-%Y%H:%M')

時間日期格式解析結(jié)束后,記得查看下結(jié)果。

train.dtypes
ID                   int64
Datetime    datetime64[ns]
Count                int64
dtype: object
train.head()
8efc8ec6-a3e7-11ec-952b-dac502259ad0.png

時間序列數(shù)據(jù)的特征工程

時間序列的特征工程一般可以分為以下幾類。本次案例我們根據(jù)實際情況,選用時間戳衍生時間特征。

8f1368da-a3e7-11ec-952b-dac502259ad0.png

時間戳雖然只有一列,但是也可以根據(jù)這個就衍生出很多很多變量了,具體可以分為三大類:時間特征、布爾特征,時間差特征。

本案例首先對日期時間進行時間特征處理,而時間特征包括年、季度、月、周、天(一年、一月、一周的第幾天)、小時、分鐘...

因為需要對test, train, test_org, train_org四個數(shù)據(jù)框進行同樣的處理,直接使用for循環(huán)批量提取年月日小時等特征。

foriin(test,train,test_org,train_org):
i['Year']=i.Datetime.dt.year
i['Month']=i.Datetime.dt.month
i['day']=i.Datetime.dt.day
i['Hour']=i.Datetime.dt.hour
#i["dayoftheweek"]=i.Datetime.dt.dayofweek
test.head()
8f320538-a3e7-11ec-952b-dac502259ad0.png

時間戳衍生中,另一常用的方法為布爾特征,即:

是否年初/年末

是否月初/月末

是否周末

是否節(jié)假日

是否特殊日期

是否早上/中午/晚上

等等

下面判斷是否是周末,進行特征衍生的布爾特征轉(zhuǎn)換。首先提取出日期時間的星期幾。

train['dayoftheweek']=train.Datetime.dt.dayofweek
#返回給定日期時間的星期幾
train.head()
8f50c914-a3e7-11ec-952b-dac502259ad0.png

再判斷day of the week是否是周末(星期六和星期日),是則返回1 ,否則返回0

defapplyer(row):
ifrow.dayofweek==5orrow.dayofweek==6:
return1
else:
return0
temp=train['Datetime']
temp2=train.Datetime.apply(applyer)
train['weekend']=temp2
train.index=train['Datetime']

對年月乘客總數(shù)統(tǒng)計后可視化,看看總體變化趨勢。

df=train.drop('ID',1)
ts=df['Count']
plt.plot(ts,label='Passengercount')

8f66c5e8-a3e7-11ec-952b-dac502259ad0.png

探索性數(shù)據(jù)分析

首先使用探索性數(shù)據(jù)分析,從不同時間維度探索分析交通系統(tǒng)乘客數(shù)量。

對年進行聚合,求所有數(shù)據(jù)中按年計算的每日平均客流量,從圖中可以看出,隨著時間的增長,每日平均客流量增長迅速。

train.groupby('Year')['Count'].mean().plot.bar()
8fae5d22-a3e7-11ec-952b-dac502259ad0.png

對月份進行聚合,求所有數(shù)據(jù)中按月計算的每日平均客流量,從圖中可以看出,春夏季客流量每月攀升,而秋冬季客流量驟減。

train.groupby('Month')['Count'].mean().plot.bar()
8fd031e0-a3e7-11ec-952b-dac502259ad0.png

年月

對年月份進行聚合,求所有數(shù)據(jù)中按年月計算的每日平均客流量,從圖可知道,幾本是按照平滑指數(shù)上升的趨勢。

temp=train.groupby(['Year','Month'])['Count'].mean()
temp.plot()#乘客人數(shù)(每月)
8feac4a6-a3e7-11ec-952b-dac502259ad0.png

對日進行聚合,求所有數(shù)據(jù)中每月中的每日平均客流量。從圖中可大致看出,在5、11、24分別出現(xiàn)三個峰值,該峰值代表了上中旬的高峰期。

train.groupby('day')['Count'].mean(
).plot.bar(figsize=(15,5))
9006a428-a3e7-11ec-952b-dac502259ad0.png

小時

對小時進行聚合,求所有數(shù)據(jù)中一天內(nèi)按小時計算的平均客流量,得到了在中(12)晚(19)分別出現(xiàn)兩個峰值,該峰值代表了每日的高峰期。

train.groupby('Hour')['Count'].mean().plot.bar()
901769d4-a3e7-11ec-952b-dac502259ad0.png

是否周末

對是否是周末進行聚合,求所有數(shù)據(jù)中按是否周末計算的平均客流量,發(fā)現(xiàn)工作日比周末客流量客流量多近一倍,果然大家都是周末都喜歡宅在家里。

train.groupby('weekend')['Count'].mean().plot.bar()
90344478-a3e7-11ec-952b-dac502259ad0.png

對星期進行聚合統(tǒng)計,求所有數(shù)據(jù)中按是周計算的平均客流量。

train.groupby('dayoftheweek')['Count'].mean().plot.bar()
9041e830-a3e7-11ec-952b-dac502259ad0.png

時間重采樣

重采樣(resampling)指的是將時間序列從一個頻率轉(zhuǎn)換到另一個頻率的處理過程;
◎ 將高頻率數(shù)據(jù)聚合到低頻率稱為降采樣(downsampling);
◎ 將低頻率數(shù)據(jù)轉(zhuǎn)換到高頻率則稱為升采樣(unsampling);

train.head()
9063722a-a3e7-11ec-952b-dac502259ad0.png

Pandas中的resample,重新采樣,是對原樣本重新處理的一個方法,是一個對常規(guī)時間序列數(shù)據(jù)重新采樣和頻率轉(zhuǎn)換的便捷的方法。

Resample方法的主要參數(shù),如需要了解詳情,可以戳這里了解更多。

參數(shù) 說明
freq 表示重采樣頻率,例如'M'、'5min'、Second(15)
how='mean' 用于產(chǎn)生聚合值的函數(shù)名或數(shù)組函數(shù),例如'mean'、'ohlc'、np.max等,默認是'mean',其他常用的值由:'first'、'last'、'median'、'max'、'min'
axis=0 默認是縱軸,橫軸設(shè)置axis=1

接下來對訓(xùn)練數(shù)據(jù)進行對月、周、日及小時多重采樣。其實我們分月份進行采樣,然后求月內(nèi)的均值。事實上重采樣,就相當于groupby,只不過是根據(jù)月份這個period進行分組。

train=train.drop('ID',1)
train.timestamp=pd.to_datetime(train.Datetime,format='%d-%m-%Y%H:%M')
train.index=train.timestamp

#每小時的時間序列
hourly=train.resample('H').mean()
#換算成日平均值
daily=train.resample('D').mean()
#換算成周平均值
weekly=train.resample('W').mean()
#換算成月平均值
monthly=train.resample('M').mean()

重采樣后對其進行可視化,直觀地看看其變化趨勢。

90728954-a3e7-11ec-952b-dac502259ad0.png

對測試數(shù)據(jù)也進行相同的時間重采樣處理。

test.Timestamp=pd.to_datetime(test.Datetime,format='%d-%m-%Y%H:%M')
test.index=test.Timestamp
#換算成日平均值
test=test.resample('D').mean()
train.Timestamp=pd.to_datetime(train.Datetime,format='%d-%m-%Y%H:%M')
train.index=train.Timestamp

#C換算成日平均值
train=train.resample('D').mean()

劃分訓(xùn)練集和驗證集

到目前為止,我們有訓(xùn)練集和測試集,實際上,我們還需要一個驗證集,用來實時驗證和調(diào)整訓(xùn)練模型。下面直接用索引切片的方式做處理。

Train=train.loc['2012-08-25':'2014-06-24']
valid=train['2014-06-25':'2014-09-25']

劃分好數(shù)據(jù)集后,繪制折線圖將訓(xùn)練集和驗證集進行可視化。

9088ae00-a3e7-11ec-952b-dac502259ad0.png

模型建立

數(shù)據(jù)準備好了,就到了模型建立階段,這里我們應(yīng)用多個時間序列預(yù)測技術(shù),如樸素法、移動平均方法、簡單指數(shù)平滑、霍爾特線性趨勢法、霍爾特-溫特法、ARIMA和SARIMAX模型。

樸素預(yù)測法

如果數(shù)據(jù)集在一段時間內(nèi)都很穩(wěn)定,我們想預(yù)測第二天的價格,可以取前面一天的價格,預(yù)測第二天的值。這種假設(shè)第一個預(yù)測點和上一個觀察點相等的預(yù)測方法就叫樸素預(yù)測法(Naive Forecast),即。

因為樸素預(yù)測法用最近的觀測值作為預(yù)測值,因此他最簡單的預(yù)測方法。雖然樸素預(yù)測法并不是一個很好的預(yù)測方法,但是它可以為其他預(yù)測方法提供一個基準。

dd=np.asarray(Train.Count)
#將結(jié)構(gòu)數(shù)據(jù)轉(zhuǎn)化為ndarray
y_hat=valid.copy()
y_hat['naive']=dd[len(dd)-1]
plt.plot(Train.index,Train['Count'],label='Train')
plt.plot(valid.index,valid['Count'],label='Valid')
plt.plot(y_hat.index,y_hat['naive'],label='NaiveForecast')
90c604bc-a3e7-11ec-952b-dac502259ad0.png

模型評價

用RMSE檢驗樸素法的的準確率

rms=sqrt(mean_squared_error(valid.Count,y_hat.naive))
print(rms)
111.79050467496724

移動平均值法

移動平均法也叫滑動平均法,取前面n個點的平均值作為預(yù)測值。

計算移動平均值涉及到一個有時被稱為"滑動窗口"的大小值。使用簡單的移動平均模型,我們可以根據(jù)之前數(shù)值的固定有限數(shù)的平均值預(yù)測某個時序中的下一個值。利用一個簡單的移動平均模型,我們預(yù)測一個時間序列中的下一個值是基于先前值的固定有限個數(shù)“p”的平均值。

這樣,對于所有的

#最近10次觀測的移動平均值,即滑動窗口大小為P=10
y_hat_avg=valid.copy()
y_hat_avg['moving_avg_forecast']=Train['Count'].rolling(10).mean().iloc[-1]

#最近20次觀測的移動平均值
y_hat_avg=valid.copy()
y_hat_avg['moving_avg_forecast']=Train['Count'].rolling(20).mean().iloc[-1]

#最近30次觀測的移動平均值
y_hat_avg=valid.copy()
y_hat_avg['moving_avg_forecast']=Train['Count'].rolling(50).mean().iloc[-1]
plt.plot(Train['Count'],label='Train')
plt.plot(valid['Count'],label='Valid')
plt.plot(y_hat_avg['moving_avg_forecast'],
label='MovingAverageForecastusing50observations')
90e1cd3c-a3e7-11ec-952b-dac502259ad0.png90f81f6a-a3e7-11ec-952b-dac502259ad0.png911e9f78-a3e7-11ec-952b-dac502259ad0.png

簡單指數(shù)平滑法

介紹這個之前,需要知道什么是簡單平均法(Simple Average),該方法預(yù)測的期望值等于所有先前觀測點的平均值。

物品價格會隨機上漲和下跌,平均價格會保持一致。我們經(jīng)常會遇到一些數(shù)據(jù)集,雖然在一定時期內(nèi)出現(xiàn)小幅變動,但每個時間段的平均值確實保持不變。這種情況下,我們可以認為第二天的價格大致和過去的平均價格值一致。

簡單平均法和加權(quán)移動平均法在選取時間點的思路上存在較大的差異:

簡單平均法將過去數(shù)據(jù)一個不漏地全部加以同等利用;

移動平均法則不考慮較遠期的數(shù)據(jù),并在加權(quán)移動平均法中給予近期更大的權(quán)重。

我們就需要在這兩種方法之間取一個折中的方法,在將所有數(shù)據(jù)考慮在內(nèi)的同時也能給數(shù)據(jù)賦予不同非權(quán)重。

簡單指數(shù)平滑法 (Simple Exponential Smoothing)相比更早時期內(nèi)的觀測值,越近的觀測值會被賦予更大的權(quán)重,而時間越久遠的權(quán)重越小。它通過加權(quán)平均值計算出預(yù)測值,其中權(quán)重隨著觀測值從早期到晚期的變化呈指數(shù)級下降,最小的權(quán)重和最早的觀測值相關(guān):

其中是平滑參數(shù)。

fromstatsmodels.tsa.apiimportExponentialSmoothing,SimpleExpSmoothing,Holt
y_hat_avg=valid.copy()
fit2=SimpleExpSmoothing(np.asarray(Train['Count'])).fit(smoothing_level=0.6,optimized=False)
y_hat_avg['SES']=fit2.forecast(len(valid))
plt.figure(figsize=(16,8))
plt.plot(Train['Count'],label='Train')
plt.plot(valid['Count'],label='Valid')
plt.plot(y_hat_avg['SES'],label='SES')
plt.legend(loc='best')
plt.show()
91301258-a3e7-11ec-952b-dac502259ad0.png

模型評價

用RMSE檢驗樸素法的的準確率

rms=sqrt(mean_squared_error(valid.Count,y_hat_avg.SES))
print(rms)
113.43708111884514

霍爾特線性趨勢法

Holts線性趨勢模型,該方法考慮了數(shù)據(jù)集的趨勢,即序列的增加或減少性質(zhì)。

盡管這些方法中的每一種都可以應(yīng)用趨勢:簡單平均法會假設(shè)最后兩點之間的趨勢保持不變,或者我們可以平均所有點之間的所有斜率以獲得平均趨勢,使用移動趨勢平均值或應(yīng)用指數(shù)平滑。但我們需要一種無需任何假設(shè)就能準確繪制趨勢圖的方法。這種考慮數(shù)據(jù)集趨勢的方法稱為霍爾特線性趨勢法,或者霍爾特指數(shù)平滑法。

y_hat_avg=valid.copy()
fit1=Holt(np.asarray(Train['Count'])
).fit(smoothing_level=0.3,smoothing_slope=0.1)
y_hat_avg['Holt_linear']=fit1.forecast(len(valid))

plt.plot(Train['Count'],label='Train')
plt.plot(valid['Count'],label='Valid')
plt.plot(y_hat_avg['Holt_linear'],label='Holt_linear')

9153734c-a3e7-11ec-952b-dac502259ad0.png

模型評價

用RMSE檢驗樸素法的的準確率

rms=sqrt(mean_squared_error(valid.Count,y_hat_avg.Holt_linear))
print(rms)
112.94278345314041

由于holts線性趨勢,到目前為止具有最好的準確性,我們嘗試使用它來預(yù)測測試數(shù)據(jù)集。

predict=fit1.forecast(len(test))
test['prediction']=predict
#計算每小時計數(shù)的比率
train_org['ratio']=train_org['Count']/train_org['Count'].sum()
#按小時計數(shù)分組
temp=train_org.groupby(['Hour'])['ratio'].sum()
#保存聚合后的數(shù)據(jù)
pd.DataFrame(temp,columns=['ratio']).to_csv('GROUPBY.csv')

temp2=pd.read_csv('GROUPBY.csv')
#按日、月、年合并test和test_org
merge=pd.merge(test,test_org,on=('day','Month','Year'),how='left')
merge['Hour']=merge['Hour_y']
merge['ID']=merge['ID_y']
merge.head()
9167badc-a3e7-11ec-952b-dac502259ad0.png

刪除不需要的特征。

merge=merge.drop(['Year','Month','Datetime','Hour_x','Hour_y','ID_x','ID_y'],axis=1)
merge.head()
91784d7a-a3e7-11ec-952b-dac502259ad0.png

通過合并merge和temp2進行預(yù)測。

prediction=pd.merge(merge,temp2,on='Hour',how='left')
#將比率轉(zhuǎn)換成原始比例
prediction['Count']=prediction['prediction']*prediction['ratio']*24
submission=prediction
pd.DataFrame(submission,columns=['ID','Count']).to_csv('Holt_Linear.csv')
918eeb84-a3e7-11ec-952b-dac502259ad0.png

霍爾特-溫特法

霍爾特-溫特(Holt-Winters)方法,在 Holt模型基礎(chǔ)上引入了 Winters 周期項(也叫做季節(jié)項),可以用來處理月度數(shù)據(jù)(周期 12)、季度數(shù)據(jù)(周期 4)、星期數(shù)據(jù)(周期 7)等時間序列中的固定周期的波動行為。引入多個 Winters 項還可以處理多種周期并存的情況。

#HoltsWintermodel
y_hat_avg=valid.copy()
fit1=ExponentialSmoothing(np.asarray(Train['Count']),seasonal_periods=7,trend='add',seasonal='add',).fit()
y_hat_avg['Holts_Winter']=fit1.forecast(len(valid))
plt.plot(Train['Count'],label='Train')
plt.plot(valid['Count'],label='Valid')
plt.plot(y_hat_avg['Holts_Winter'],label='Holt_Winter')

91a226ae-a3e7-11ec-952b-dac502259ad0.png

模型評價

用RMSE檢驗樸素法的的準確率

rms=sqrt(mean_squared_error(valid.Count,y_hat_avg.Holts_Winter))
print(rms)
82.37292653831038

模型預(yù)測

predict=fit1.forecast(len(test))
test['prediction']=predict
#按日、月、年合并Test和test_original
merge=pd.merge(test,test_org,on=('day','Month','Year'),how='left')
merge['Hour']=merge['Hour_y']
merge=merge.drop(['Year','Month','Datetime','Hour_x','Hour_y'],axis=1)
#通過合并merge和temp2進行預(yù)測
prediction=pd.merge(merge,temp2,on='Hour',how='left')
#將比率轉(zhuǎn)換成原始比例
prediction['Count']=prediction['prediction']*prediction['ratio']*24
prediction['ID']=prediction['ID_y']
submission=prediction.drop(['day','Hour','ratio','prediction','ID_x','ID_y'],axis=1)
#轉(zhuǎn)換最終提交的csv格式
pd.DataFrame(submission,columns=['ID','Count']).to_csv('Holtwinters.csv')
91b6f2b4-a3e7-11ec-952b-dac502259ad0.png

迪基-福勒檢驗

函數(shù)執(zhí)行迪基-福勒檢驗以確定數(shù)據(jù)是否為平穩(wěn)時間序列。

在統(tǒng)計學里,迪基-福勒檢驗(Dickey-Fuller test)可以測試一個自回歸模型是否存在單位根(unit root)?;貧w模型可以寫為,是一階差分。測試是否存在單位根等同于測試是否。

因為迪基-福勒檢驗測試的是殘差項,并非原始數(shù)據(jù),所以不能用標準t統(tǒng)計量。我們需要用迪基-福勒統(tǒng)計量。

fromstatsmodels.tsa.stattoolsimportadfuller
deftest_stationary(timeseries):
#確定滾動數(shù)據(jù)
rolmean=timeseries.rolling(24).mean()
rolstd=timeseries.rolling(24).std()

#會議滾動數(shù)據(jù)
orig=plt.plot(timeseries,color='blue',label='Original')
mean=plt.plot(rolmean,color='red',label='RollingMean')
std=plt.plot(rolstd,color='black',label='RollingStd')
plt.legend(loc='best')
plt.title('RollingMean&StandardDeviation')
plt.show(block=False)

#執(zhí)行迪基-福勒檢驗
print('ResultsofDickey-FullerTest:')
dftest=adfuller(timeseries,autolag='AIC')
dfoutput=pd.Series(dftest[0:4],index=['TestStatistic','P-value','#lagsused','NoofObservationsused'])
forkey,valueindftest[4].items():
dfoutput['CriticalValue(%s)'%key]=value
print(dfoutput)

繪制檢驗圖

test_stationary(train_org['Count'])
91ca66be-a3e7-11ec-952b-dac502259ad0.png
Results of Dickey-Fuller Test: 
Test Statistic                -4.456561
P-value                        0.000235
#lags used                    45.000000
No of Observations used    18242.000000
Critical Value (1%)           -3.430709
Critical Value (5%)           -2.861698
Critical Value (10%)          -2.566854
dtype: float64

檢驗統(tǒng)計數(shù)據(jù)表明,由于p值小于0.05,數(shù)據(jù)是平穩(wěn)的。

移動平均值

在統(tǒng)計學中,移動平均(moving average),又稱滑動平均是一種通過創(chuàng)建整個數(shù)據(jù)集中不同子集的一系列平均數(shù)來分析數(shù)據(jù)點的計算方法。移動平均通常與時間序列數(shù)據(jù)一起使用,以消除短期波動,突出長期趨勢或周期。

對原始數(shù)據(jù)求對數(shù)。

Train_log=np.log(Train['Count'])
valid_log=np.log(Train['Count'])
Train_log.head()
Datetime
2012-08-25    1.152680
2012-08-26    1.299283
2012-08-27    0.949081
2012-08-28    0.882389
2012-08-29    0.916291
Freq: D, Name: Count, dtype: float64

繪制移動平均值曲線

moving_avg=Train_log.rolling(24).mean()
plt.plot(Train_log)
plt.plot(moving_avg,color='red')
plt.show()
91e12674-a3e7-11ec-952b-dac502259ad0.png

去除移動平均值后再進行迪基-福勒檢驗

train_log_moving_avg_diff=Train_log-moving_avg
train_log_moving_avg_diff.dropna(inplace=True)
test_stationary(train_log_moving_avg_diff)
92011a2e-a3e7-11ec-952b-dac502259ad0.png
Results of Dickey-Fuller Test: 
Test Statistic            -5.861646e+00
P-value                    3.399422e-07
#lags used                 2.000000e+01
No of Observations used    6.250000e+02
Critical Value (1%)       -3.440856e+00
Critical Value (5%)       -2.866175e+00
Critical Value (10%)      -2.569239e+00
dtype: float64

對數(shù)時序數(shù)據(jù)求二階差分后再迪基-福勒檢驗

train_log_diff=Train_log-Train_log.shift(1)
test_stationary(train_log_diff.dropna())
921bee62-a3e7-11ec-952b-dac502259ad0.png
Results of Dickey-Fuller Test: 
Test Statistic            -8.237568e+00
P-value                    5.834049e-13
#lags used                 1.900000e+01
No of Observations used    6.480000e+02
Critical Value (1%)       -3.440482e+00
Critical Value (5%)       -2.866011e+00
Critical Value (10%)      -2.569151e+00
dtype: float64

季節(jié)性分解

對進行對數(shù)轉(zhuǎn)換后的原始數(shù)據(jù)進行季節(jié)性分解。

decomposition=seasonal_decompose(
pd.DataFrame(Train_log).Count.values,freq=24)
trend=decomposition.trend
seasonal=decomposition.seasonal
residual=decomposition.resid

plt.plot(Train_log,label='Original')
plt.plot(trend,label='Trend')
plt.plot(seasonal,label='Seasonality')
plt.plot(residual,label='Residuals')
922acd1a-a3e7-11ec-952b-dac502259ad0.png

對季節(jié)性分解后的殘差數(shù)據(jù)進行迪基-福勒檢驗

train_log_decompose=pd.DataFrame(residual)
train_log_decompose['date']=Train_log.index
train_log_decompose.set_index('date',inplace=True)
train_log_decompose.dropna(inplace=True)
test_stationary(train_log_decompose[0])
924ec422-a3e7-11ec-952b-dac502259ad0.png
Results of Dickey-Fuller Test: 
Test Statistic            -7.822096e+00
P-value                    6.628321e-12
#lags used                 2.000000e+01
No of Observations used    6.240000e+02
Critical Value (1%)       -3.440873e+00
Critical Value (5%)       -2.866183e+00
Critical Value (10%)      -2.569243e+00
dtype: float64

自相關(guān)和偏自相關(guān)圖

fromstatsmodels.tsa.stattoolsimportacf,pacf
lag_acf=acf(train_log_diff.dropna(),nlags=25)
lag_pacf=pacf(train_log_diff.dropna(),nlags=25,method='ols')
plt.plot(lag_acf)
plt.axhline(y=0,linestyle='--',color='gray')
plt.axhline(y=-1.96/np.sqrt(len(train_log_diff.dropna())),linestyle='--',color='gray')
plt.axhline(y=1.96/np.sqrt(len(train_log_diff.dropna())),linestyle='--',color='gray')
plt.plot(lag_pacf)
plt.axhline(y=0,linestyle='--',color='gray')
plt.axhline(y=-1.96/np.sqrt(len(train_log_diff.dropna())),linestyle='--',color='gray')
plt.axhline(y=1.96/np.sqrt(len(train_log_diff.dropna())),linestyle='--',color='gray')
926d5388-a3e7-11ec-952b-dac502259ad0.png929041ea-a3e7-11ec-952b-dac502259ad0.png

AR模型

AR模型訓(xùn)練及預(yù)測

model=ARIMA(Train_log,order=(2,1,0))
#這里q值是零,因為它只是AR模型
results_AR=model.fit(disp=-1)
plt.plot(train_log_diff.dropna(),label='original')
plt.plot(results_AR.fittedvalues,color='red',label='predictions')
92a341b4-a3e7-11ec-952b-dac502259ad0.png
AR_predict=results_AR.predict(start="2014-06-25",end="2014-09-25")
AR_predict=AR_predict.cumsum().shift().fillna(0)
AR_predict1=pd.Series(np.ones(valid.shape[0])*np.log(valid['Count'])[0],index=valid.index)
AR_predict1=AR_predict1.add(AR_predict,fill_value=0)
AR_predict=np.exp(AR_predict1)
plt.plot(valid['Count'],label="Valid")
plt.plot(AR_predict,color='red',label="Predict")
plt.legend(loc='best')
plt.title('RMSE:%.4f'%(np.sqrt(np.dot(AR_predict,valid['Count']))/valid.shape[0]))
92ca9c78-a3e7-11ec-952b-dac502259ad0.png

MA模型

model=ARIMA(Train_log,order=(0,1,2))
#這里的p值是零,因為它只是MA模型
results_MA=model.fit(disp=-1)
plt.plot(train_log_diff.dropna(),label='original')
plt.plot(results_MA.fittedvalues,color='red',label='prediction')
92f605d4-a3e7-11ec-952b-dac502259ad0.png
MA_predict=results_MA.predict(start="2014-06-25",end="2014-09-25")
MA_predict=MA_predict.cumsum().shift().fillna(0)
MA_predict1=pd.Series(np.ones(valid.shape[0])*np.log(valid['Count'])[0],index=valid.index)
MA_predict1=MA_predict1.add(MA_predict,fill_value=0)
MA_predict=np.exp(MA_predict1)

plt.plot(valid['Count'],label="Valid")
plt.plot(MA_predict,color='red',label="Predict")
plt.legend(loc='best')
plt.title('RMSE:%.4f'%(np.sqrt(np.dot(MA_predict,valid['Count']))/valid.shape[0]))
9310a146-a3e7-11ec-952b-dac502259ad0.png

ARMA模型

model=ARIMA(Train_log,order=(2,1,2))
results_ARIMA=model.fit(disp=-1)
plt.plot(train_log_diff.dropna(),label='original')
plt.plot(results_ARIMA.fittedvalues,color='red',label='predicted')
9325d228-a3e7-11ec-952b-dac502259ad0.png
defcheck_prediction_diff(predict_diff,given_set):
predict_diff=predict_diff.cumsum().shift().fillna(0)
predict_base=pd.Series(np.ones(given_set.shape[0])*np.log(given_set['Count'])[0],index=given_set.index)
predict_log=predict_base.add(predict_diff,fill_value=0)
predict=np.exp(predict_log)

plt.plot(given_set['Count'],label="Givenset")
plt.plot(predict,color='red',label="Predict")
plt.legend(loc='best')
plt.title('RMSE:%.4f'%(np.sqrt(np.dot(predict,given_set['Count']))/given_set.shape[0]))

defcheck_prediction_log(predict_log,given_set):
predict=np.exp(predict_log)

plt.plot(given_set['Count'],label="Givenset")
plt.plot(predict,color='red',label="Predict")
plt.legend(loc='best')
plt.title('RMSE:%.4f'%(np.sqrt(np.dot(predict,given_set['Count']))/given_set.shape[0]))
plt.show()

ARIMA_predict_diff=results_ARIMA.predict(start="2014-06-25",
end="2014-09-25")
check_prediction_diff(ARIMA_predict_diff,valid)
93542b46-a3e7-11ec-952b-dac502259ad0.png

SARIMAX模型

y_hat_avg=valid.copy()
fit1=sm.tsa.statespace.SARIMAX(Train.Count,order=(2,1,4),seasonal_order=(0,1,1,7)).fit()
y_hat_avg['SARIMA']=fit1.predict(start="2014-6-25",end="2014-9-25",dynamic=True)
plt.plot(Train['Count'],label='Train')
plt.plot(valid['Count'],label='Valid')
plt.plot(y_hat_avg['SARIMA'],label='SARIMA')
8e6ef822-a3e7-11ec-952b-dac502259ad0.png

模型評價

rms=sqrt(mean_squared_error(valid.Count,y_hat_avg.SARIMA))
print(rms)
70.26240839723575

預(yù)測

predict=fit1.predict(start="2014-9-26",end="2015-4-26",dynamic=True)
test['prediction']=predict
#按日、月、年合并Test和test_original
merge=pd.merge(test,test_org,on=('day','Month','Year'),how='left')
merge['Hour']=merge['Hour_y']
merge=merge.drop(['Year','Month','Datetime','Hour_x','Hour_y'],axis=1
#通過合并merge和temp2進行預(yù)測
prediction=pd.merge(merge,temp2,on='Hour',how='left')
#將比率轉(zhuǎn)換成原始比例
prediction['Count']=prediction['prediction']*prediction['ratio']*24
prediction['ID']=prediction['ID_y']
submission=prediction.drop(['day','Hour','ratio','prediction','ID_x','ID_y'],axis=1)
#轉(zhuǎn)換最終提交的csv格式
pd.DataFrame(submission,columns=['ID','Count']).to_csv('SARIMAX.csv')

939ad33e-a3e7-11ec-952b-dac502259ad0.png

原文標題:時間序列分析和預(yù)測實戰(zhàn)

文章出處:【微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:彭菁

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7335

    瀏覽量

    94769
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4417

    瀏覽量

    67507
  • 時間序列
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    10700

原文標題:時間序列分析和預(yù)測實戰(zhàn)

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    【「時間序列與機器學習」閱讀體驗】+ 鳥瞰這本書

    清晰,從時間序列分析基礎(chǔ)理論出發(fā),逐步深入到機器學習算法在時間序列
    發(fā)表于 08-12 11:28

    波導(dǎo)理論知識

    波導(dǎo)理論知識 學習資料! 
    發(fā)表于 11-03 08:36

    測試理論知識-美國國家儀器內(nèi)部AE培訓(xùn)資料

    附件是美國國家儀器應(yīng)用工程師內(nèi)部培訓(xùn)資料,主要針對測試測量基礎(chǔ)理論知識
    發(fā)表于 10-21 11:01

    檢測技術(shù)基礎(chǔ)理論知識

    檢測技術(shù)基礎(chǔ)理論知識
    發(fā)表于 11-27 14:51

    你都知道單片機的基礎(chǔ)理論知識學習包括哪些嗎

    你都知道單片機的基礎(chǔ)理論知識學習包括哪些嗎?
    發(fā)表于 01-21 07:20

    串行和并行通訊的基礎(chǔ)理論知識分析

    基礎(chǔ)理論知識串行和并行通訊比喻為單車道和多車道全雙工、半雙工及單工通訊通訊方式說明全雙工在同一時刻,兩個設(shè)備之間可以同時收發(fā)數(shù)據(jù)半雙工兩個設(shè)備之間可以收發(fā)數(shù)據(jù),但不能在同一時刻進行單工在任何時刻都
    發(fā)表于 02-22 06:32

    科學數(shù)據(jù)時間序列預(yù)測方法

    針對傳統(tǒng)的時間序列分析方法預(yù)測科學數(shù)據(jù)效果較差的特點,提出了一種結(jié)合自組織神經(jīng)網(wǎng)絡(luò)和灰色理論時間
    發(fā)表于 12-31 23:56 ?10次下載

    改進GP分形理論的最近鄰序列預(yù)測算方法

    改進GP分形理論的最近鄰序列預(yù)測算方法:針對現(xiàn)有的時間序列分析
    發(fā)表于 01-03 17:00 ?12次下載

    USB接口的基礎(chǔ)理論知識

    USB接口的基礎(chǔ)理論知識 USB的重要關(guān)鍵字:
    發(fā)表于 10-15 13:08 ?1170次閱讀
    USB接口的<b class='flag-5'>基礎(chǔ)理論知識</b>

    開關(guān)電源的理論知識

    開關(guān)電源的理論知識 - 張興柱博士,下來看看。
    發(fā)表于 03-31 10:26 ?0次下載

    維修電工中級理論知識試卷分享

    本文主要內(nèi)容是維修電工的中級理論知識。
    發(fā)表于 10-11 15:52 ?26次下載
    維修電工中級<b class='flag-5'>理論知識</b>試卷分享

    電信傳輸理論知識詳解

    本文詳細介紹了電信傳輸理論知識(新編)。
    發(fā)表于 11-16 15:57 ?3次下載
    電信傳輸<b class='flag-5'>理論知識</b>詳解

    變頻器的故障分析和解決 實踐檢驗、理論知識及維修水平

    變頻器的故障分析和解決不僅需要實踐檢驗,還需要掌握相關(guān)變頻器相關(guān)的理論知識,理論分析與維修實踐相結(jié)合以達到較高的維修水平,維修人員需要學習的相關(guān)理論
    的頭像 發(fā)表于 07-17 08:54 ?5034次閱讀
    變頻器的故障<b class='flag-5'>分析</b>和解決 實踐檢驗、<b class='flag-5'>理論知識</b>及維修水平

    單片機學習筆記:基礎(chǔ)理論知識學習

    基礎(chǔ)理論知識包括模擬電路、數(shù)字電路和C語言知識。模擬電路和數(shù)字電路屬于抽象學科,要把它學好還得費點精神。在你學習單片機之前,覺得模擬電路和數(shù)字電路基礎(chǔ)不好的話,不要急著學習單片機,應(yīng)該先回顧所學過的模擬電路和數(shù)字電路知識,為學習
    的頭像 發(fā)表于 05-30 10:45 ?5061次閱讀

    詳解單片機基礎(chǔ)理論知識

    單片機基礎(chǔ)理論知識包括模擬電路、數(shù)字電路和C語言知識,模擬電路與數(shù)字電路屬于抽象學科,要把這些學好還得費點功夫,但是在學習單片機之前,覺得自己模擬電路和數(shù)字電路基礎(chǔ)不好的話,先不要急著入門單片機
    發(fā)表于 03-30 17:19 ?5862次閱讀
    詳解單片機<b class='flag-5'>基礎(chǔ)理論知識</b>