Python代碼詳解:入門時間序列分類

我們接觸的大多數(shù)時間序列數(shù)據(jù)主要涉及產(chǎn)生預(yù)測的交易。無論是預(yù)測產(chǎn)品的需求還是銷售額,航空公司的乘客數(shù)量或特定股票的收盤價,我們都習(xí)慣于利用久經(jīng)考驗的時間序列技術(shù)來預(yù)測需求。

但隨著生成的數(shù)據(jù)量呈指數(shù)增長,嘗試新想法和算法的機會也隨之增加。使用復(fù)雜的時間序列數(shù)據(jù)集仍然是一個利基領(lǐng)域,擴展你的保留曲目以包含新想法總是有幫助的。

這就是本文的目的,向你介紹時間序列分類的新概念。我們將首先了解這個主題的含義以及它在行業(yè)中的應(yīng)用。但是不會只停留在理論部分——我們將通過處理時間序列數(shù)據(jù)集并執(zhí)行二進制時間序列分類來解決問題。邊學(xué)邊應(yīng)用——這將有助于你以實際的方式理解這個概念。

時間序列分類介紹

時間序列分類實際上已經(jīng)存在了一段時間。但到目前為止,它主要限于研究實驗室,而沒有進行行業(yè)應(yīng)用。但是有很多研究正在進行,正在創(chuàng)建新的數(shù)據(jù)集并提出了許多新的算法。

可以想象,時間序列分類數(shù)據(jù)與常規(guī)分類問題不同,因為屬性具有有序序列。 讓我們來看看一些時間序列分類用例,以了解這種差異。

1.對心電圖(ECG/EEG)信號進行分類

心電圖或心電圖記錄心臟的電活動,廣泛用于診斷各種心臟問題。使用外部電極捕獲這些心電圖信號。

例如,考慮以下信號樣本,它代表一個心跳的電活動。左側(cè)的圖像表示正常心跳,而與其相鄰的圖像表示心肌梗塞。

[圖片上傳失敗...(image-f419ea-1550147176398)]

從電極捕獲的數(shù)據(jù)將是時間序列形式,并且信號可以分類為不同的類別。我們還可以對記錄大腦電活動的腦電信號進行分類。

在學(xué)習(xí)的道路上肯定會遇到困難,沒有好的學(xué)習(xí)資料怎么去學(xué)習(xí)呢?
如果你感覺學(xué)不會?莫慌,推薦你加群
前面923中間414后面804 ,群里有志同道合的小伙伴
互幫互助,還可以拿到許多視頻教程!

2.圖像分類

圖像也可以是順序的時間相關(guān)格式。請考慮以下情形:

根據(jù)天氣條件、土壤肥力、水的可用性和其他外部因素,農(nóng)作物在特定的田地中生長。這塊田地被監(jiān)測拍攝了5年,并標(biāo)記在該字段上種植的作物的名稱。 你知道為什么要這么做嗎?數(shù)據(jù)集中的圖像是在固定的時間間隔之后拍攝的,并且具有定義的序列,這可能是對圖像進行分類的重要因素。

3.對運動傳感器數(shù)據(jù)進行分類

傳感器生成高頻數(shù)據(jù),可以識別其范圍內(nèi)物體的移動。通過設(shè)置多個無線傳感器并觀察傳感器中信號強度的變化,可以識別物體的運動方向。

設(shè)置問題陳述

我們將致力于“室內(nèi)用戶運動預(yù)測”問題。在該挑戰(zhàn)中,多個運動傳感器被放置在不同的房間中,并且目標(biāo)是基于從這些運動傳感器捕獲的頻率數(shù)據(jù)來識別個體是否已經(jīng)移動穿過房間。

兩個房間有四個運動傳感器(A1,A2,A3,A4)。請看下面的圖像,其中說明了傳感器在每個房間中的位置。這兩個房間的設(shè)置是在3對不同的房間(group1,group2,group3)中創(chuàng)建的。

[圖片上傳失敗...(image-a9d588-1550147176398)]

一個人可以沿著上圖中所示的六個預(yù)定義路徑進行任何移動。如果一個人走在路徑2,3,4或6上,他會在單個房間內(nèi)移動。另一方面,如果一個人沿著路徑1或路徑5行進,我們可以說該人在兩個房間之間移動。

