丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能開發(fā)者 正文
發(fā)私信給AI研習(xí)社
發(fā)送

0

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

本文作者: AI研習(xí)社 2017-02-17 12:08
導(dǎo)語:專家手把手帶你做時(shí)間序列預(yù)測練習(xí)。

編者按:本文是澳大利亞知名機(jī)器學(xué)習(xí)專家 Jason Brownlee 撰寫的教程,極其全面細(xì)致,一步步向讀者解釋如何操作,以及為什么這么做。雷鋒網(wǎng)整理編譯,特與大家分享。更多AI開發(fā)技術(shù)文章,請關(guān)注AI研習(xí)社(微信號:okweiwu)。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

Jason Brownlee:時(shí)間序列預(yù)測法是一個(gè)過程,而獲得良好預(yù)測結(jié)果的唯一途徑是實(shí)踐這個(gè)過程。

在本教程中,您將了解如何利用Python語言來預(yù)測波士頓每月持械搶劫案發(fā)生的數(shù)量。

本教程所述為您提供了一套處理時(shí)間序列預(yù)測問題的框架,包括方法步驟和工具,通過實(shí)踐,可以用它來解決自己遇到的相關(guān)問題。

本教程結(jié)束之后,您將了解:

  • 如何核查Python環(huán)境并準(zhǔn)確地定義一個(gè)時(shí)間序列預(yù)測問題。

  • 如何構(gòu)建一套測試工具鏈,用于評估模型,開發(fā)預(yù)測原型。以及如何通過時(shí)間序列分析工具更好地理解你的問題。

  • 如何開發(fā)自回歸積分滑動(dòng)平均模型(ARIMA),將其保存到文件,并在之后加載它對新的時(shí)間步驟進(jìn)行預(yù)測。

讓我們開始吧。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

波士頓

概述

在本教程中,我們將端到端地來解析一個(gè)時(shí)間序列預(yù)測工程,從下載數(shù)據(jù)集、定義問題到訓(xùn)練出最終模型并進(jìn)行預(yù)測。

該工程并不面面俱到,但展示了如何通過系統(tǒng)性地處理時(shí)間序列預(yù)測問題,來快速獲得好的結(jié)果。

我們將通過如下步驟來解析該工程 :

  1. 環(huán)境配置.

  2. 問題描述

  3. 測試工具鏈

  4. 持續(xù)性.

  5. 數(shù)據(jù)分析

  6. ARIMA 模型

  7. 模型驗(yàn)證

該部分提供一個(gè)解決時(shí)間序列預(yù)測問題的模板,你可以套用自己的數(shù)據(jù)集。

1. 環(huán)境配置

本教程假設(shè)在已安裝好了SciPy及其相關(guān)依賴庫的環(huán)境下進(jìn)行,包括:

  1. SciPy

  2. NumPy

  3. Matplotlib

  4. Pandas

  5. scikit-learn

  6. statsmodels

我使用的是Python2.7。該腳本將幫助你確認(rèn)你安裝這些庫的版本。

# scipy

import scipy

print('scipy: {}'.format(scipy.__version__))

# numpy

import numpy

print('numpy: {}'.format(numpy.__version__))

# matplotlib

import matplotlib

print('matplotlib: {}'.format(matplotlib.__version__))

# pandas

import pandas

print('pandas: {}'.format(pandas.__version__))

# scikit-learn

import sklearn

print('sklearn: {}'.format(sklearn.__version__))

# statsmodels

import statsmodels

print('statsmodels: {}'.format(statsmodels.__version__))


我編寫該教程的所用的開發(fā)環(huán)境顯示的結(jié)果如下:

scipy: 0.18.1

numpy: 1.11.2

matplotlib: 1.5.3

pandas: 0.19.1

sklearn: 0.18.1

statsmodels: 0.6.1 

2. 問題描述

我們研究的問題是預(yù)測美國波士頓每月持械搶劫案的數(shù)量。

該數(shù)據(jù)集提供了從1966年1月到1975年10月在波士頓每月發(fā)生的的武裝搶劫案的數(shù)量, 或者說,是這十年間的數(shù)據(jù)。

這些值是一些記錄的觀察計(jì)數(shù),總有118個(gè)觀察值。

數(shù)據(jù)集來自于McCleary&Hay(1980)。

您可以了解有關(guān)此數(shù)據(jù)集的更多信息,并直接從 DataMarket 下載。

下載地址:https://datamarket.com/data/set/22ob/monthly-boston-armed-robberies-jan1966-oct1975-deutsch-and-alt-1977#!ds=22ob&display=line

將數(shù)據(jù)集下載為CSV文件,并將其放在當(dāng)前工作目錄中,文件名為“robberies.csv”。

3.測試工具鏈

我們必須開發(fā)一套測試工具鏈來審查數(shù)據(jù)和評估候選模型。

這包含兩個(gè)步驟:

1.定義好驗(yàn)證數(shù)據(jù)集。

2.開發(fā)一套模型評估方法。

3.1 驗(yàn)證數(shù)據(jù)集

這個(gè)數(shù)據(jù)集不是當(dāng)前時(shí)間段的數(shù)據(jù)集。 這意味著我們不能輕輕松松收集更新后的數(shù)據(jù)來驗(yàn)證該模型。

因此,我們假設(shè)現(xiàn)在是1974年10月,并將分析和模型選擇的數(shù)據(jù)集里扣除最后一年的數(shù)據(jù)。

最后一年的數(shù)據(jù)將用于驗(yàn)證生成的最終模型。

下面的代碼會(huì)加載該數(shù)據(jù)集為Pandas序列對象并將其切分成兩部分,一個(gè)用于模型開發(fā)(dataset.csv)和另一個(gè)用于驗(yàn)證(validation.csv)。

from pandas import   Series

series = Series.from_csv('robberies.csv', header=0)

split_point = len(series) - 12

dataset, validation = series[0:split_point], series[split_point:]

print('Dataset   %d, Validation %d' % (len(dataset), len(validation)))

dataset.to_csv('dataset.csv')

validation.to_csv('validation.csv')

運(yùn)行該示例將會(huì)創(chuàng)建兩個(gè)文件并打印出每個(gè)文件中的觀察數(shù)。

1. Dataset 106, Validation 12

這些文件的具體內(nèi)容是:

  • dataset.csv:1966年1月至1974年10月的觀察(106次觀察)

  • validation.csv:1974年11月至1975年10月的觀察(12次觀察)

驗(yàn)證數(shù)據(jù)集大小是原始數(shù)據(jù)集的10%。

請注意,由于保存的數(shù)據(jù)集中沒有標(biāo)題行,因此,稍后處理這些文件時(shí),我們也不需要滿足此要求。

3.2. 模型驗(yàn)證

模型評估將僅對上一節(jié)中準(zhǔn)備的dataset.csv中的數(shù)據(jù)進(jìn)行處理。

模型評估涉及兩個(gè)要素:

1. 評價(jià)指標(biāo)。

2. 測試策略。

3.2.1評價(jià)指標(biāo)

這些觀察值是搶劫案的計(jì)數(shù)。

我們將使用均方根誤差(RMSE)的方式來評價(jià)預(yù)測的好壞。這將給予錯(cuò)誤的預(yù)測更多的權(quán)重,并且將具有與原始數(shù)據(jù)相同的單位。

在RMSE進(jìn)行計(jì)算和報(bào)告之前,必須反轉(zhuǎn)對數(shù)據(jù)的所有轉(zhuǎn)換,以使不同方法的效果可直接比較。

我們可以使用scikit-learn庫的輔助函數(shù)mean_squared_error()來執(zhí)行RMSE計(jì)算,該函數(shù)計(jì)算出了預(yù)期值列表(測試集)和預(yù)測列表之間的均方誤差。 然后我們可以取這個(gè)值的平方根來作為一個(gè)RMSE分?jǐn)?shù)。

例如: 

  1. from sklearn.metrics import mean_squared_error

  2. from math import sqrt

  3. ...

  4. test = ...

  5. predictions = ...

  6. mse = mean_squared_error(test, predictions)

  7. rmse = sqrt(mse)

  8. print('RMSE:   %.3f' % rmse)

3.2.2 測試策略

將使用步進(jìn)驗(yàn)證的方式(walk-forward)來評估候選模型。

這是因?yàn)樵搯栴}定義需要滾動(dòng)式預(yù)測的模型。給定所有可用數(shù)據(jù),這需要逐步進(jìn)行預(yù)測。

步進(jìn)驗(yàn)證的方式將按照如下幾步執(zhí)行:

  • 數(shù)據(jù)集的前50%將被用來訓(xùn)練模型。

  • 剩余的50%的數(shù)據(jù)集將被迭代并測試模型。

  • 對于測試數(shù)據(jù)集中的每個(gè)步驟:

  • 訓(xùn)練該模型

  • 利用該模型預(yù)測一次,并經(jīng)預(yù)測結(jié)果保存下來用于之后的驗(yàn)證

  • 測試數(shù)據(jù)集的數(shù)據(jù)作為下一個(gè)迭代的訓(xùn)練集數(shù)據(jù)

  • 對在測試數(shù)據(jù)集迭代期間進(jìn)行的預(yù)測結(jié)果進(jìn)行評估,并報(bào)告RMSE得分。

由于較小的數(shù)據(jù)規(guī)模,我們將允許在每次預(yù)測之前,在給定所有可用數(shù)據(jù)的情況下重新訓(xùn)練模型。

我們可以使用簡單的NumPy和Python來編寫測試工具的代碼。

首先,我們可以將數(shù)據(jù)集直接分成訓(xùn)練和測試集。 我們總要將加載的數(shù)據(jù)轉(zhuǎn)換為float32類型,以防止仍然有一些數(shù)據(jù)為String或Integer數(shù)據(jù)類型。

  1. # prepare data

  2. X = series.values

  3. X = X.astype('float32')

  4. train_size = int(len(X) * 0.50)

  5. train, test = X[0:train_size], X[train_size:]

接下來,我們可以時(shí)間步長遍歷測試數(shù)據(jù)集。訓(xùn)練數(shù)據(jù)集存儲在一個(gè)Python的list對象中,因?yàn)槲覀冃枰诿看蔚泻苋菀椎母郊右恍┯^察值,Numpy數(shù)組連接有些overkill。

模型進(jìn)行的預(yù)測,按慣例稱為yhat。這是由于結(jié)果或觀察被稱為y,而yhat(有上標(biāo)“^”的y)是用于預(yù)測y變量的數(shù)學(xué)符號。

打印預(yù)測和觀察結(jié)果,對每個(gè)觀察值進(jìn)行完整性檢查,以防模型存在問題。

  1. # walk-forward   validation

  2. history = [x for x in train]

  3. predictions = list()

  4. for i in range(len(test)):

  5. # predict

  6. yhat = ...

  7. predictions.append(yhat)

  8. # observation

  9. obs = test[i]

  10. history.append(obs)

  11. print('>Predicted=%.3f,   Expected=%3.f' % (yhat, obs))

4. Persistence(持續(xù)性模型)

在數(shù)據(jù)分析和建模陷入困境之前的第一步是建立一個(gè)評估原型。

這里將為利用測試工具進(jìn)行模型評估和性能測量,分別提供一套模版。通過該性能測量,可以將當(dāng)前模型和其他更復(fù)雜的預(yù)測模型進(jìn)行比較。

時(shí)間序列預(yù)測的預(yù)測原型被稱為天真預(yù)測或Persistence。

在這里,先前時(shí)間步驟的觀察結(jié)果將被用作于下一時(shí)間步長的預(yù)測。

我們可以將其直接插入上一節(jié)中定義的測試工具中。

下面羅列了完整的代碼:

  1. from pandas import   Series

  2. from sklearn.metrics import mean_squared_error

  3. from math import sqrt

  4. # load data

  5. series = Series.from_csv('dataset.csv')

  6. # prepare data

  7. X = series.values

  8. X = X.astype('float32')

  9. train_size = int(len(X) * 0.50)

  10. train, test = X[0:train_size], X[train_size:]

  11. # walk-forward   validation

  12. history = [x for x in train]

  13. predictions = list()

  14. for i in range(len(test)):

  15. # predict

  16. yhat = history[-1]

  17. predictions.append(yhat)

  18. # observation

  19. obs = test[i]

  20. history.append(obs)

  21. print('>Predicted=%.3f,   Expected=%3.f' % (yhat, obs))

  22. # report performance

  23. mse = mean_squared_error(test, predictions)

  24. rmse = sqrt(mse)

  25. print('RMSE:   %.3f' % rmse)

運(yùn)行測試工具,打印測試數(shù)據(jù)集中每次迭代的預(yù)測值和實(shí)際觀察值。

示例到進(jìn)行打印模型的RMSE這一步結(jié)束。

在該示例中,我們可以看到持久性模型實(shí)現(xiàn)了51.844的RMSE。 這意味著,對于每個(gè)預(yù)測,該模型中平均有51次搶劫值預(yù)測是錯(cuò)誤的。

  1. ...

  2. >Predicted=241.000, Expected=287

  3. >Predicted=287.000, Expected=355

  4. >Predicted=355.000, Expected=460

  5. >Predicted=460.000, Expected=364

  6. >Predicted=364.000, Expected=487

  7. RMSE: 51.844

我們現(xiàn)在有了一個(gè)預(yù)測方法和性能評估的原型; 現(xiàn)在我們可以開始深入數(shù)據(jù)。

5. 數(shù)據(jù)分析

我們可以使用統(tǒng)計(jì)匯總和數(shù)據(jù)的繪圖,來快速了解該預(yù)測問題的數(shù)據(jù)結(jié)構(gòu)。

在本節(jié)中,我們將從四個(gè)角度來看數(shù)據(jù):

1.摘要統(tǒng)計(jì)。

2.線圖。

3.密度圖。

4.盒型-虛線圖。

5.1 摘要統(tǒng)計(jì)

利用文本編輯器中打開數(shù)據(jù)dataset.csv文件或原始的robberies.csv文件,并查看數(shù)據(jù)。

快速檢查表明,數(shù)據(jù)集里沒有明顯丟失的觀察數(shù)據(jù)。 我們可能已經(jīng)更早的發(fā)現(xiàn)了像NaN或'?'等值數(shù),如果我們試圖強(qiáng)制序列化數(shù)據(jù)為浮點(diǎn)值。

摘要統(tǒng)計(jì)提供了觀察值的快速預(yù)覽。 它可以幫助我們快速了解我們正在使用的東西。

以下示例為計(jì)算并打印時(shí)間系列的摘要統(tǒng)計(jì)信息。 

  1. from pandas import   Series

  2. series = Series.from_csv('dataset.csv')

  3. print(series.describe())

運(yùn)行該示例會(huì)提供大量的摘要信息供回顧。

這些統(tǒng)計(jì)數(shù)據(jù)包含的一些信息為:

  • 觀察次數(shù)(計(jì)數(shù))與我們的期望相符,這意味著我們將數(shù)據(jù)正確處理了。

  • 平均值約為173,我們可以想象出我們在這個(gè)序列中的級別。

  • 在112次搶劫時(shí),標(biāo)準(zhǔn)偏差(平均值的平均分布)相對較大。

  • 百分位數(shù)與標(biāo)準(zhǔn)差一致表明數(shù)據(jù)有很大的差異。

  1. count    106.000000

  2. mean     173.103774

  3. std      112.231133

  4. min       29.000000

  5. 25%       74.750000

  6. 50%      144.500000

  7. 75%      271.750000

  8. max      487.000000

對于序列中比較大的變化將可能模型很難進(jìn)行高度準(zhǔn)確的預(yù)測,如果它是由隨機(jī)波動(dòng)(例如,非系統(tǒng)的)引起,

5.2 線圖

畫一個(gè)時(shí)間序列的線圖可以對該問題提供很多深入的信息。

下面的示例創(chuàng)建并顯示出數(shù)據(jù)集的線圖。

  1. from pandas import   Series

  2. from matplotlib   import pyplot

  3. series = Series.from_csv('dataset.csv')

  4. series.plot()

  5. pyplot.show()

運(yùn)行示例并查看繪圖。 注意系列中的任何明顯的時(shí)間結(jié)構(gòu)。

  • 圖中的一些觀察結(jié)果包括:

  • 隨著時(shí)間的推移,劫案有增加的趨勢。

  • 似乎沒有任何明顯的異常值。

  • 每年都有相對較大的波動(dòng),上下波動(dòng)。

  • 后幾年的波動(dòng)似乎大于前幾年的波動(dòng)。

  • 整體趨勢表明該數(shù)據(jù)集幾乎肯定不是穩(wěn)定的,并且波形的明顯變化也可能對此有所提示。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

每月波士頓搶劫案數(shù)據(jù)線圖

這些簡單的觀察結(jié)果表明,我們可以看到對趨勢進(jìn)行建模和從時(shí)間序列中將它提取出來的好處。

或者,我們可以使用差分法從而使序列的建模平穩(wěn)。如果后期波動(dòng)有增長趨勢,我們甚至可能需要兩個(gè)差分到不同級別。

5.3 密度圖

提取出密度圖,可以提供對數(shù)據(jù)結(jié)構(gòu)的進(jìn)一步了解。

下面的示例創(chuàng)建了沒有任何時(shí)間結(jié)構(gòu)的觀測值的直方圖和密度圖。

  1. from pandas import   Series

  2. from matplotlib   import pyplot

  3. series = Series.from_csv('dataset.csv')

  4. pyplot.figure(1)

  5. pyplot.subplot(211)

  6. series.hist()

  7. pyplot.subplot(212)

  8. series.plot(kind='kde')

  9. pyplot.show()

運(yùn)行示例并查看繪圖。

圖中展示的一些分析結(jié)果包括:

  • 分布不是高斯分布。

  • 分布是左移的,可以是指數(shù)或雙高斯分布

    時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

每月波士頓搶劫密案數(shù)量密度圖

我們可以看到在建模之前進(jìn)行一些數(shù)據(jù)的維度變換的一些益處。

5.4 盒形-虛線圖

我們可以按年份對月度數(shù)據(jù)進(jìn)行分組,并了解每年觀察值的分布情況,以及觀察值可能如何變化。

我們確實(shí)希望從數(shù)據(jù)中看到一些趨勢(增加平均值或中位數(shù)),但看到其余的分布是如何變化的可能會(huì)更有趣。

下面的示例將觀察值按照年份劃分,并為每個(gè)觀察年創(chuàng)建一個(gè)盒型-虛線圖。 最后一年(1974年)只包含10個(gè)月,可能與其他有12個(gè)月的觀察值的年份相比會(huì)無效。 因此,只有1966年和1973年之間的數(shù)據(jù)被繪制。

  1. from pandas import   Series

  2. from pandas import   DataFrame

  3. from pandas import   TimeGrouper

  4. from matplotlib   import pyplot

  5. series = Series.from_csv('dataset.csv')

  6. groups = series['1966':'1973'].groupby(TimeGrouper('A'))

  7. years = DataFrame()

  8. for name, group in groups:

  9. years[name.year] = group.values

  10. years.boxplot()

  11. pyplot.show()

圖中的一些觀察結(jié)果包括:

  • 每年的中間值(紅線)顯示可能不是線性的趨勢

  • 散列值和中間50%的數(shù)據(jù)(藍(lán)色框)不同,但時(shí)間長了可能會(huì)有變化。

  • 較早的年份,也許是前2年,與數(shù)據(jù)集的其余部分有很大的不同。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

波士頓每月?lián)尳侔笖?shù)目的盒形-虛線圖

觀察結(jié)果表明,年度波動(dòng)可能不是系統(tǒng)性的,難以模擬。 他們還建議將建模的前兩年的數(shù)據(jù)從模型分離出來可能有一些好處,如果確實(shí)不同。

這種對數(shù)據(jù)進(jìn)行年度觀察是一個(gè)有趣的方法,而且可以通過查看年度匯總統(tǒng)計(jì)數(shù)據(jù)和其中的變化,來進(jìn)一步跟進(jìn)未來的變化。

接下來,我們可以開始查看該序列的預(yù)測模型。

6. ARIMA 模型

在本節(jié)中,我們將會(huì)針對該問題開發(fā)自回歸積分滑動(dòng)平均模型,即ARIMA模型。

我們將其分四個(gè)步驟:

1.開發(fā)一套手動(dòng)配置的ARIMA模型。

2.使用ARIMA的網(wǎng)格搜索來找到優(yōu)化的模型。

3.預(yù)測殘差的分析,以評估模型中的所有偏差。

