上個專輯咱們分析了COVID19的數據,主要從可視化的角度進行了分析。 其實 kaggle上COVID19的數據集多達上千個(連接)。 有興趣的能夠下載更多的內容研究,後續我也會考慮使用其中一部分數據進行建模。html
今天咱們來入手另外一個經典數據集,Energy Consumption (能源消耗)。該數據集是美國PJM公司(至關於國家電網或者南方電網)統計的能源消耗狀況,時間跨度爲達20年,數據集的採樣頻率爲小時。python
時間序列,通常指一維的時間序列(更準確的叫一元時間序列),這是約定俗成的省略。因爲也有多元時間序列,因此在和別人交流時,須要判斷ta所說的時間序列是否是特指一元時間序列。c++
我遇到的時間序列:git
時間序列的預測就是用過去的信息,預測將來的信息。github
你可能據說過prophet,隱約有以下印象:算法
夠了,知道這些就能夠閱讀本文了。至於它如何分解時間序列,如何劃分changepoint,等等。實戰過程當中你天然會想着去了解。爲啥呢?想提高模型的效果,總得嘗試調參啊。今天我就花了一個小時,完成從安裝prophet(包含入坑出坑)到模型預測。windows
這裏特意花一點時間來講一下prophet的安裝過程,由於它裏面有坑,坑裏面還有天坑。不然就是半小時從據說prophet 到完成預測了。api
先說一下本人此次使用的環境:CPU only的筆記本+ pycharm 軟件。bash
打開prophet的官網,在安裝指導頁面,你會被這簡單而又熟悉的pip代碼吸引。機器學習
結果,安裝失敗。
回去仔細閱讀安裝說明,下面還有小字:
The major dependency that Prophet has is pystan. PyStan has its own installation instructions. Install pystan with pip before using pip to install fbprophet.
複製代碼
pystan 一眼就看出是能夠pip安裝的。因而pip install pystan,沒有報錯,內心竊喜。而後pip install fbprophet
結果。。。仍是失敗!!
回去仔細閱讀pystan的說明:
原來pystan也有一堆東西要提早安裝,可是我一看到要安裝c++,我瑟瑟發抖。由於這中間的坑不是一篇文章能說完的。再者,我不想弄亂本身windows的系統。
因而花了一點時間仔細看說明,想要節省時間,就用pystan安裝手冊的推薦的用Anaconda 安裝吧。 因而個人安裝步驟以下:
終於成功了,趕忙碼代碼。 一如既往,代碼優先。
從kaggle上下載數據,放到本地文件夾data中。 首先導入模塊,包括數據分析經典的pandas,sklearn,numpy,matplotlib 以及咱們本文的明星Prophet。
from fbprophet import Prophet
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error
import numpy as np
複製代碼
簡單說一下數據集,kaggle提供了PJM 各個區域(客戶羣)的數據。咱們快速瀏覽每一個數據的columns,發現除了pjm_hourly_est文件,剩下的都是兩列數據,一個時間列,一個耗電量(MW)。pjm_hourly_est 不過是把全部其餘文件的信息合併到一個文件而已。
AEP_hourly
Index(['Datetime', 'AEP_MW'], dtype='object')
******************************
COMED_hourly
Index(['Datetime', 'COMED_MW'], dtype='object')
******************************
DAYTON_hourly
Index(['Datetime', 'DAYTON_MW'], dtype='object')
******************************
DEOK_hourly
Index(['Datetime', 'DEOK_MW'], dtype='object')
******************************
DOM_hourly
Index(['Datetime', 'DOM_MW'], dtype='object')
******************************
DUQ_hourly
Index(['Datetime', 'DUQ_MW'], dtype='object')
******************************
EKPC_hourly
Index(['Datetime', 'EKPC_MW'], dtype='object')
******************************
FE_hourly
Index(['Datetime', 'FE_MW'], dtype='object')
******************************
NI_hourly
Index(['Datetime', 'NI_MW'], dtype='object')
******************************
PJME_hourly
Index(['Datetime', 'PJME_MW'], dtype='object')
******************************
PJMW_hourly
Index(['Datetime', 'PJMW_MW'], dtype='object')
******************************
pjm_hourly_est
Index(['Datetime', 'AEP', 'COMED', 'DAYTON', 'DEOK', 'DOM', 'DUQ', 'EKPC',
'FE', 'NI', 'PJME', 'PJMW', 'PJM_Load'],
dtype='object')
******************************
PJM_Load_hourly
Index(['Datetime', 'PJM_Load_MW'], dtype='object')
******************************
複製代碼
咱們就是想看看prophet如何預測,因此就使用第一個數據集吧。
file = 'data/AEP_hourly.csv'
raw_df = pd.read_csv(file)
print(raw_df.head(5))
print(raw_df.tail(5))
複製代碼
結果以下,看來時間跨度從2004年底到2018年初。
Datetime AEP_MW
0 2004-12-31 01:00:00 13478.0
1 2004-12-31 02:00:00 12865.0
2 2004-12-31 03:00:00 12577.0
3 2004-12-31 04:00:00 12517.0
4 2004-12-31 05:00:00 12670.0
Datetime AEP_MW
121268 2018-01-01 20:00:00 21089.0
121269 2018-01-01 21:00:00 20999.0
121270 2018-01-01 22:00:00 20820.0
121271 2018-01-01 23:00:00 20415.0
121272 2018-01-02 00:00:00 19993.0
複製代碼
對於prophet,啥都不知道,那就看指導手冊吧,每一個指導手冊都會有quick start,讓你快速調用。
對於prophet,輸入的數據須要有如下格式:
因此,根據上述要求,咱們來處理數據:
dt_format = '%Y-%m-%d %H:%M:%S' # 處理時間格式
raw_df['Datetime']= pd.to_datetime(raw_df['Datetime'],format=dt_format)
raw_df.rename({'AEP_MW':'y','Datetime':'ds'},axis=1,inplace=True) # 重命名
print(raw_df.info())
複製代碼
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ds 121273 non-null datetime64[ns]
1 y 121273 non-null float64
dtypes: datetime64[ns](1), float64(1)
複製代碼
對於機器學習,劃分訓練和測試數據集是必須的。由於時間序列有時間上的連貫性,不能輕易的用sklearn的train_test_split 函數劃分。 這裏咱們劃分很簡單,咱們剛纔已經預覽了數據集的首尾,知道器時間跨度爲2004 到2018,有十幾年的數據,因此咱們這裏就劃分爲最後一年爲測試集,其餘的數據爲訓練集。 Timestamp 能夠支持邏輯比大小,因此咱們就能夠經過如下代碼劃分數據集。
split_dt = pd.Timestamp('2017-01-01 00:00:00')
train_df = raw_df[raw_df['ds']< split_dt]
test_df = raw_df[raw_df['ds']>= split_dt]
複製代碼
prophet 聽從sklearn 模型的API接口規範,也就是建模經典三部曲:建立模型--> fit訓練數據--> predict 測試集。
代碼還真的只有三行!!
model = Prophet()
model= model.fit(train_df)
y_hat = model.predict(test_df)
複製代碼
原本想調用matplotlib 畫圖試試,結果看到prophet已經自帶plot函數。
model.plot(y_hat)
複製代碼
從人眼可見的角度來判斷,預測的有點模樣,有周期趨勢,均值彷佛也差很少。咱們來看一下,偏差多大,這裏採用mean_absolute_error來衡量,而且計算偏差佔均值的比例。
print(mean_absolute_error(test_df['y'].values,y_hat['yhat']))
print(mean_absolute_error(test_df['y'].values,y_hat['yhat'])/test_df['y'].values.mean())
複製代碼
1782.2521239509801
0.12056939407796417
複製代碼
平均偏差爲1782MW,偏差約等於觀測對象水平的12%。 那這個偏差是大仍是小呢?模型是好還不是很差呢? 我以爲單看準確度,確定不是好的模型。可是問題出在哪裏呢?是prophet 模型的上限就是這樣的準確度?仍是咱們沒有好好調整prophet的參數?
沒有對比就沒有傷害!!下一篇,咱們能夠對比一下咱們的快速prophet 模型與網上的大牛的結果對比。
到此咱們就已經預測了最後一年的時間趨勢,可是咱們對prophet仍是不甚瞭解。 prophet 核心就是時間序列的分解技術,它能夠從原始序列中剝離每日週期序列,每週週期序列,每一年週期序列,以及大趨勢。
咱們能夠看看plot此次分解的結果。彷佛大的趨勢是一條水平線,也就是常值。每週的序列週期不是特別明顯,可是每一年的週期比較明顯,週期約爲半年,幅值高達2000左右。
fig2 = model.plot_components(y_hat)
複製代碼
本文中咱們採用prophet模型,對能源消耗的數據集的進行了預測,其中預測一年的平均偏差爲1782 左右。 本文還涵蓋了使用prophet建模的一些輔助事項: