1. 程式人生 > >用Python玩轉時序資料

用Python玩轉時序資料

40bcc382257664321cfa7ba1566b3d48cf8bfef2

時間序列是日常生活中最常見的資料型別之一。股票價格、銷售資訊、氣候資料、能源使用,甚至個人身高體重都是可以用來定期收集的資料樣本。幾乎每個資料科學家在工作中都會遇到時間序列,能夠有效地處理這些資料是資料科學領域之中的一項非常重要的技能。

本文簡要介紹瞭如何從零開始使用Python中的時間序列。這包括對時間序列的簡單定義,以及對利用pandas訪問倫敦市居民智慧電錶所獲取資料的處理。可以點選此處獲取本文中所使用的資料。還提供了一些我認為有用的程式碼。

讓我們從基礎開始,時間序列的定義是這樣的:

時間序列是按時間的順序進行索引、排列或者繪製的資料點的集合。最常見的定義是,一個時間序列是在連續的相同間隔的時間點上取得的序列,因此它是一個離散時間資料的序列。

時間序列資料是圍繞相對確定的時間戳而組織的。因此,與隨機樣本相比,可能包含我們將要嘗試提取的一些相關資訊。

載入和控制時間序列

資料集

讓我們使用一些關於能源消耗計費的資料作為例子,以kWh(每半小時)為單位, 201111月至20142月期間,對參與英國電力網路領導的低碳倫敦專案的倫敦居民樣本資料進行分析。我們可以從繪製一些圖表開始,最好了解一下樣本的結構和範圍,這也將允許我們尋找最終需要糾正的缺失值。

bb1c04add122e45a3b52b834f34f8ffdcc1e8052

對於本文的其餘部分,我們只關注DateTimekWh兩列。

952a95644124bb2b4d064fc03a59395acf41ece3

重取樣

讓我們從較簡單的重取樣技術開始。重取樣涉及到更改時間序列觀測的頻率。特徵工程可能是你對重新取樣時間序列資料感興趣的一個原因。實際上,它可以用來為監督學習模型提供額外的架構或者是對學習問題的領會角度。

pandas中的重取樣方法與GroupBy方法相似,因為你基本上是按照特定時間間隔進行分組的。然後指定一種方法來重新取樣。讓我們通過一些例子來把重取樣技術描述的更具體些。我們從每週的總結開始:

·data.resample()方法將用於對DataFramekWh列資料重新取樣;

·“W”表示我們要按每週重新取樣;

·sum()方法用於表示在此時間段計算kWh列的總和;

4c51afdaa525a8fc1fe33bbf80454c1811ce41c2

我們可以對每日的資料也這麼做處理,並且可以使用groupbymean函式進行按小時處理:

d504e3f9503b54b2d179c5b66f035de15a19e984

9ea1358c3d54f7d50b8fd2efd3a7758e3377b129

為了進一步進行重新取樣,pandas有許多內建的選項,你甚至還可以定義自己的方法。下面兩個表分別顯示了時間週期選項及其縮寫別名和一些可能用於重取樣的常用方法。

258e4aeef3151c660c502d2e47066230c0767dab

cc4be2da049920864807e783dd44d6aafc6018b4


其它探索

這裡還有一些你可以用於處理資料而進行的其它探索:

cbfdda2adfe36dc78ead94c2caa355caaaa93fb9

d41974da0be58f43d8c10c5a5a971d43d962db49

393d0a708408e577b8be92607d73f3bd728cf40f

243e4831dd1c12975244c4f3c83edc2671953c59

06673e07eda261555e44ea02adc99578ea867520

Prophet建模

1e281616097ae3177c900b05805cbd4627ec5c7c

Facebook Prophet2017年釋出的,可用於Python,而R.Prophet是設計用於分析在不同時間間隔上顯示模式的日觀測時間序列。Prophet對於資料丟失情況和趨勢的變化具有很強的魯棒性,並且通常能夠很好地處理異常值。它還具有高階的功能,可以模擬假日在時間序列上產生的影響並執行自定義的變更點,但我將堅持使用基本規則來啟動和執行模型。我認為Prophet可能是生產快速預測結果的一個好的選擇,因為它有直觀的引數,並且可以由有良好領域知識背景的但缺乏預測模型的技術技能的人來進行調整。有關Prophet的更多資訊,大家可以點選這裡查閱官方文件。

在使用Prophet之前,我們將資料裡的列重新命名為正確的格式。Date列必須稱為“ds”和要預測值的列為“y”。我們在下面的示例中使用了每日彙總的資料。

7db062ecc598b4e732b8488bbd0cf53e44763b90

然後我們匯入Prophet,建立一個模型並與資料相匹配。在Prophet中,changepoint_prior_scale引數用於控制趨勢對變化的敏感度,越高的值會更敏感,越低的值則敏感度越低。在試驗了一系列值之後,我將這個引數設定為0.10,而不是預設值0.05

bfafd1ade6a1b39a476224373a6557e53b76547e

為了進行預測,我們需要建立一個稱為未來資料框(future dataframe)的東西。我們需要指定要預測的未來時間段的數量(在我們的例子中是兩個月)和預測頻率(每天)。然後我們用之前建立的Prophet模型和未來資料框進行預測。

274593475d6cca002aadde617101d54e89fa9894

非常簡單!未來資料框包含了未來兩個月內的預估居民使用電量。我們可以用一個圖表來進行視覺化預測展示:

179467d15b6ef0147094af11c3a2674ff34e9c9a

圖中的黑點代表了實際值,藍線則代表了預測值,而淺藍色陰影區域代表不確定性。

如下圖所示,不確定性區域隨著我們在之後的進一步變化而擴大,因為初始的不確定性隨著時間的推移而擴散和增多。