4.使用能量變換探索模型的改進(jìn)。

6.1 手動(dòng)配置ARIMA

Nasonasonal ARIMA(p,d,q)需要三個(gè)參數(shù),并且通常是傳統(tǒng)地進(jìn)行手動(dòng)配置。

時(shí)間序列數(shù)據(jù)的分析。假設(shè)我們使用的是靜態(tài)時(shí)間序列。

時(shí)間序列基本上肯定是非靜態(tài)的。我們可以通過首先區(qū)分序列,并使用統(tǒng)計(jì)測試,來確保結(jié)果是靜態(tài)的。

下面的示例創(chuàng)建一個(gè)靜態(tài)版本的序列,并將其保存到文件stationary.csv。

  1. from pandas import   Series

  2. from statsmodels.tsa.stattools   import adfuller

  3.  

  4. # create a differe

  5. def difference(dataset):

  6. diff = list()

  7. for i in range(1, len(dataset)):

  8. value = dataset[i] - dataset[i - 1]

  9. diff.append(value)

  10. return Series(diff)

  11.  

  12. series = Series.from_csv('dataset.csv')

  13. X = series.values

  14. # difference data

  15. stationary = difference(X)

  16. stationary.index = series.index[1:]

  17. # check if stationary

  18. result = adfuller(stationary)

  19. print('ADF   Statistic: %f' % result[0])

  20. print('p-value:   %f' % result[1])

  21. print('Critical   Values:')

  22. for key, value in result[4].items():

  23. print('\t%s:   %.3f' % (key, value))

  24. # save

  25. stationary.to_csv('stationary.csv')

運(yùn)行示例輸出統(tǒng)計(jì)顯著性測試的結(jié)果,以表明序列是否靜止。 具體來說,強(qiáng)化迪基-福勒檢驗(yàn)。

結(jié)果表明,測試的統(tǒng)計(jì)值-3.980946小于-2.893的5%時(shí)的臨界值。 這表明我們可以否決具有小于5%的顯著性水平的零假設(shè)(即,結(jié)果為統(tǒng)計(jì)結(jié)果的概率很低)。

拒絕零假設(shè)意味著過程沒有單位根,反過來說就是,該時(shí)間序列是固定的或者不具有時(shí)間依賴性結(jié)構(gòu)。

  1. ADF Statistic: -3.980946

  2. p-value: 0.001514

  3. Critical Values:

  4. 5%: -2.893

  5. 1%: -3.503

  6. 10%: -2.584

這表明至少需要一個(gè)級別的差分。 我們的ARIMA模型中的d參數(shù)應(yīng)至少為1的值。

下一步是分別選擇自回歸(AR)和移動(dòng)平均(MA)參數(shù)的滯后值,p和q。

我們可以通過審查自相關(guān)函數(shù)(ACF)和部分自相關(guān)函數(shù)(PACF)圖來做到這一點(diǎn)。

以下示例為該序列創(chuàng)建ACF和PACF圖。

  1. from pandas import   Series

  2. from statsmodels.graphics.tsaplots   import plot_acf

  3. from statsmodels.graphics.tsaplots   import plot_pacf

  4. from matplotlib   import pyplot

  5. series = Series.from_csv('dataset.csv')

  6. pyplot.figure()

  7. pyplot.subplot(211)

  8. plot_acf(series, ax=pyplot.gca())

  9. pyplot.subplot(212)

  10. plot_pacf(series, ax=pyplot.gca())

  11. pyplot.show()

運(yùn)行示例并查看繪圖,詳細(xì)了解一下如何設(shè)置ARIMA模型的p和q變量。

下面是從圖中得到的一些觀察結(jié)論。

  • ACF顯示1個(gè)月的顯著滯后。

  • PACF顯示了大約2個(gè)月的顯著滯后,滯后至大約12個(gè)月以后。

  • ACF和PACF在同一點(diǎn)顯示出下降,可能是AR和MA參數(shù)的混合。

p和q值的正確的起點(diǎn)是1或2。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

每月波士頓搶劫案數(shù)量的ACF和PACF圖

這個(gè)快速分析結(jié)果表明ARIMA(1,1,2)對原始數(shù)據(jù)可能是一個(gè)很好的切入點(diǎn)。

雷鋒網(wǎng)了解,實(shí)驗(yàn)表明,這套ARIMA的配置不會(huì)收斂,并引起底層庫的錯(cuò)誤。一些實(shí)驗(yàn)表明,該模型表現(xiàn)不太穩(wěn)定,同時(shí)定義了非零的AR和MA階數(shù)。

該模型可以簡化為ARIMA(0,1,2)。 下面的示例演示了此ARIMA模型在測試工具上的性能。

  1. from pandas import   Series

  2. from sklearn.metrics import mean_squared_error

  3. from statsmodels.tsa.arima_model   import ARIMA

  4. from math import sqrt

  5. # load data

  6. series = Series.from_csv('dataset.csv')

  7. # prepare data

  8. X = series.values

  9. X = X.astype('float32')

  10. train_size = int(len(X) * 0.50)

  11. train, test = X[0:train_size], X[train_size:]

  12. # walk-forward   validation

  13. history = [x for x in train]

  14. predictions = list()

  15. for i in range(len(test)):

  16. # predict

  17. model = ARIMA(history, order=(0,1,2))

  18. model_fit = model.fit(disp=0)

  19. yhat = model_fit.forecast()[0]

  20. predictions.append(yhat)

  21. # observation

  22. obs = test[i]

  23. history.append(obs)

  24. print('>Predicted=%.3f,   Expected=%3.f' % (yhat, obs))

  25. # report performance

  26. mse = mean_squared_error(test, predictions)

  27. rmse = sqrt(mse)

  28. print('RMSE:   %.3f' % rmse)

運(yùn)行此示例結(jié)果的RMSE值為49.821,低于持續(xù)性模型(Persistence)。

  1. ...

  2. >Predicted=280.614, Expected=287

  3. >Predicted=302.079, Expected=355

  4. >Predicted=340.210, Expected=460

  5. >Predicted=405.172, Expected=364

  6. >Predicted=333.755, Expected=487

  7. RMSE: 49.821

這是一個(gè)好的開始,但是我們可以達(dá)到改進(jìn)結(jié)果通過一個(gè)配置更好的ARIMA模型。

6.2 網(wǎng)格搜索ARIMA超參數(shù)

許多ARIMA配置在此數(shù)據(jù)集上不穩(wěn)定,但可能有其他超參數(shù)導(dǎo)向一個(gè)表現(xiàn)良好的模型。

在本節(jié)中,我們將搜索p,d和q的值,以找出不會(huì)導(dǎo)致錯(cuò)誤的組合,并找到可獲得最佳性能的組合。 我們將使用網(wǎng)格搜索來探索整數(shù)值子集中的所有組合。

具體來說,我們將搜索以下參數(shù)的所有組合:

  • p:      0 - 12.

  • d:      0 - 3.

  • q:      0 -12.

