1. 程式人生 > >長短期記憶(LSTM)系列_LSTM的資料準備(3)——如何使用差分法消除資料的趨勢和季節性

長短期記憶(LSTM)系列_LSTM的資料準備(3)——如何使用差分法消除資料的趨勢和季節性

導讀:

我們的很多資料是具有季節性或者趨勢性的,就是隨著時間越來越久,資料隨著一個趨勢來變化,這種內在的趨勢對資料的預測有一定的影響。那麼怎麼來消除這個影響呢?

我們可以使用差分法,差分法簡單說就是在一系列資料中,相鄰兩個相減得到相鄰兩個值的變化量,我們在進行資料分析的過程中,只對差分之後的結果進行分析,也就是說我們只分析連續資料間的變化情況,而忽略了資料本身的累加形成的趨勢性或者季節性。最後我們對資料進行逆轉換即可。

正文如下:

差分變換

差分是一種轉換時間序列資料集的方法。

它可用於消除序列對時間的依賴性,即所謂的時間依賴性。這包括趨勢和季節性等結構。

 

通過從當前觀察中減去先前的觀察來執行差分。

difference(t) = observation(t) - observation(t-1)


當必須將預測轉換回原始比例時,需要反轉該過程。

通過將先前時間步驟的觀察值新增到差值,可以反轉該過程。

inverted(t) = differenced(t) + observation(t-1)

以這種方式,可以計算一系列差異和反轉差異。

滯後差異

將連續觀察之間的差異稱為滯後-1差異。

可以調整滯後差異以適應特定的時間結構。

對於具有季節性成分的時間序列,滯後可以預期為季節性的週期(寬度)。

差異訂單

在執行差分運算之後,一些時間結構可能仍然存在,例如在非線性趨勢的情況下。

因此,差分過程可以重複多次,直到所有時間依賴性都被消除。

執行差分的次數稱為差分順序。

計算差分

我們可以手動區分資料集。

這涉及開發一個建立差異資料集的新功能。該函式將遍歷提供的序列並以指定的間隔或滯後計算差異值。

下面名為difference()的函式實現了此過程。

#建立一個差分序列

def difference(dataset, interval=1):

diff = list()

for i in range(interval, len(dataset)):

value

= dataset[i] - dataset[i - interval]

diff.append(value)

return Series(diff)

我們可以看到該函式在指定的時間間隔後小心地開始差異資料集,以確保實際上可以計算差值。定義預設間隔或滯後值1。這是一個合理的預設值。

進一步的改進是還能夠指定執行差分操作的次序或次數。

下面名為inverse_difference()的函式會反轉單個預測的差異運算。它還要求提供前一時間步的實際觀測值。

# 差分的逆轉換

def inverse_difference(last_ob, value):

return value + last_ob

 

區別於消除趨勢

在本節中,我們將介紹使用差異變換來移除趨勢。

趨勢通過提高水平使時間序列非靜止。這具有隨時間改變平均時間序列值的效果。

下面的示例將difference()函式應用於具有線性增加趨勢的人為資料集。

# 建立一個差分序列
def difference(dataset, interval=1):
	diff = list()
	for i in range(interval, len(dataset)):
		value = dataset[i] - dataset[i - interval]
		diff.append(value)
	return diff

# 差分的逆轉換
def inverse_difference(last_ob, value):
	return value + last_ob

# 定義一個有線性趨勢的資料集
data = [i+1 for i in range(20)]
print(data)
# 對資料做差分
diff = difference(data)
print(diff)
# 差分的逆轉換
inverted = [inverse_difference(data[i], diff[i]) for i in range(len(diff))]
print(inverted)

最後,使用來自原始序列的先前值作為每個變換的引物來反轉差異序列。執行該示例首先使用線性趨勢列印設計序列。接下來,列印差異資料集,顯示每個時間步長增加一個單位。該序列的長度為19而不是20,因為序列中第一個值的差異無法計算,因為沒有先前值。

 

1

2

3

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

 

區別於刪除季節性

 

在本節中,我們將介紹使用差異變換來消除季節性。

季節性變化或季節性是隨著時間的推移而定期重複的迴圈。

 

季節性有很多種類。一些明顯的例子包括:時間,每日,每週,每月,每年等。因此,確定時間序列問題中是否存在季節性因素是主觀的。

確定是否存在季節性方面的最簡單方法是繪製和審查您的資料,可能是在不同的尺度和新增趨勢線。

下面的示例將difference()函式應用於人為的季節性資料集。資料集包括兩個迴圈,每個迴圈360個單元。

from math import sin
from math import radians
from matplotlib import pyplot

# 建立一個差分序列
def difference(dataset, interval=1):
	diff = list()
	for i in range(interval, len(dataset)):
		value = dataset[i] - dataset[i - interval]
		diff.append(value)
	return diff

# 差分的逆轉換
def inverse_difference(last_ob, value):
	return value + last_ob

# 定義一個有線性趨勢的資料集
data = [sin(radians(i)) for i in range(360)] + [sin(radians(i)) for i in range(360)]
pyplot.plot(data)
pyplot.show()
# 對資料做差分
diff = difference(data, 360)
pyplot.plot(diff)
pyplot.show()
# 差分的逆轉換
inverted = [inverse_difference(data[i], diff[i]) for i in range(len(diff))]
pyplot.plot(inverted)
pyplot.show()

首先執行示例建立並繪製360時間步長序列的兩個週期的資料集。

人工資料集的線圖

                                                             人工資料集的線圖

接下來,應用差異變換並繪製結果。該圖顯示了360個零值,並刪除了所有季節性訊號。

在上面的去趨勢示例中,差值應用滯後為1,這意味著犧牲了第一個值。這裡整個週期用於差分,即360個時間步長。結果是犧牲整個第一迴圈以區分第二迴圈。

差異季節性資料集的線圖

                                                        差異季節性資料集的線圖

最後,轉換反轉顯示第二個週期恢復了季節性。

差分資料集的線圖與反向差分變換

                                                 差分資料集的線圖與反向差分變換