38eb6e48000e3ba52559500d527c9d36ea2a2188

Prophet還可以允許我們輕鬆地對整體趨勢和元件模式進行視覺化展示:

35ab60fd45aa64655455b76202c6fd0abc90c731

每年的模式很有趣,因為它看起來表明了居民的電量使用在秋季和冬季會增加,而在春季和夏季則會減少。直觀地說,這正是我們期望要看到的。從每週的趨勢來看,週日的使用量似乎比一週中其它時間都要多。最後,總體的趨勢表明,使用量增長了一年,然後才緩慢地下降。需要進行進一步的調查來解釋這一趨勢。在下一篇文章中,我們將嘗試找出是否與天氣有關。

LSTMLong Short-Term Memory,長短期記憶網路)預測

LSTM迴圈神經網路具有學習長序列觀測值的前景。部落格文章《瞭解LSTM網路》,在以一種易於理解的方式來解釋底層複雜性方面做的非常出色。以下是一個描述LSTM內部單元體系結構的示意圖:

8482146bc0f0c7f1e8570a6626405e0cf827a97e

來源:Understanding LSTM Networks

LSTM似乎非常適合於對時間序列的預測。讓我們再次使用一下每日彙總的資料。

ad31a42683a11d4bc66fb581612674586bedeaba

LSTM對輸入資料的大小很敏感,特別是當使用SigmoidTanh這兩個啟用函式的時候。通常,將資料重新調整到[01][-11]這個範圍是一個不錯的實踐,也稱為規範化。我們可以使用scikit-learn庫中的MinMaxScaler預處理類來輕鬆地規範化資料集。

def43ca17d6fc236ab4e8c40fd021a1bcf26cb7a

現在我們可以將已排好序的資料集拆分為訓練資料集和測試資料集。下面的程式碼計算出了分割點的索引,並將資料拆分為多個訓練資料集,其中80%的觀測值可用於訓練模型,剩下的20%用於測試模型。

af820a4470ddc067430e76f89f48bdfb9aded5f4

我們可以定義一個函式來建立一個新的資料集,並使用這個函式來準備用於建模的訓練資料集和測試資料集。

a752beb32c119c587e3d66955712ea627529b541

LSTM網路要求輸入的資料以如下的形式提供特定的陣列結構:[樣本、時間間隔、特徵]

資料目前都規範成了[樣本,特徵]的形式,我們正在為每個樣本設計兩個時間間隔。可以將準備好的分別用於訓練和測試的輸入資料轉換為所期望的結構,如下所示:

5c726255191ca4045404b38d7ac9f3c6ab385fac

就是這樣,現在已經準備好為示例設計和設定LSTM網路了。

626b2a47702f486fc0094e24e01ff03a992dc627

從下面的損失圖可以看出,該模型在訓練資料集和測試資料集上都具有可比較的表現。

741adcd1f0f28745ac2b00e7b4c47f3c6e3c8451

在下圖中,我們看到LSTM在擬合測試資料集方面做得非常好。

c59950101ccd3c25c09c6bbd075563124ffcbd00

聚類(Clustering

最後,我們還可以使用示例的資料進行聚類。執行聚類有很多不同的方式,但一種方式是按結構層次來形成聚類。你可以通過兩種方式形成一個層次結構:從頂部開始來拆分,或從底部開始來合併。我決定先看看後者。

讓我們從資料開始,只需簡單地匯入原始資料,併為某年中的某日和某日中的某一小時新增兩列。

bf4bb310722fc4cf288cf714a449eadea3155338

db87f82b37a85007e9441a36870a5030f565a19e

LinkageDendrograms

linkage函式根據物件的相似性,將距離資訊和物件對分組放入聚類中。這些新形成的聚類隨後相互連線,以建立更大的聚類。這個過程將會進行迭代,直到在原始資料集中的所有物件在層次樹中都連線在了一起。

對資料進行聚類:

cd609fb4652654ad28626da872f1be0cd94b642a

完成了!!!這難道不是很簡單嗎?

當然很簡單了,但是上面程式碼中的“ward”在那裡意味著什麼呢?這實際上是如何執行的?正如scipy linkage文件上告訴我們的那樣,“ward”是可以用來計算新形成的聚類之間距離的一個方法。關鍵字“ward”linkage函式使用Ward方差最小化演算法。其它常見的linkage方法,如singlecompleteaverage,還有不同的距離度量標準,如euclideanmanhattanhammingcosine,如果你想玩玩的話也可以使用一下。

現在讓我們來看看這個稱為dendogram的分層聚類圖。dendogram圖是聚類的層次圖,其中那些條形的長度表示到下一個聚類中心的距離。

3b9b73ddb1c12f8945ceb172f991a084920a568c

如果這是你第一次看到dendrogram圖,那看起來挺複雜的,但是別擔心,讓我們把它分解來看:

·在x軸上可以看到一些標籤,如果你沒有指定任何其它內容,那麼這些標籤就是X上樣本的索引;

·在y軸上,你可以看到那些距離長度(在我們的例子中是ward方法);

·水平線是聚類的合併;

·那些垂線告訴你哪些聚類或者標籤是合併的一部分,從而形成了新的聚類;

·水平線的高度是用來表示需要被橋接以形成新聚類的距離;

即使有解釋說明,之前的dendogram圖看起來仍然不明顯。我們可以減少一點,以便能更好地檢視資料。

a35346026ce4729dd77720373c276804e585a86e

建議查詢聚類文件以便能瞭解更多內容,並嘗試使用不同的引數。

本文由北郵@愛可可-愛生活 老師推薦,阿里云云棲社群組織翻譯。

文章原標題《Playing with time series data in python

譯者:Mags,審校:袁虎。

文章為簡譯,更為詳細的內容,請檢視原文