這是(13 * 4 * 13),或676,測試工具的運(yùn)行結(jié)果,并且將花費(fèi)需要一些時(shí)間用來執(zhí)行。

下面是利用網(wǎng)格搜索的測試工具的完整示例:

  1. import warnings

  2. from pandas import   Series

  3. from statsmodels.tsa.arima_model   import ARIMA

  4. from sklearn.metrics import mean_squared_error

  5. from math import sqrt

  6.  

  7. # evaluate an ARIMA   model for a given order (p,d,q) and return RMSE

  8. def   evaluate_arima_model(X, arima_order):

  9. # prepare training   dataset

  10. X = X.astype('float32')

  11. train_size = int(len(X) * 0.50)

  12. train, test = X[0:train_size], X[train_size:]

  13. history = [x for x in train]

  14. # make predictions

  15. predictions = list()

  16. for t in range(len(test)):

  17. model = ARIMA(history, order=arima_order)

  18. model_fit = model.fit(disp=0)

  19. yhat = model_fit.forecast()[0]

  20. predictions.append(yhat)

  21. history.append(test[t])

  22. # calculate out of   sample error

  23. mse = mean_squared_error(test, predictions)

  24. rmse = sqrt(mse)

  25. return rmse

  26.  

  27. # evaluate   combinations of p, d and q values for an ARIMA model

  28. def evaluate_models(dataset, p_values, d_values, q_values):

  29. dataset = dataset.astype('float32')

  30. best_score, best_cfg = float("inf"), None

  31. for p in p_values:

  32. for d in d_values:

  33. for q in q_values:

  34. order = (p,d,q)

  35. try:

  36. mse = evaluate_arima_model(dataset, order)

  37. if mse < best_score:

  38. best_score, best_cfg = mse, order

  39. print('ARIMA%s   MSE=%.3f' % (order,mse))

  40. except:

  41. continue

  42. print('Best   ARIMA%s MSE=%.3f' % (best_cfg, best_score))

  43.  

  44. # load dataset

  45. series = Series.from_csv('dataset.csv')

  46. # evaluate parameters

  47. p_values = range(0,13)

  48. d_values = range(0, 4)

  49. q_values = range(0, 13)

  50. warnings.filterwarnings("ignore")

  51. evaluate_models(series.values, p_values, d_values, q_values)

運(yùn)行該示例并運(yùn)行所有組合,并將無錯(cuò)誤收斂的結(jié)果報(bào)出來。

該示例當(dāng)前硬件上運(yùn)行至少需要2小時(shí)。

結(jié)果表明,最佳配置為ARIMA(0,1,2),巧合的是,這在前面的部分中已經(jīng)被證明。

  1. ...

  2. ARIMA(6, 1, 0) MSE=52.437

  3. ARIMA(6, 2, 0) MSE=58.307

  4. ARIMA(7, 1, 0) MSE=51.104

  5. ARIMA(7, 1, 1) MSE=52.340

  6. ARIMA(8, 1, 0) MSE=51.759

  7. Best ARIMA(0, 1, 2) MSE=49.821

6.3 檢查殘差

對一個(gè)模型來說,一個(gè)不錯(cuò)的最終檢查,是檢查其殘差預(yù)測誤差。

理想情況下,殘差的分布應(yīng)該是符合零均值的高斯分布。

我們可以通過用直方圖和密度圖繪制殘差來檢查這一點(diǎn)。

以下示例為計(jì)算測試集上預(yù)測的殘差,并創(chuàng)建該密度圖。

  1. from pandas import   Series

  2. from pandas import   DataFrame

  3. from sklearn.metrics import mean_squared_error

  4. from statsmodels.tsa.arima_model   import ARIMA

  5. from math import sqrt

  6. from matplotlib   import pyplot

  7. # load data

  8. series = Series.from_csv('dataset.csv')

  9. # prepare data

  10. X = series.values

  11. X = X.astype('float32')

  12. train_size = int(len(X) * 0.50)

  13. train, test = X[0:train_size], X[train_size:]

  14. # walk-foward   validation

  15. history = [x for x in train]

  16. predictions = list()

  17. for i in range(len(test)):

  18. # predict

  19. model = ARIMA(history, order=(0,1,2))

  20. model_fit = model.fit(disp=0)

  21. yhat = model_fit.forecast()[0]

  22. predictions.append(yhat)

  23. # observation

  24. obs = test[i]

  25. history.append(obs)

  26. # errors

  27. residuals = [test[i]-predictions[i] for i in range(len(test))]

  28. residuals = DataFrame(residuals)

  29. pyplot.figure()

  30. pyplot.subplot(211)

  31. residuals.hist(ax=pyplot.gca())

  32. pyplot.subplot(212)

  33. residuals.plot(kind='kde', ax=pyplot.gca())

  34. pyplot.show()

運(yùn)行該示例會(huì)創(chuàng)建兩個(gè)圖表。

這些圖表征了一個(gè)有長右尾的高斯樣分布。

這可能表明該預(yù)測是有偏差的,并且在這種情況下,在建模之前對原始數(shù)據(jù)進(jìn)行基于能量的變換可能是有用的。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

殘差密度圖

通過檢查所有時(shí)間序列的殘差中是否有某種類型的自相關(guān)性也是一個(gè)好辦法。 如果存在,它將表明模型有更多的機(jī)會(huì)來建模數(shù)據(jù)中的時(shí)間結(jié)構(gòu)。

下面的示例是重新計(jì)算殘差,并創(chuàng)建ACF和PACF圖以檢查出比較明顯的的自相關(guān)性。

  1. from pandas import   Series

  2. from pandas import   DataFrame

  3. from sklearn.metrics import mean_squared_error

  4. from statsmodels.tsa.arima_model   import ARIMA

  5. from statsmodels.graphics.tsaplots   import plot_acf

  6. from statsmodels.graphics.tsaplots   import plot_pacf

  7. from math import sqrt

  8. from matplotlib   import pyplot

  9. # load data

  10. series = Series.from_csv('dataset.csv')

  11. # prepare data

  12. X = series.values

  13. X = X.astype('float32')

  14. train_size = int(len(X) * 0.50)

  15. train, test = X[0:train_size], X[train_size:]

  16. # walk-foward   validation

  17. history = [x for x in train]

  18. predictions = list()

  19. for i in range(len(test)):

  20. # predict

  21. model = ARIMA(history, order=(0,1,2))

  22. model_fit = model.fit(disp=0)

  23. yhat = model_fit.forecast()[0]

  24. predictions.append(yhat)

  25. # observation

  26. obs = test[i]

  27. history.append(obs)

  28. # errors

  29. residuals = [test[i]-predictions[i] for i in range(len(test))]

  30. residuals = DataFrame(residuals)

  31. pyplot.figure()

  32. pyplot.subplot(211)

  33. plot_acf(residuals, ax=pyplot.gca())

  34. pyplot.subplot(212)

  35. plot_pacf(residuals, ax=pyplot.gca())

  36. pyplot.show()

