介紹 時(shí)間序列(簡(jiǎn)稱TS)被認(rèn)為是分析領(lǐng)域比較少人知道的技能。(我也是幾天前才知道它)。但是你一定知道最近的小型編程馬拉松就是基于時(shí)間序列發(fā)展起來的,我參加了這項(xiàng)活動(dòng)去學(xué)習(xí)了解決時(shí)間序列問題的基本步驟,在這兒我要分享給大家。這絕對(duì)能幫助你在編程馬拉松中獲得一個(gè)合適的模型。 文章之前,我極力推薦大家閱讀《基于R語言的時(shí)間序列建模完整教程》A Complete Tutorial on Time Series Modeling in R,它就像這篇文章的前篇。它關(guān)注基本概念和基于R語言,我將重點(diǎn)使用這些概念來解決Python編程里面端到端的問題。R語言存在許多關(guān)于時(shí)間序列的資源,但是很少關(guān)于Python的,所以本文將使用Python。 36大數(shù)據(jù)專稿,原文作者:AARSHAY JAIN 本文由36大數(shù)據(jù)翻譯,任何不標(biāo)明譯者和出處以及本文鏈接http://www./archives/43811的均為侵權(quán)。 我們的過程包括下面幾步: 1、時(shí)間序列有什么特別之處? 2、在Pandas上傳和加載時(shí)間序列(pandas 是基于 Numpy 構(gòu)建的含有更高級(jí)數(shù)據(jù)結(jié)構(gòu)和工具的數(shù)據(jù)分析包,類似于 Numpy 的核心是 ndarray,pandas 也是圍繞著 Series 和 DataFrame 兩個(gè)核心數(shù)據(jù)結(jié)構(gòu)展開的 。) 3、如何檢驗(yàn)時(shí)間序列的穩(wěn)定性? 4、如何令時(shí)間序列穩(wěn)定? 5、時(shí)間序列預(yù)測(cè)。 1、時(shí)間序列有什么特別之處? 顧名思義,時(shí)間序列是時(shí)間間隔不變的情況下收集的時(shí)間點(diǎn)集合。這些集合被分析用來了解長(zhǎng)期發(fā)展趨勢(shì),為了預(yù)測(cè)未來或者表現(xiàn)分析的其他形式。但是是什么令時(shí)間序列與常見的回歸問題的不同? 有兩個(gè)原因: 1、時(shí)間序列是跟時(shí)間有關(guān)的。所以基于線性回歸模型的假設(shè):觀察結(jié)果是獨(dú)立的在這種情況下是不成立的。 2、隨著上升或者下降的趨勢(shì),更多的時(shí)間序列出現(xiàn)季節(jié)性趨勢(shì)的形式,如:特定時(shí)間框架的具體變化。即:如果你看到羊毛夾克的銷售上升,你就一定會(huì)在冬季做更多銷售。 因?yàn)闀r(shí)間序列的固有特性,有各種不同的步驟可以對(duì)它進(jìn)行分析。下文將詳細(xì)分析。通過在Python上傳時(shí)間序列對(duì)象開始。我們將使用飛機(jī)乘客數(shù)據(jù)集。 請(qǐng)記住本文的目的是希望使你熟悉關(guān)于時(shí)間序列的不同使用方法。本文的例子只是用來方便解釋時(shí)間序列對(duì)象,我重點(diǎn)關(guān)注題目的廣泛性,不會(huì)做非常精確的預(yù)測(cè)。 2、在pandas上傳和加載時(shí)間序列 Pandas有專門處理時(shí)間序列對(duì)象的庫(kù),特別是可以存儲(chǔ)時(shí)間信息和允許人們執(zhí)行快速合作的datatime64(ns)類。從激發(fā)所需的庫(kù)開始。 import pandas as pd import numpy as np import matplotlib.pylab as plt %matplotlib inline from matplotlib.pylab import rcParams rcParams['figure.figsize'] = 15, 6 現(xiàn)在,我們可以上傳數(shù)據(jù)集和查看一些最初的行以及列的數(shù)據(jù)類型。 data = pd.read_csv('AirPassengers.csv') print data.head() print '\n Data Types:' print data.dtypes 數(shù)據(jù)包含了指定的月份和該月的游客數(shù)量。但是時(shí)間序列對(duì)象的讀取和數(shù)據(jù)類型的“對(duì)象”和“整數(shù)類型”的讀取是不一樣的。為了將讀取的數(shù)據(jù)作為時(shí)間序列,我們必須通過特殊的參數(shù)讀取csv指令。 dateparse = lambda dates: pd.datetime.strptime(dates, '%Y-%m') data = pd.read_csv('AirPassengers.csv', parse_dates='Month', index_col='Month',date_parser=dateparse) print data.head() 我們逐個(gè)解釋這些參數(shù): 1、parse_dates:這是指定含有時(shí)間數(shù)據(jù)信息的列。正如上面所說的,列的名稱為“月份”。 1、index_col:使用pandas 的時(shí)間序列數(shù)據(jù)背后的關(guān)鍵思想是:目錄成為描述時(shí)間數(shù)據(jù)信息的變量。所以該參數(shù)告訴pandas使用“月份”的列作為索引。 2、date_parser:指定將輸入的字符串轉(zhuǎn)換為可變的時(shí)間數(shù)據(jù)。Pandas默認(rèn)的數(shù)據(jù)讀取格式是‘YYYY-MM-DD HH:MM:SS’。如需要讀取的數(shù)據(jù)沒有默認(rèn)的格式,就要人工定義。這和dataparse的功能部分相似,這里的定義可以為這一目的服務(wù)。 現(xiàn)在我們看到數(shù)據(jù)有作為索引的時(shí)間對(duì)象和作為列的乘客(#Passengers)。我們可以通過以下指令再次檢查索引的數(shù)據(jù)類型。 data.index 注意: dtype=’datetime[ns]’ 確認(rèn)它是一個(gè)時(shí)間數(shù)據(jù)對(duì)象。個(gè)人而言,我會(huì)將列轉(zhuǎn)換為序列對(duì)象,這樣當(dāng)我每次使用時(shí)間序列的時(shí)候,就不需要每次都要提及列名稱。當(dāng)然,這因人而異,如果能令你更好工作,可以使用它作為數(shù)據(jù)框架。 ts = data[‘#Passengers’] ts.head(10) 在進(jìn)一步深入前,我會(huì)探討一些關(guān)于時(shí)間序列數(shù)據(jù)的索引技術(shù)。先在序列對(duì)象選擇一個(gè)特殊值??梢酝ㄟ^以下兩種方式實(shí)現(xiàn): #1. Specific the index as a string constant: ts['1949-01-01'] #2. Import the datetime library and use 'datetime' function: from datetime import datetime ts[datetime(1949,1,1)] 兩種方法都會(huì)返回值“112”,這可以通過先前的結(jié)果確認(rèn)。希望我們可以獲得1949年5月(包括1949年5月)之前的數(shù)據(jù)。這又可以用以下兩種方法實(shí)現(xiàn): #1. Specify the entire range: ts['1949-01-01':'1949-05-01'] #2. Use ':' if one of the indices is at ends: ts[:'1949-05-01'] 兩種方法都會(huì)輸出以下結(jié)果: 我們要注意兩點(diǎn):
考慮到可以使用另外一個(gè)例子:你需要1949年所有的值。可以這樣做: ts['1949'] 可見,月份部分已經(jīng)省略。如果你要獲得某月所有的日期,日期部分也可以省略。 現(xiàn)在,讓我們開始分析時(shí)間序列。 3、如何檢驗(yàn)時(shí)間序列的穩(wěn)定性? 如果一個(gè)時(shí)間序列的統(tǒng)計(jì)特征如平均數(shù),方差隨著時(shí)間保持不變,我們就可以認(rèn)為它是穩(wěn)定的。為什么時(shí)間序列的穩(wěn)定性這么重要?大部分時(shí)間序列模型是在假設(shè)它是穩(wěn)定的前提下建立的。直觀地說,我們可以這樣認(rèn)為,如果一個(gè)時(shí)間序列隨著時(shí)間產(chǎn)生特定的行為,就有很高的可能性認(rèn)為它在未來的行為是一樣的。同時(shí),根據(jù)穩(wěn)定序列得出的理論是更加成熟的, 也是更容易實(shí)現(xiàn)與非穩(wěn)定序列的比較。 穩(wěn)定性的確定標(biāo)準(zhǔn)是非常嚴(yán)格的。但是,如果時(shí)間序列隨著時(shí)間產(chǎn)生恒定的統(tǒng)計(jì)特征,根據(jù)實(shí)際目的我們可以假設(shè)該序列是穩(wěn)定的。如下:
我會(huì)跳過一些細(xì)節(jié),因?yàn)樵谖恼乱呀?jīng)說的非常清楚。接下來,是關(guān)于測(cè)試穩(wěn)定性的方法。首先是簡(jiǎn)化坐標(biāo)和數(shù)據(jù),進(jìn)行可視分析。數(shù)據(jù)可以通過以下指令定位。 ts['1949'] 非常清晰的看到,隨著季節(jié)性的變動(dòng),飛機(jī)乘客的數(shù)量總體上是在不斷增長(zhǎng)的。但是,不是經(jīng)常都可以獲得這樣清晰的視覺推論(下文給出相應(yīng)例子)。所以,更正式的講,我們可以通過下面的方法測(cè)試穩(wěn)定性。 1、繪制滾動(dòng)統(tǒng)計(jì):我們可以繪制移動(dòng)平均數(shù)和移動(dòng)方差,觀察它是否隨著時(shí)間變化。隨著移動(dòng)平均數(shù)和方差的變化,我認(rèn)為在任何“t”瞬間,我們都可以獲得去年的移動(dòng)平均數(shù)和方差。如:上一個(gè)12個(gè)月份。但是,這更多的是一種視覺技術(shù)。 2、DF檢驗(yàn):這是一種檢查數(shù)據(jù)穩(wěn)定性的統(tǒng)計(jì)測(cè)試。無效假設(shè):時(shí)間序列是不穩(wěn)定的。測(cè)試結(jié)果由測(cè)試統(tǒng)計(jì)量和一些置信區(qū)間的臨界值組成。如果“測(cè)試統(tǒng)計(jì)量”少于“臨界值”,我們可以拒絕無效假設(shè),并認(rèn)為序列是穩(wěn)定的。 這些概念不是憑直覺得出來的。我推薦大家瀏覽前篇文章。如果你對(duì)一些理論數(shù)據(jù)感興趣,你可以參考Brockwell 和 Davis關(guān)于時(shí)間序列和預(yù)測(cè)的介紹的書。這本書的數(shù)據(jù)很多,但是如果你能讀懂言外之意,你會(huì)明白這些概念和正面接觸這些數(shù)據(jù)。 回到檢查穩(wěn)定性這件事上,我們將使用滾動(dòng)數(shù)據(jù)坐標(biāo)連同許多DF測(cè)試結(jié)果,我已經(jīng)定義了一個(gè)需要時(shí)間序列作為輸入的函數(shù),為我們生成結(jié)果。請(qǐng)注意,我已經(jīng)繪制標(biāo)準(zhǔn)差來代替方差,為了保持單元和平均數(shù)相似。 from statsmodels.tsa.stattools import adfuller def test_stationarity(timeseries): #Determing rolling statistics rolmean = pd.rolling_mean(timeseries, window=12) rolstd = pd.rolling_std(timeseries, window=12) #Plot rolling statistics: orig = plt.plot(timeseries, color='blue',label='Original') mean = plt.plot(rolmean, color='red', label='Rolling Mean') std = plt.plot(rolstd, color='black', label = 'Rolling Std') plt.legend(loc='best') plt.title('Rolling Mean & Standard Deviation') plt.show(block=False) #Perform Dickey-Fuller test: print 'Results of Dickey-Fuller Test:' dftest = adfuller(timeseries, autolag='AIC') dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used']) for key,value in dftest[4].items(): dfoutput['Critical Value (%s)'%key] = value print dfoutput 代碼是非常直觀的,如果你在閱讀過程中遇到挑戰(zhàn)可以在評(píng)論處提出。 輸入序列開始運(yùn)行: 基本上是不可能使序列完全穩(wěn)定,我們只能努力讓它盡可能的穩(wěn)定。 先讓我們弄明白是什么導(dǎo)致時(shí)間序列不穩(wěn)定。這兒有兩個(gè)主要原因。
模型的根本原理或者預(yù)測(cè)序列的趨勢(shì)和季節(jié)性,從序列中刪除這些因素,將得到一個(gè)穩(wěn)定的序列。然后統(tǒng)計(jì)預(yù)測(cè)技術(shù)可以在這個(gè)序列上完成。最后一步是通過運(yùn)用趨勢(shì)和季節(jié)性限制倒回到將預(yù)測(cè)值轉(zhuǎn)換成原來的區(qū)間。 注意:我將探討一系列方法??赡苡行?duì)文中情況有用,有些不能。但是我的目的是得到一系列可用方法,而不是僅僅關(guān)注目前的問題。 讓我們通過分析趨勢(shì)的一部分開始工作吧。 預(yù)測(cè)&消除趨勢(shì) 消除趨勢(shì)的第一個(gè)方法是轉(zhuǎn)換。例如,在本例中,我們可以清楚地看到,有一個(gè)顯著的趨勢(shì)。所以我們可以通過變換,懲罰較高值而不是較小值。這可以采用日志,平方根,立方跟等等。讓我們簡(jiǎn)單在這兒轉(zhuǎn)換一個(gè)對(duì)數(shù)。 ts_log = np.log(ts) plt.plot(ts_log) 在這個(gè)簡(jiǎn)單的例子中,很容易看到一個(gè)向前的數(shù)據(jù)趨勢(shì)。但是它表現(xiàn)的不是很直觀。所以我們可以使用一些技術(shù)來估計(jì)或?qū)@個(gè)趨勢(shì)建模,然后將它從序列中刪除。這里有很多方法,最常用的有:
我在這兒討論將平滑,你也應(yīng)該嘗試其他可以解決的問題的技術(shù)。平滑是指采取滾動(dòng)估計(jì),即考慮過去的幾個(gè)實(shí)例。有各種方法可以解決這些問題,但我將主要討論以下兩個(gè)。 移動(dòng)平均數(shù) 在這個(gè)方法中,根據(jù)時(shí)間序列的頻率采用“K”連續(xù)值的平均數(shù)。我們可以采用過去一年的平均數(shù),即過去12個(gè)月的平均數(shù)。關(guān)于確定滾動(dòng)數(shù)據(jù),pandas有特定的功能定義。 moving_avg = pd.rolling_mean(ts_log,12) plt.plot(ts_log) plt.plot(moving_avg, color='red') 紅色表示了滾動(dòng)平均數(shù)。讓我們從原始序列中減去這個(gè)平均數(shù)。注意,從我們采用過去12個(gè)月的值開始,滾動(dòng)平均法還沒有對(duì)前11個(gè)月的值定義。我們可以看到: ts_log_moving_avg_diff = ts_log - moving_avg ts_log_moving_avg_diff.head(12) 注意前11個(gè)月是非數(shù)字的,現(xiàn)在讓我們對(duì)這11個(gè)月降值和檢查這些模塊去測(cè)試穩(wěn)定性。 ts_log_moving_avg_diff.dropna(inplace=True) test_stationarity(ts_log_moving_avg_diff) 這看起來像個(gè)更好的序列。滾動(dòng)平均值出現(xiàn)輕微的變化,但是沒有明顯的趨勢(shì)。同時(shí),檢驗(yàn)統(tǒng)計(jì)量比5%的臨界值小,所以我們?cè)?5%的置信區(qū)間認(rèn)為它是穩(wěn)定序列。 但是,這個(gè)方法有一個(gè)缺陷:要嚴(yán)格定義時(shí)段。在這種情況下,我們可以采用年平均數(shù),但是對(duì)于復(fù)雜的情況的像預(yù)測(cè)股票價(jià)格,是很難得到一個(gè)數(shù)字的。所以,我們采取“加權(quán)移動(dòng)平均法”可以對(duì)最近的值賦予更高的權(quán)重。關(guān)于指定加重這兒有很多技巧。 指數(shù)加權(quán)移動(dòng)平均法是很受歡迎的方法,所有的權(quán)重被指定給先前的值連同衰減系數(shù)。這可以通過pandas實(shí)現(xiàn): expwighted_avg = pd.ewma(ts_log, halflife=12) plt.plot(ts_log) plt.plot(expwighted_avg, color='red') 注意,這里使用了參數(shù)“半衰期”來定義指數(shù)衰減量。這只是一個(gè)假設(shè),將很大程度上取決于業(yè)務(wù)領(lǐng)域。其他參數(shù),如跨度和質(zhì)心也可以用來定義衰減,正如上面鏈接分享的探討?,F(xiàn)在讓我們從這個(gè)序列轉(zhuǎn)移,繼續(xù)檢查穩(wěn)定性。 ts_log_ewma_diff = ts_log - expwighted_avg test_stationarity(ts_log_ewma_diff) 這個(gè)時(shí)間序列有更少的平均值變化和標(biāo)準(zhǔn)差大小變化。同時(shí),檢驗(yàn)統(tǒng)計(jì)量小于1%的臨界值,這比以前的情況好。請(qǐng)注意在這種情況下就不會(huì)有遺漏值因?yàn)樗械闹翟谝婚_始就被賦予了權(quán)重。所以在運(yùn)行的時(shí)候,它沒有先前的值參與。 消除趨勢(shì)和季節(jié)性 之前討論來了簡(jiǎn)單的趨勢(shì)減少技術(shù)不能在所有情況下使用,特別是在高季節(jié)性情況下。讓我們談?wù)撘幌聝煞N消除趨勢(shì)和季節(jié)性的方法。
差分 處理趨勢(shì)和季節(jié)性的最常見的方法之一就是差分法。在這種方法中,我們采用特定瞬間和它前一個(gè)瞬間的不同的觀察結(jié)果。這主要是在提高平穩(wěn)性。pandas可以實(shí)現(xiàn)一階差分: ts_log_diff = ts_log - ts_log.shift() plt.plot(ts_log_diff) 表中可以看出很大程度上減少了趨勢(shì)。讓我們通過模塊驗(yàn)證一下: ts_log_diff.dropna(inplace=True) test_stationarity(ts_log_diff) 我們可以看到平均數(shù)和標(biāo)準(zhǔn)差隨著時(shí)間有小的變化。同時(shí),DF檢驗(yàn)統(tǒng)計(jì)量小于10% 的臨界值,因此該時(shí)間序列在90%的置信區(qū)間上是穩(wěn)定的。我們同樣可以采取二階或三階差分在具體應(yīng)用中獲得更好的結(jié)果。這些方法你可以自己嘗試。 分解 在這種方法中,趨勢(shì)和季節(jié)性是分別建模的并倒回到序列的保留部分。我將跳過統(tǒng)計(jì)數(shù)據(jù),直接給出結(jié)果: from statsmodels.tsa.seasonal import seasonal_decompose decomposition = seasonal_decompose(ts_log) trend = decomposition.trend seasonal = decomposition.seasonal residual = decomposition.resid plt.subplot(411) plt.plot(ts_log, label='Original') plt.legend(loc='best') plt.subplot(412) plt.plot(trend, label='Trend') plt.legend(loc='best') plt.subplot(413) plt.plot(seasonal,label='Seasonality') plt.legend(loc='best') plt.subplot(414) plt.plot(residual, label='Residuals') plt.legend(loc='best') plt.tight_layout() 在這里我們可以看到趨勢(shì),季節(jié)性從數(shù)據(jù)分離,我們可以建立殘差的模型,讓我們檢查殘差的穩(wěn)定性: ts_log_decompose = residual ts_log_decompose.dropna(inplace=True) test_stationarity(ts_log_decompose) DF測(cè)試統(tǒng)計(jì)量明顯低于1%的臨界值,這樣時(shí)間序列是非常接近穩(wěn)定。你也可以嘗試高級(jí)的分解技術(shù)產(chǎn)生更好的結(jié)果。同時(shí),你應(yīng)該注意到, 在這種情況下將殘差轉(zhuǎn)換為原始值對(duì)未來數(shù)據(jù)不是很直觀。 預(yù)測(cè)時(shí)間序列 我們看到不同的技術(shù)和它們有效的工作使得時(shí)間序列得以穩(wěn)定。讓我們建立差分后的時(shí)間序列模型,因?yàn)樗呛苁軞g迎的技術(shù),也相對(duì)更容易添加噪音和季節(jié)性倒回到預(yù)測(cè)殘差。在執(zhí)行趨勢(shì)和季節(jié)性評(píng)估技術(shù)上,有兩種情況:
讓我給你簡(jiǎn)要介紹一下ARIMA,我不會(huì)介紹技術(shù)細(xì)節(jié),但如果你希望更有效地應(yīng)用它們,你應(yīng)該理解這些概念的細(xì)節(jié)。ARIMA代表自回歸整合移動(dòng)平均數(shù)。平穩(wěn)時(shí)間序列的ARIMA預(yù)測(cè)的只不過是一個(gè)線性方程(如線性回歸)。預(yù)測(cè)依賴于ARIMA模型參數(shù)(p d q)。
在這里一個(gè)重要的問題是如何確定“p”和“q”的值。我們使用兩個(gè)坐標(biāo)來確定這些數(shù)字。我們來討論它們。
時(shí)間序列的自回歸函數(shù)和部分自回歸函數(shù)可以在差分后繪制為: #ACF and PACF plots: from statsmodels.tsa.stattools import acf, pacf lag_acf = acf(ts_log_diff, nlags=20) lag_pacf = pacf(ts_log_diff, nlags=20, method='ols') #Plot ACF: plt.subplot(121) plt.plot(lag_acf) plt.axhline(y=0,linestyle='--',color='gray') plt.axhline(y=-1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray') plt.axhline(y=1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray') plt.title('Autocorrelation Function') #Plot PACF: plt.subplot(122) plt.plot(lag_pacf) plt.axhline(y=0,linestyle='--',color='gray') plt.axhline(y=-1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray') plt.axhline(y=1.96/np.sqrt(len(ts_log_diff)),linestyle='--',color='gray') plt.title('Partial Autocorrelation Function') plt.tight_layout() 在這個(gè)點(diǎn)上,0的每一條邊上的兩條虛線之間是置信區(qū)間。這些可以用來確定“p”和“q”的值: 1、p-部分自相關(guān)函數(shù)表第一次截?cái)嗟纳蠈又眯艆^(qū)間是滯后值。如果你仔細(xì)看,該值是p=2。 2、q- 自相關(guān)函數(shù)表第一次截?cái)嗟纳蠈又眯艆^(qū)間是滯后值。如果你仔細(xì)看,該值是q=2。 現(xiàn)在,考慮個(gè)體以及組合效應(yīng)建立3個(gè)不同的ARIMA模型。我也會(huì)發(fā)布各自的RSS(是一種描述和同步網(wǎng)站內(nèi)容的格式,是使用最廣泛的XML應(yīng)用)。請(qǐng)注意,這里的RSS是指殘差值,而不是實(shí)際序列。 首先,我們需要上傳ARIMA模型。 from statsmodels.tsa.arima_model import ARIMA p,d,q值可以指定使用ARIMA的命令參數(shù)即采用一個(gè)元(p,d,q)。建立三種情況下的模型: 自回歸(AR)模型: model = ARIMA(ts_log, order=(2, 1, 0)) results_AR = model.fit(disp=-1) plt.plot(ts_log_diff) plt.plot(results_AR.fittedvalues, color='red') plt.title('RSS: %.4f'% sum((results_AR.fittedvalues-ts_log_diff)**2)) 組合模型 model = ARIMA(ts_log, order=(0, 1, 2)) results_MA = model.fit(disp=-1) plt.plot(ts_log_diff) plt.plot(results_MA.fittedvalues, color='red') plt.title('RSS: %.4f'% sum((results_MA.fittedvalues-ts_log_diff)**2)) 移動(dòng)平均數(shù)(MA )模型 model = ARIMA(ts_log, order=(2, 1, 2)) results_ARIMA = model.fit(disp=-1) plt.plot(ts_log_diff) plt.plot(results_ARIMA.fittedvalues, color='red') plt.title('RSS: %.4f'% sum((results_ARIMA.fittedvalues-ts_log_diff)**2)) 在這里我們可以看到,自回歸函數(shù)模型和移動(dòng)平均數(shù)模型幾乎有相同的RSS,但相結(jié)合效果顯著更好。現(xiàn)在,我們只剩下最后一步,即把這些值倒回到原始區(qū)間。 倒回到原始區(qū)間 既然組合模型獲得更好的結(jié)果,讓我們將它倒回原始值,看看它如何執(zhí)行。第一步是作為一個(gè)獨(dú)立的序列,存儲(chǔ)預(yù)測(cè)結(jié)果,觀察它。 predictions_ARIMA_diff = pd.Series(results_ARIMA.fittedvalues, copy=True) print predictions_ARIMA_diff.head() 注意,這些是從‘1949-02-01’開始,而不是第一個(gè)月。為什么?這是因?yàn)槲覀儗⒌谝粋€(gè)月份取為滯后值,一月前面沒有可以減去的元素。將差分轉(zhuǎn)換為對(duì)數(shù)尺度的方法是這些差值連續(xù)地添加到基本值。一個(gè)簡(jiǎn)單的方法就是首先確定索引的累計(jì)總和,然后將其添加到基本值。累計(jì)總和可以在下面找到: predictions_ARIMA_diff_cumsum = predictions_ARIMA_diff.cumsum() print predictions_ARIMA_diff_cumsum.head() 你可以在頭腦使用之前的輸出結(jié)果進(jìn)行回算,檢查這些是否正確的。接下來我們將它們添加到基本值。為此我們將使用所有的值創(chuàng)建一個(gè)序列作為基本值,并添加差值。我們這樣做: predictions_ARIMA_log = pd.Series(ts_log.ix[0], index=ts_log.index) predictions_ARIMA_log = predictions_ARIMA_log.add(predictions_ARIMA_diff_cumsum,fill_value=0) predictions_ARIMA_log.head() 第一個(gè)元素是基本值本身,從基本值開始值累計(jì)添加。最后一步是將指數(shù)與原序列比較。 predictions_ARIMA = np.exp(predictions_ARIMA_log) plt.plot(ts) plt.plot(predictions_ARIMA) plt.title('RMSE: %.4f'% np.sqrt(sum((predictions_ARIMA-ts)**2)/len(ts)))
最后我們獲得一個(gè)原始區(qū)間的預(yù)測(cè)結(jié)果。雖然不是一個(gè)很好的預(yù)測(cè)。但是你獲得了思路對(duì)嗎?現(xiàn)在,我把它留個(gè)你去進(jìn)一步改進(jìn),做一個(gè)更好的方案。 最后注意 在本文中,我試圖提供你們一個(gè)標(biāo)準(zhǔn)方法去解決時(shí)間序列問題。這個(gè)不可能達(dá)到一個(gè)更好的時(shí)間,因?yàn)榻裉焓俏覀兊男⌒途幊恬R拉松,挑戰(zhàn)你們是否可以解決類似的問題。我們廣泛的討論了穩(wěn)定性的概念和最終的預(yù)測(cè)殘差。這是一個(gè)漫長(zhǎng)的過程,我跳過了一些統(tǒng)計(jì)細(xì)節(jié),我鼓勵(lì)大家使用這些作為參考材料。如果你不想復(fù)制粘貼,你可以從我的GitHub庫(kù)下載iPython筆記本的代碼。 |
|