時間序列資料分析101 - (13) 基於聚類的機器學習方法
大綱
1。概述
2。準備和處理時間序列資料
3。探索式分析(EDA)
4。基於統計學的時間序列分析方法
5。基於狀態空間模型的時間序列分析方法
6。特徵生成和特徵選擇
7.基於機器學習的時間序列分析方法
7.2 時間序列聚類問題
8。基於深度學習的時間序列分析方法
9。模型最佳化的考慮
所有原始碼和markdown在github同步更新
https://github。com/skywateryang
7。2 時間序列聚類問題
聚類問題(cluster)的核心是尋找相似的資料點構造有意義的組別,從而為後續分析做服務。聚類問題的一個重要的步驟是確定距離,也就是如何判斷不同樣本之間的相似度。
對時間序列資料,一般有兩大類思路:
基於特徵計算距離
基於原始時間序列計算距離
第一類方法和傳統機器學習的聚類方法沒有多大差別,首先像7。1章節一樣利用原始的時間序列構造特徵,再以特徵進行聚類。
針對時間序列資料,本節將對第二類思路具體展開。一個最常用的演算法叫做動態時間規整dynamic time warping (DTW) ,非常適合用於形狀特徵很重要的時間序列資料。DTW解決的是一對多的問題,歐氏距離的計算要求兩個向量是等長的,也就是要求兩組時間序列的長度是一模一樣才能計算,而很多情況我們得到的時間序列都不是等長的,此時DTW就能發揮作用了。
下面列舉兩個常見的應用場景:
聲音模式識別:假設我們想追蹤聲音來識別說話內容,由於不同人說話的語速有快慢,這就是典型的非等長時間序列的例子,但是每個單詞的聲音模式是相同的,使用DTW就能很好地解決這一問題
股票市場:在我們做股票預測時,股票市場由於存在巨大的波動性,導致在短期內不一定完全重合,但是從長期看很容易捕獲相同的模式
透過一幅圖可以幫助我們理解DTW的演算法本質,DTW的核心是捕獲時間序列的模式或形狀特徵,不要求時間軸一一對應。
DTW方法有一些基本的規則:
一條時間序列上的每個點都能和另一條時間序列上的某個點相匹配
一條時間序列的開始點總是和另一條時間序列的開始點相匹配(不一定是一對一)
一條時間序列的終止點總是和另一條時間序列的終止點相匹配(不一定是一對一)
兩個時間序列的匹配連線不會交叉
計算DTW距離的演算法如下,是典型的動態規劃演算法。
from
math
import
sqrt
import
numpy
as
np
ts1
=
[
1
,
2
,
3
]
ts2
=
[
2
,
2
,
2
,
3
,
4
]
def
distDTW
(
ts1
,
ts2
)
DTW
=
{}
for
i
in
range
(
len
(
ts1
)):
DTW
[(
i
,
-
1
)]
=
np
。
inf
for
i
in
range
(
len
(
ts2
)):
DTW
[(
-
1
,
i
)]
=
np
。
inf
DTW
[(
-
1
,
-
1
)]
=
0
for
i
in
range
(
len
(
ts1
)):
for
j
in
range
(
len
(
ts2
)):
dist
=
(
ts1
[
i
]
-
ts2
[
j
])
**
2
DTW
[(
i
,
j
)]
=
dist
+
min
(
DTW
[(
i
-
1
,
j
)],
DTW
[(
i
,
j
-
1
)],
DTW
[(
i
-
1
,
j
-
1
)])
return
sqrt
(
DTW
[
len
(
ts1
)
-
1
,
len
(
ts2
)
-
1
])
除了DTW距離,還有幾種其他的應用於時間序列的距離演算法:
弗雷歇距離(Fréchet distance )
弗雷歇距離可以理解為狗繩距離,也就是人和狗各自走過一段路所需要的最短的狗繩距離
最長公共子序列(Longest common subsequence )
最長公共子序列主要用於非數值的時間序列,比如兩個英文單詞,最長的公共序列的長度也可以用於判斷距離
python實戰演練
import
matplotlib。pyplot
as
plt
import
pandas
as
pd
import
numpy
as
np
from
sklearn
import
preprocessing
from
sklearn。cluster
import
AgglomerativeClustering
from
sklearn。metrics。cluster
import
homogeneity_score
from
scipy。spatial。distance
import
euclidean
from
fastdtw
import
fastdtw
from
tqdm
import
tqdm
# 歸一化資料
data_cluster
=
data
。
drop
([
‘id’
,
‘classes’
],
axis
=
1
)
data_values
=
preprocessing
。
scale
(
data_cluster
。
values
)
# 使用第一類聚類思路進行層次聚類
clustering
=
AgglomerativeClustering
(
n_clusters
=
5
,
linkage
=
‘ward’
)
clustering
。
fit
(
data_values
)
# 輸出模型評估指標
homogeneity_score
(
clustering
。
labels_
,
data
。
classes
)
使用構造的特徵進行層次聚類,同質性評估為0。43
rowlist
=
np
。
array
(
range
(
0
,
50
))
for
a
in
[
np
。
array
(
range
(
100
,
150
)),
np
。
array
(
range
(
200
,
250
)),
np
。
array
(
range
(
300
,
350
)),
np
。
array
(
range
(
400
,
450
))]:
rowlist
=
np
。
append
(
rowlist
,
a
)
# 使用第二類聚類思路首先計算DTW距離,這一步計算量比較大,先把結果存下來,並且作為簡化,只選擇了部分資料送入模型
pairwise_dis
=
pd
。
DataFrame
(
np
。
zeros
((
250
,
250
)))
for
index_r
,
r
in
tqdm
(
enumerate
(
rowlist
)):
for
index_c
,
c
in
enumerate
(
rowlist
):
arr1
=
eeg
[
eeg
。
id
==
r
][
‘measurements’
]
。
values
[:
500
]
arr2
=
eeg
[
eeg
。
id
==
c
][
‘measurements’
]
。
values
[:
500
]
distance
,
_
=
fastdtw
(
arr1
,
arr2
,
dist
=
euclidean
)
pairwise_dis
。
iloc
[
index_r
,
index_c
]
=
distance
pairwise_dis
。
to_csv
(
‘data/pairwise_dis。csv’
,
index
=
False
)
pairwise_distance
=
pd
。
read_csv
(
‘data/pairwise_dis。csv’
)
# 使用第二類聚類思路進行層次聚類
dtw_clustering
=
AgglomerativeClustering
(
linkage
=
‘average’
,
n_clusters
=
5
,
affinity
=
‘precomputed’
)
_
=
dtw_clustering
。
fit_predict
(
pairwise_distance
)
# 輸出模型評估指標
homogeneity_score
(
dtw_clustering
。
labels_
,
data
[
data
。
index
。
isin
(
rowlist
)][
‘classes’
])
使用原時間序列計算DTW距離進行層次聚類,同質性評估為0。32