結(jié)果表明,該時(shí)間序列中存在的少量的自相關(guān)性已被模型捕獲。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

殘差A(yù)CF和PACF圖

6.4 Box-Cox 變換數(shù)據(jù)集

Box-Cox變換是可以對一組能量變換進(jìn)行評估的方法,包括但不限于數(shù)據(jù)的對數(shù),平方根和互逆變換。

下面的示例對數(shù)據(jù)的執(zhí)行一個(gè)對數(shù)變換,并生成一些曲線以查看對時(shí)間序列的影響。

  1. from pandas import   Series

  2. from pandas import   DataFrame

  3. from scipy.stats import boxcox

  4. from matplotlib   import pyplot

  5. from statsmodels.graphics.gofplots   import qqplot

  6. series = Series.from_csv('dataset.csv')

  7. X = series.values

  8. transformed, lam = boxcox(X)

  9. print('Lambda:   %f' % lam)

  10. pyplot.figure(1)

  11. # line plot

  12. pyplot.subplot(311)

  13. pyplot.plot(transformed)

  14. # histogram

  15. pyplot.subplot(312)

  16. pyplot.hist(transformed)

  17. # q-q plot

  18. pyplot.subplot(313)

  19. qqplot(transformed, line='r', ax=pyplot.gca())

  20. pyplot.show()

運(yùn)行示例創(chuàng)建三個(gè)圖:經(jīng)變換的時(shí)間序列的線圖,展示變換后值的分布的直方圖,以及展示變換后的值得分布與理想化高斯分布相比的Q-Q圖。

這些圖中的一些觀察結(jié)果如下:

  • 大的波動(dòng)已在時(shí)間序列的線圖中被移除。

  • 直方圖顯示出了數(shù)值更平坦更均勻(表現(xiàn)良好)的分布。

  • Q-Q圖是合理的,但仍然不適合高斯分布。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

每月波士頓搶劫案數(shù)據(jù)的BoxCox變換圖

毫無疑問,Box-Cox變換對時(shí)間序列做了一些事情,而且是有效的。

在使用轉(zhuǎn)換數(shù)據(jù)測試ARIMA模型之前,我們必須有一種方法來進(jìn)行逆轉(zhuǎn)轉(zhuǎn)換,以便可以將對在轉(zhuǎn)換后的尺度上進(jìn)行訓(xùn)練的模型所做的預(yù)測轉(zhuǎn)換回原始尺度。

示例中使用的boxcox()函數(shù)通過優(yōu)化損失函數(shù)找到理想的lambda值。

lambda在以下函數(shù)中用于數(shù)據(jù)轉(zhuǎn)換:

  1. transform = log(x), if lambda == 0

  2. transform = (x^lambda - 1) / lambda, if lambda != 0

這個(gè)變換函數(shù)可以直接逆過來,如下:

  1. x = exp(transform) if lambda == 0

  2. x = exp(log(lambda * transform + 1) / lambda)

這個(gè)逆Box-Cox變換函數(shù)可以在Python中如下實(shí)現(xiàn):

  1. # invert box-cox   transform

  2. from math import log

  3. from math import exp

  4. def boxcox_inverse(value, lam):

  5. if lam == 0:

  6. return exp(value)

  7. return exp(log(lam   * value + 1) / lam)

我們可以用Box-Cox變換重新評估ARIMA(0,1,2)模型。

這包括在擬合ARIMA模型之前的初次變換,然后在存儲之前對預(yù)測進(jìn)行反變換,以便稍后與期望值進(jìn)行比較。

boxcox()函數(shù)可能失敗。 在實(shí)踐中,我已經(jīng)認(rèn)識到這一點(diǎn),它似乎是返回了一個(gè)小于-5的lambda值。 按照慣例,lambda值在-5和5之間計(jì)算。

對于小于-5的lambda值添加檢查,如果是這種情況,則假定lambda值為1,并且使用原始數(shù)據(jù)來擬合模型。 lambda值為1與未轉(zhuǎn)換相同,因此逆變換沒有效果。

下面列出了完整的示例。

  1. from pandas import   Series

  2. from sklearn.metrics import mean_squared_error

  3. from statsmodels.tsa.arima_model   import ARIMA

  4. from math import sqrt

  5. from math import log

  6. from math import exp

  7. from scipy.stats import boxcox

  8.  

  9. # invert box-cox   transform

  10. def boxcox_inverse(value, lam):

  11. if lam == 0:

  12. return exp(value)

  13. return exp(log(lam   * value + 1) / lam)

  14.  

  15. # load data

  16. series = Series.from_csv('dataset.csv')

  17. # prepare data

  18. X = series.values

  19. X = X.astype('float32')

  20. train_size = int(len(X) * 0.50)

  21. train, test = X[0:train_size], X[train_size:]

  22. # walk-foward   validation

  23. history = [x for x in train]

  24. predictions = list()

  25. for i in range(len(test)):

  26. # transform

  27. transformed, lam = boxcox(history)

  28. if lam < -5:

  29. transformed, lam = history, 1

  30. # predict

  31. model = ARIMA(transformed, order=(0,1,2))

  32. model_fit = model.fit(disp=0)

  33. yhat = model_fit.forecast()[0]

  34. # invert transformed   prediction

  35. yhat = boxcox_inverse(yhat, lam)

  36. predictions.append(yhat)

  37. # observation

  38. obs = test[i]

  39. history.append(obs)

  40. print('>Predicted=%.3f,   Expected=%3.f' % (yhat, obs))

  41. # report performance

  42. mse = mean_squared_error(test, predictions)

  43. rmse = sqrt(mse)

  44. print('RMSE:   %.3f' % rmse)

運(yùn)行此示例將打印每次迭代的預(yù)測值和預(yù)期值

注意,當(dāng)使用boxcox()轉(zhuǎn)換函數(shù)時(shí),可能會(huì)看到一些警告; 例如:

  1. RuntimeWarning: overflow encountered in square

  2. llf -= N / 2.0 * np.log(np.sum((y - y_mean)**2. / N, axis=0))

不過現(xiàn)在可以忽略這些。

在轉(zhuǎn)換數(shù)據(jù)上生成的模型最終的RMSE為49.443。 對于未轉(zhuǎn)換的數(shù)據(jù),這是一個(gè)比ARIMA模型更小的誤差,但只是很細(xì)微的,它可能是,也可能不是統(tǒng)計(jì)意義上的不同。

  1. ...

  2. >Predicted=276.253, Expected=287

  3. >Predicted=299.811, Expected=355

  4. >Predicted=338.997, Expected=460

  5. >Predicted=404.509, Expected=364

  6. >Predicted=349.336, Expected=487

  7. RMSE: 49.443

我們將使用該Box-Cox變換的模型作為最終模型。

7. 模型驗(yàn)證

在開發(fā)完模型并選擇最終模型后,必須對其進(jìn)行驗(yàn)證和確定。

