時間序列分類實踐介紹(使用Python代碼)

https://www.analyticsvidhya.com/blog/2019/01/introduction-time-series-classification/

介紹

分類時間序列數據?這真的有可能嗎?可能有什麼用呢?這些只是您閱讀本文標題時必須具備的一些問題。這是公平的 - 當我第一次遇到這個概念時,我有完全相同的想法!

我們大多數人的時間序列數據主要涉及產生預測的交易。無論是預測產品的需求還是銷售額,航空公司的乘客數量或特定股票的收盤價,我們都習慣於利用久經考驗的時間序列技術來預測需求。

但隨着生成的數據量呈指數增長,嘗試新想法和算法的機會也隨之增加。使用複雜的時間序列數據集仍然是一個利基領域,擴展您的保留曲目以包含新想法總是有幫助的。

這就是我在文章中的目的,向您介紹時間序列分類的新概念。我們將首先了解這個主題的含義以及它在行業中的應用。但是我們不會停留在理論部分 - 我們將通過處理時間序列數據集並執行二進制時間序列分類來解決問題。邊做邊學 - 這將有助於您以實際的方式理解這個概念。

如果您之前沒有處理過時間序列問題,我強烈建議您先從一些基本預測開始。您可以通過以下文章瞭解初學者:

 

目錄

  1. 時間序列分類簡介
    1. 心電圖信號
    2. 圖像數據
    3. 傳感器
  2. 設置問題陳述
  3. 閱讀和理解數據
  4. 預處理
  5. 建立我們的時間序列分類模型

 

時間序列分類簡介

時間序列分類實際上已經存在了一段時間。但到目前爲止,它主要限於研究實驗室,而不是行業應用。但是有很多研究正在進行,正在創建新的數據集並提出了許多新的算法。當我第一次看到這個時間序列分類概念時,我最初的想法是 - 我們如何對時間序列進行分類以及時間序列分類數據是什麼樣的?我相信你一定想知道同樣的事情。

可以想象,時間序列分類數據與常規分類問題不同,因爲屬性具有有序序列。讓我們來看看一些時間序列分類用例,以瞭解這種差異。

 

1)對ECG / EEG信號進行分類

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

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

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

 

2)圖像分類

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

根據天氣條件,土壤肥力,水的可用性和其他外部因素,農作物在特定的田地中生長。該字段的圖片每天拍攝5年,並標記在該字段上種植的作物的名稱。你知道我要去哪兒嗎?數據集中的圖像是在固定的時間間隔之後拍攝的,並且具有定義的序列,這可能是對圖像進行分類的重要因素。

 

3)分類運動傳感器數據

傳感器生成高頻數據,可以識別其範圍內物體的移動。通過設置多個無線傳感器並觀察傳感器中信號強度的變化,我們可以識別物體的運動方向。

您還可以考慮哪些其他應用可以應用時間序列分類?請在文章下方的評論部分告訴我。

 

設置問題陳述

我們將致力於“ 室內用戶運動預測 ”問題。在該挑戰中,多個運動傳感器被放置在不同的房間中,並且目標是基於從這些運動傳感器捕獲的頻率數據來識別個體是否已經移動穿過房間。

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

一個人可以沿着上圖中所示的六個預定義路徑中的任何一個移動。如果一個人走在路徑2,3,4或6上,他會在房間內移動。另一方面,如果一個人沿着路徑1或路徑5行進,我們可以說該人已經在房間之間移動。

傳感器讀數可用於識別人在給定時間點的位置。當人在房間或房間內移動時,傳感器中的讀數會發生變化。此更改可用於標識人員的路徑。

現在問題陳述已經清楚了,現在是時候開始編碼了!在下一節中,我們將查看問題的數據集,這有助於消除您在此聲明中可能存在的任何遺留問題。您可以從以下鏈接下載數據集:室內用戶移動預測

 

閱讀和理解數據

我們的數據集包含316個文件:

  • 314 MovementAAL csv文件,包含放置在環境中的運動傳感器的讀數
  • 一個目標包含每個MovementAAL文件的目標變量csv文件
  • 一個Group Data csv文件,用於標識哪個MovementAAL文件屬於哪個安裝組
  • 路徑包含該對象所採取的方法csv文件

我們來看看數據集。我們將從導入必要的庫開始。

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

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

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

df2.head()

df1.shape,df2.shape
((27,4),(26,4))

這些文件包含來自四個傳感器的標準化數據 - A1,A2,A3,A4。csv文件的長度(行數)不同,因爲對應於每個csv的數據的持續時間不同。爲簡化起見,我們假設每秒都會收集傳感器數據。第一次讀數持續27秒(所以27行),而另一次讀數持續26秒(所以26行)。

在構建模型之前,我們必須處理這種不同的長度。現在,我們將使用以下代碼塊讀取傳感器中的值並將其存儲在列表中:

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]

我們現在有一個列表'序列 ',其中包含來自運動傳感器的數據和'目標',其中包含csv文件的標籤。當我們打印序列[0]時,我們從第一個csv文件中獲取傳感器的值:

sequences[0]

 

如前所述,數據集是在三對不同的房間中收集的 - 因此有三組。此信息可用於將數據集劃分爲訓練集,測試集和驗證集。我們現在將加載DatasetGroup csv文件:

groups = pd.read_csv('MovementAAL / groups / MovementAAL_DatasetGroup.csv',header = 0)
groups = groups.values [:,1]

我們將前兩組的數據用於培訓目的,第三組用於測試。

 

預處理步驟

由於時間序列數據的長度不同,我們無法直接在此數據集上構建模型。那麼我們怎樣才能決定一個系列的理想長度呢?我們可以通過多種方式處理它,這裏有一些想法(我很樂意在評論部分聽到您的建議):

  • 用零填充較短的序列以使所有序列的長度相等。在這種情況下,我們將向模型提供不正確的數據
  • 找到系列的最大長度,並使用最後一行中的數據填充序列
  • 確定數據集中序列的最小長度,並將所有其他序列截斷爲該長度。但是,這將導致數據的巨大損失
  • 取所有長度的平均值,截斷較長的系列,並填充比平均長度短的系列

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

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

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

#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')

現在已準備好數據集,我們將根據組將其分開。準備火車,驗證和測試集:

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

 

建立時間序列分類模型

我們準備了用於LSTM(長短期記憶)模型的數據。我們處理了可變長度序列並創建了訓練,驗證和測試集。讓我們構建一個單層LSTM網絡。

注意:您可以在這個精彩解釋的教程中熟悉LSTM 。我會建議你先完成它,因爲它可以幫助你理解下面代碼的工作原理。

model = Sequential()
model.add(LSTM(256, input_shape=(seq_len, 4)))
model.add(Dense(1, activation='sigmoid'))
model.summary()

我們現在將訓練模型並監控驗證的準確性:

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)

我的準確度得分爲0.78846153846153844。這是一個非常有希望的開始,但我們肯定可以通過使用超參數,改變學習速度和/或時代數來改善LSTM模型的性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章