傳感器讀數(shù)可用于識別人在給定時間點的位置。當(dāng)人在房間或房間內(nèi)移動時,傳感器中的讀數(shù)會發(fā)生變化。此更改可用于標(biāo)識人員的路徑。

既然這個問題陳述已經(jīng)清楚了,現(xiàn)在是時候開始編碼了!

讀取和理解數(shù)據(jù)

我們的數(shù)據(jù)集有316個文件

· 314個MovementAAL csv文件,包含放置在環(huán)境中的運動傳感器的讀數(shù)

· Target csv文件,其中包含每個MovementAAL文件的目標(biāo)變量

· 一個組數(shù)據(jù)csv文件,用于標(biāo)識哪個MovementAAL文件屬于哪個安裝組

· Path csv文件,包含對象所采用的路徑

我們來看看數(shù)據(jù)集。我們將從導(dǎo)入必要的數(shù)據(jù)庫庫開始。

import pandas as pd

import numpy as np

%matplotlib inline

import matplotlib.pyplot as plt

from os import listdir

from keras.preprocessing import sequence

import tensorflow as tf

from keras.models import Sequential

from keras.layers import Dense

from keras.layers import LSTM

from keras.optimizers import Adam

from keras.models import load_model

from keras.callbacks import ModelCheckpoint

在加載所有文件之前,讓我們快速了解一下要處理的數(shù)據(jù)。從移動數(shù)據(jù)中讀取前兩個文件:

df1 = pd.read_csv(‘/MovementAAL/dataset/MovementAAL_RSS_1.csv')

df2 = pd.read_csv('/MovementAAL/dataset/MovementAAL_RSS_2.csv')

df1.head

[圖片上傳失敗...(image-8afde3-1550147176398)]

df2.head

[圖片上傳失敗...(image-fc46f5-1550147176398)]

df1.shape, df2.shape

((27, 4), (26, 4))

這些文件包含來自四個傳感器的標(biāo)準(zhǔn)化數(shù)據(jù)——A1,A2,A3,A4。csv文件的長度(行數(shù))不同,因為對應(yīng)于每個csv的數(shù)據(jù)的持續(xù)時間不同。為簡化起見,我們假設(shè)每秒都會收集傳感器數(shù)據(jù)。第一次讀數(shù)持續(xù)27秒(所以是27行),而另一次讀數(shù)持續(xù)26秒(所以是26行)。

在構(gòu)建模型之前,我們必須處理這些不同的長度?,F(xiàn)在,我們將使用以下代碼塊讀取傳感器中的值并將其存儲在列表中:

path = 'MovementAAL/dataset/MovementAAL_RSS_'

sequences = list

for i in range(1,315):

file_path = path + str(i) + '.csv'

print(file_path)

df = pd.read_csv(file_path, header=0)

values = df.values

sequences.append(values)



targets = pd.read_csv('MovementAAL/dataset/MovementAAL_target.csv')

targets = targets.values[:,1]

我們現(xiàn)在有一個列表“序列”,其中包含來自運動傳感器的數(shù)據(jù)和“目標(biāo)”,其中包含csv文件的標(biāo)簽。當(dāng)我們打印序列[0]時,從第一個csv文件中獲取傳感器的值:

sequences[0]

[圖片上傳失敗...(image-f21f4f-1550147176398)]

如前所述,數(shù)據(jù)集是在三對不同的房間中收集的——因此有三組。此信息可用于將數(shù)據(jù)集劃分為訓(xùn)練集、測試集和驗證集。我們現(xiàn)在將加載DatasetGroup csv文件:

groups= pd.read_csv('MovementAAL/groups/MovementAAL_DatasetGroup.csv', header=0)

groups = groups.values[:,1]

我們將前兩組的數(shù)據(jù)用于培訓(xùn)目的,第三組用于測試。

預(yù)處理步驟

由于時間序列數(shù)據(jù)的長度不同,我們無法直接在此數(shù)據(jù)集上構(gòu)建模型。那么怎樣才能決定一個系列的理想長度呢?我們可以通過多種方式處理它,這里有一些想法:

· 用零填充較短的序列,使所有序列的長度相等。在這種情況下,我們將向模型提供不正確的數(shù)據(jù)。

· 查找序列的最大長度,并使用最后一行中的數(shù)據(jù)填充序列。

· 確定數(shù)據(jù)集中序列的最小長度,并將所有其他序列截斷為該長度。但是,這將導(dǎo)致數(shù)據(jù)的巨大損失。

· 取所有長度的平均值,截斷較長的系列,并填充比平均長度短的序列。

讓我們找出最小長度、最大長度和平均長度:

len_sequences =

for one_seq in sequences:

len_sequences.append(len(one_seq))

pd.Series(len_sequences).describe

count 314.000000

mean 42.028662

std 16.185303

min 19.000000

25% 26.000000

50% 41.000000

75% 56.000000

max 129.000000

dtype: float64

大多數(shù)文件的長度在40到60之間。只有3個文件的長度超過100。因此,采用最小或最大長度沒有多大意義。第90個四分位數(shù)為60,這被視為數(shù)據(jù)序列的長度。我們來編代碼:

#Padding the sequence with the values in last row to max length

to_pad = 129

new_seq =

for one_seq in sequences:

len_one_seq = len(one_seq)

last_val = one_seq[-1]

n = to_pad - len_one_seq

to_concat = np.repeat(one_seq[-1], n).reshape(4, n).transpose

new_one_seq = np.concatenate([one_seq, to_concat])

new_seq.append(new_one_seq)

final_seq = np.stack(new_seq)

#truncate the sequence to length 60

from keras.preprocessing import sequence

seq_len = 60

final_seq=sequence.pad_sequences(final_seq, maxlen=seq_len, padding='post', dtype='float', truncating='post')

既然數(shù)據(jù)集已準(zhǔn)備好,我們將根據(jù)組將其分開。準(zhǔn)備訓(xùn)練、驗證和測試集:

train = [final_seq[i] for i in range(len(groups)) if (groups[i]==2)]

validation = [final_seq[i] for i in range(len(groups)) if groups[i]==1]

test = [final_seq[i] for i in range(len(groups)) if groups[i]==3]

train_target = [targets[i] for i in range(len(groups)) if (groups[i]==2)]

validation_target = [targets[i] for i in range(len(groups)) if groups[i]==1]

test_target = [targets[i] for i in range(len(groups)) if groups[i]==3]

train = np.array(train)

validation = np.array(validation)

test = np.array(test)

train_target = np.array(train_target)

train_target = (train_target+1)/2

validation_target = np.array(validation_target)

validation_target = (validation_target+1)/2

test_target = np.array(test_target)

test_target = (test_target+1)/2

構(gòu)建時間序列分類模型

我們準(zhǔn)備了用于LSTM(長短期記憶)模型的數(shù)據(jù)。我們處理了可變長度序列并創(chuàng)建了訓(xùn)練、驗證和測試集。構(gòu)建一個單層LSTM網(wǎng)絡(luò)。

model = Sequential

model.add(LSTM(256, input_shape=(seq_len, 4)))

model.add(Dense(1, activation='sigmoid'))

model.summary

[圖片上傳失敗...(image-710f90-1550147176398)]

我們現(xiàn)在將訓(xùn)練模型并監(jiān)控驗證的準(zhǔn)確性:

adam = Adam(lr=0.001)

chk = ModelCheckpoint('best_model.pkl', monitor='val_acc', save_best_only=True, mode='max', verbose=1)

model.compile(loss='binary_crossentropy', optimizer=adam, metrics=['accuracy'])

model.fit(train, train_target, epochs=200, batch_size=128, callbacks=[chk], validation_data=(validation,validation_target))

#loading the model and checking accuracy on the test data

model = load_model('best_model.pkl')

from sklearn.metrics import accuracy_score

test_preds = model.predict_classes(test)

accuracy_score(test_target, test_preds)

這里的準(zhǔn)確度得分為0.78846153846153844。這是一個非常有前景的開始,但我們肯定可以通過使用超參數(shù),改變學(xué)習(xí)速度和/或時代數(shù)來改善LSTM模型的性能。

總結(jié)

預(yù)處理步驟是所有部分中最復(fù)雜的。然而,它也是最重要的一個(否則整個時間序列數(shù)據(jù)將會失敗)。在處理此類挑戰(zhàn)時,向模型提供正確的數(shù)據(jù)同樣重要。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容