驗(yàn)證是一個(gè)可選的過程,為我們提供了“最后的檢查手段”,以確保我們沒有被自己欺騙。

此部分包括以下步驟:

1.    確定模型:訓(xùn)練并保存最終模型。

2.    進(jìn)行預(yù)測: 加載最終模型并進(jìn)行預(yù)測。

3.    驗(yàn)證模型: 加載和驗(yàn)證最終模型。

7.1 確定模型

模型的確定涉及在整個(gè)數(shù)據(jù)集上擬合ARIMA模型,值得注意的一點(diǎn)是,該步驟中的數(shù)據(jù)集已經(jīng)經(jīng)過了變換。

一旦擬合好之后,模型可以保存到文件以供后續(xù)使用。這里由于我們對數(shù)據(jù)執(zhí)行了Box-Cox變換,因此我們需要明確所選擇的lamda值,以便使得來自模型的任何預(yù)測都可以被轉(zhuǎn)換回原始的未轉(zhuǎn)換的尺度。

下面的示例展示了在Box-Cox變換數(shù)據(jù)集上使用ARIMA(0,1,2)模型,并將整個(gè)擬合對象和lambda值保存到文件中的過程。

  1. from pandas import   Series

  2. from statsmodels.tsa.arima_model   import ARIMA

  3. from scipy.stats import boxcox

  4. import numpy

  5. # load data

  6. series = Series.from_csv('dataset.csv')

  7. # prepare data

  8. X = series.values

  9. X = X.astype('float32')

  10. # transform data

  11. transformed, lam = boxcox(X)

  12. # fit model

  13. model = ARIMA(transformed, order=(0,1,2))

  14. model_fit = model.fit(disp=0)

  15. # save model

  16. model_fit.save('model.pkl')

  17. numpy.save('model_lambda.npy', [lam])

運(yùn)行該示例會(huì)創(chuàng)建兩個(gè)本地文件:

  • model.pkl這是通過ARIMA.fit()      調(diào)用生成的ARIMAResult對象。 包括了各種系數(shù)和在擬合模型時(shí)返回的所有其他內(nèi)部數(shù)據(jù)。

  • model_lambda.npy這是作為一行一列NumPy數(shù)組對象存儲的lambda值。

這些文件或許會(huì)保存的過于詳細(xì)。其實(shí)在操作中真正需要的是:來自模型的AR和MA系數(shù)、用于差異數(shù)量的d參數(shù)、以及滯后的觀察值、模型殘差和用于變換的lamda值。

7.2 進(jìn)行預(yù)測

這里,最直接的方法是加載模型并進(jìn)行單一預(yù)測。

這是相對直接的,涉及恢復(fù)保存的模型、lambda值和調(diào)用forecast() 方法。

然而,在當(dāng)前穩(wěn)定版本的statsmodels庫(v0.6.1)中存在一個(gè)Bug,它的錯(cuò)誤提示如下:

  1. TypeError: __new__() takes at least 3 arguments (1 given)

據(jù)我測試發(fā)現(xiàn),這個(gè)bug也似乎存在于statsmodels的0.8版本候選1版本中。

更多詳細(xì)信息,請參閱Zae Myung Kim的討論和在GitHub上的解決辦法。

鏈接:https://github.com/statsmodels/statsmodels/pull/3217

我們可以使用一個(gè)猴子補(bǔ)?。╩onkey patch)來解決這個(gè)問題,在保存之前將一個(gè) __getnewargs __() 實(shí)例函數(shù)添加到ARIMA類中。

下面的示例與上一小節(jié)的變化相同。

  1. from pandas import   Series

  2. from statsmodels.tsa.arima_model   import ARIMA

  3. from scipy.stats import boxcox

  4. import numpy

  5.  

  6. # monkey patch around   bug in ARIMA class

  7. def __getnewargs__(self):

  8. return ((self.endog),(self.k_lags, self.k_diff, self.k_ma))

  9.  

  10. ARIMA.__getnewargs__ = __getnewargs__

  11.  

  12. # load data

  13. series = Series.from_csv('dataset.csv')

  14. # prepare data

  15. X = series.values

  16. X = X.astype('float32')

  17. # transform data

  18. transformed, lam = boxcox(X)

  19. # fit model

  20. model = ARIMA(transformed, order=(0,1,2))

  21. model_fit = model.fit(disp=0)

  22. # save model

  23. model_fit.save('model.pkl')

  24. numpy.save('model_lambda.npy', [lam])

我們現(xiàn)在可以加載模型并進(jìn)行單一預(yù)測。

下面這個(gè)示例展示了加載模型,對下一時(shí)間步進(jìn)進(jìn)行了預(yù)測,反轉(zhuǎn)Box-Cox變換,并打印預(yù)測結(jié)果的過程。

  1. from pandas import   Series

  2. from statsmodels.tsa.arima_model   import ARIMAResults

  3. from math import exp

  4. from math import log

  5. import numpy

  6.  

  7. # invert box-cox   transform

  8. def boxcox_inverse(value, lam):

  9. if lam == 0:

  10. return exp(value)

  11. return exp(log(lam   * value + 1) / lam)

  12.  

  13. model_fit = ARIMAResults.load('model.pkl')

  14. lam = numpy.load('model_lambda.npy')

  15. yhat = model_fit.forecast()[0]

  16. yhat = boxcox_inverse(yhat, lam)

  17. print('Predicted:   %.3f' % yhat)

最后得到的預(yù)測值為452。

如果我們在validation.csv中查看的話,我們可以看到下一個(gè)時(shí)間段的第一行的數(shù)值是452。模型達(dá)到了100% 的正確率,這是非常驚人的(也是幸運(yùn)的)。

  1. Predicted: 452.043

7.3 驗(yàn)證模型

在這一步驟中,我們可以加載模型并以模擬操作的方式使用它。

在測試工具部分中,我們將原始數(shù)據(jù)集的最后12個(gè)月保存在單獨(dú)的文件中,以驗(yàn)證最終模型。

我們現(xiàn)在可以加載此validation.csv文件,并用它來檢驗(yàn)我們的模型對真正“未知”的數(shù)據(jù)究竟表現(xiàn)如何。

這里可以采用兩種方式:

  • 加載模型并使用它預(yù)測未來的12個(gè)月。 超過前一兩個(gè)月的預(yù)測將很快開始降低技能(start to degrade in skill)。

  • 加載模型并以步進(jìn)預(yù)測的方式使用該模型,更新每個(gè)時(shí)間步長上的變換和模型。      這是首選的方法,在實(shí)踐中使用這個(gè)模型,它將表現(xiàn)出最佳的性能。

與前面章節(jié)中的模型評估一樣,我們將以步進(jìn)預(yù)測的方式進(jìn)行預(yù)測。 這意味著我們將在驗(yàn)證數(shù)據(jù)集中逐步引導(dǎo)時(shí)間點(diǎn),并將觀察結(jié)果作為歷史記錄的更新。

  1. from pandas import   Series

  2. from matplotlib   import pyplot

  3. from statsmodels.tsa.arima_model   import ARIMA

  4. from statsmodels.tsa.arima_model   import ARIMAResults

  5. from scipy.stats import boxcox

  6. from sklearn.metrics import mean_squared_error

  7. from math import sqrt

  8. from math import exp

  9. from math import log

  10. import numpy

  11.  

  12. # invert box-cox   transform

  13. def boxcox_inverse(value, lam):

  14. if lam == 0:

  15. return exp(value)

  16. return exp(log(lam   * value + 1) / lam)

  17.  

  18. # load and prepare   datasets

  19. dataset = Series.from_csv('dataset.csv')

  20. X = dataset.values.astype('float32')

  21. history = [x for x in X]

  22. validation = Series.from_csv('validation.csv')

  23. y = validation.values.astype('float32')

  24. # load model

  25. model_fit = ARIMAResults.load('model.pkl')

  26. lam = numpy.load('model_lambda.npy')

  27. # make first   prediction

  28. predictions = list()

  29. yhat = model_fit.forecast()[0]

  30. yhat = boxcox_inverse(yhat, lam)

  31. predictions.append(yhat)

  32. history.append(y[0])

  33. print('>Predicted=%.3f,   Expected=%3.f' % (yhat, y[0]))

  34. # rolling forecasts

  35. for i in range(1, len(y)):

  36. # transform

  37. transformed, lam = boxcox(history)

  38. if lam < -5:

  39. transformed, lam = history, 1

  40. # predict

  41. model = ARIMA(transformed, order=(0,1,2))

  42. model_fit = model.fit(disp=0)

  43. yhat = model_fit.forecast()[0]

  44. # invert transformed   prediction

  45. yhat = boxcox_inverse(yhat, lam)

  46. predictions.append(yhat)

  47. # observation

  48. obs = y[i]

  49. history.append(obs)

  50. print('>Predicted=%.3f,   Expected=%3.f' % (yhat, obs))

  51. # report performance

  52. mse = mean_squared_error(y, predictions)

  53. rmse = sqrt(mse)

  54. print('RMSE:   %.3f' % rmse)

  55. pyplot.plot(y)

  56. pyplot.plot(predictions, color='red')

  57. pyplot.show()

運(yùn)行以上示例將打印出在驗(yàn)證數(shù)據(jù)集中所有時(shí)間步長上的每個(gè)預(yù)測值和預(yù)期值。

修正階段最終的RMSE預(yù)測結(jié)果為53次搶劫。 這與預(yù)期的49次并沒有太大的出入,我希望它在簡單的持久性模型上也能有類似的表現(xiàn)。

  1. >Predicted=452.043, Expected=452

  2. >Predicted=423.088, Expected=391

  3. >Predicted=408.378, Expected=500

  4. >Predicted=482.454, Expected=451

  5. >Predicted=445.944, Expected=375

  6. >Predicted=413.881, Expected=372

  7. >Predicted=413.209, Expected=302

  8. >Predicted=355.159, Expected=316

  9. >Predicted=363.515, Expected=398

  10. >Predicted=406.365, Expected=394

  11. >Predicted=394.186, Expected=431

  12. >Predicted=428.174, Expected=431

  13. RMSE: 53.078

我們在這里同時(shí)提供了預(yù)測結(jié)果與驗(yàn)證數(shù)據(jù)集之間相互比較的圖表。

該預(yù)測具有持續(xù)性預(yù)測的特性。這表明雖然這個(gè)時(shí)間序列有明顯的趨勢,但它仍然是一個(gè)相當(dāng)困難的問題。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

驗(yàn)證時(shí)間步驟的預(yù)測

教程擴(kuò)展

需要說明的是,本教程并不完美,你可以有很多改善結(jié)果的方法。

本節(jié)列出了一些或許可行的改進(jìn)措施。

  • 統(tǒng)計(jì)顯著性檢驗(yàn)。使用統(tǒng)計(jì)學(xué)測試來檢查不同模型之間的結(jié)果差異是否具有統(tǒng)計(jì)學(xué)的意義。T檢驗(yàn)將是一個(gè)很好的入手點(diǎn)。

  • 使用數(shù)據(jù)變換的網(wǎng)格進(jìn)行搜索。通過Box-Cox變換在ARIMA超參數(shù)中重復(fù)網(wǎng)格搜索過程,并查看是否可以實(shí)現(xiàn)一個(gè)與此前不同的,并且更好的參數(shù)集。

  • 檢查殘差。通過Box-Cox變換檢測最終模型的預(yù)測誤差的殘差,以查看是否存在可以進(jìn)一步優(yōu)化的偏差或自相關(guān)。

  • 精簡模型存儲。嘗試簡化模型保存,僅僅存儲那些必要的系數(shù),而不是整個(gè)ARIMAResults對象。

  • 手動(dòng)處理趨勢。使用線性或非線性模型直接對趨勢進(jìn)行建模,并明確地從序列中刪除它。如果該趨勢是非線性的,并且更適合非線性建模,那這種方式可能會(huì)帶來更好的性能表現(xiàn)。

  • 置信區(qū)間。顯示驗(yàn)證數(shù)據(jù)集中預(yù)測的置信區(qū)間。

  • 數(shù)據(jù)選擇??紤]在沒有前兩年數(shù)據(jù)的情況下對問題進(jìn)行建模,并查看這是否對預(yù)測技能(forecast skill)有影響。

總結(jié)

通過本教程的學(xué)習(xí),你可以初步了解到基于Python的時(shí)間序列預(yù)測項(xiàng)目的具體實(shí)現(xiàn)步驟和工具。

我們在本教程中討論了很多內(nèi)容,具體來說包括以下三個(gè)方面:

  • 如何通過性能指標(biāo)和評估方法開發(fā)測試工具,以及如何快速開發(fā)基準(zhǔn)預(yù)測原型和方法。

  • 如何通過時(shí)間序列分析來提出最好的模擬預(yù)測問題的方法。

  • 如何開發(fā)ARIMA模型,并保存它,然后加載它用來對新數(shù)據(jù)進(jìn)行預(yù)測。

歡迎加入雷鋒網(wǎng) ML 開發(fā)者讀者群,添加“ycopen3”微信號,回復(fù)關(guān)鍵詞“開發(fā)者”,群助拉您進(jìn)群交流!

via machine learning mastery

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。

時(shí)間序列預(yù)測教程:如何利用 Python 預(yù)測波士頓每月持械搶劫案數(shù)量?

分享:
相關(guān)文章

編輯

聚焦數(shù)據(jù)科學(xué),連接 AI 開發(fā)者。更多精彩內(nèi)容,請?jiān)L問:yanxishe.com
當(dāng)月熱門文章
最新文章
請?zhí)顚懮暾埲速Y料
姓名
電話
郵箱
微信號
作品鏈接
個(gè)人簡介
為了您的賬戶安全,請驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號信息
您的賬號已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說