DTW計(jì)算的結(jié)果是兩個(gè)序列的對(duì)齊路徑以及最小的總對(duì)齊代價(jià)。

2. K-means聚類

K-means是一種基于劃分的聚類算法,目標(biāo)是將數(shù)據(jù)分成?K個(gè)簇,使每個(gè)簇內(nèi)的數(shù)據(jù)點(diǎn)與簇中心的距離平方和最小。

K-means目標(biāo)函數(shù)

結(jié)合DTW后,簇內(nèi)距離采用DTW度量,簇中心定義為簇內(nèi)所有樣本到該中心的DTW距離最小的序列。

完整案例

1. 虛擬數(shù)據(jù)集生成

生成三個(gè)具有不同特征的時(shí)間序列簇,每個(gè)簇包含50個(gè)序列。加入噪聲和隨機(jī)擾動(dòng)模擬真實(shí)場(chǎng)景。

import numpy as np
import matplotlib.pyplot as plt

# 設(shè)置隨機(jī)種子
np.random.seed(42)

# 生成時(shí)間序列簇
def generate_series(base_series, noise_level=0.2, count=50):
series = []
for _ in range(count):
noise = np.random.normal(0, noise_level, len(base_series))
series.append(base_series + noise)
return np.array(series)

# 基礎(chǔ)序列
t = np.linspace(0, 6 * np.pi, 100)
cluster1 = np.sin(t)
cluster2 = np.cos(t)
cluster3 = np.sin(t / 2)

# 生成三個(gè)簇
data_cluster1 = generate_series(cluster1)
data_cluster2 = generate_series(cluster2)
data_cluster3 = generate_series(cluster3)

# 合并數(shù)據(jù)
data = np.vstack([data_cluster1, data_cluster2, data_cluster3])

# 繪制原始數(shù)據(jù)
plt.figure(figsize=(10, 6))
for series in data_cluster1:
plt.plot(series, alpha=0.5, color='red')
for series in data_cluster2:
plt.plot(series, alpha=0.5, color='blue')
for series in data_cluster3:
plt.plot(series, alpha=0.5, color='green')
plt.title('Original Time Series Data')
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()

原始時(shí)間序列分布。紅色、藍(lán)色、綠色分別代表三個(gè)簇,各自具有不同的波動(dòng)特征。

2. 動(dòng)態(tài)時(shí)間規(guī)整(DTW)距離計(jì)算

使用fastdtw庫(kù)實(shí)現(xiàn)DTW距離計(jì)算:

from fastdtw import fastdtw
from scipy.spatial.distance import euclidean

# 計(jì)算 DTW 距離矩陣
def compute_dtw_distance_matrix(data):
n = len(data)
distance_matrix = np.zeros((n, n))
for i in range(n):
for j in range(i + 1, n):
# 確保每個(gè)時(shí)間序列是一維
series_i = np.squeeze(data[i]) # 使用 np.squeeze() 移除多余的維度
series_j = np.squeeze(data[j])

# 確保數(shù)據(jù)是1維
assert series_i.ndim == 1, f"Series {i} is not 1D!"
assert series_j.ndim == 1, f"Series {j} is not 1D!"

distance, _ = fastdtw(series_i, series_j, dist=euclidean)
distance_matrix[i, j] = distance
distance_matrix[j, i] = distance
return distance_matrix

3. K-means聚類

改進(jìn)的K-means將DTW作為距離度量。使用tslearn庫(kù)中的TimeSeriesKMeans實(shí)現(xiàn):

from tslearn.clustering import TimeSeriesKMeans
from tslearn.metrics import dtw

# 使用DTW的K-means聚類
n_clusters = 3
model = TimeSeriesKMeans(n_clusters=n_clusters, metric="dtw", verbose=True)
labels = model.fit_predict(data)

# 繪制聚類結(jié)果
plt.figure(figsize=(10, 6))
colors = ['red', 'blue', 'green']
for i in range(n_clusters):
cluster_data = data[labels == i]
for series in cluster_data:
plt.plot(series, alpha=0.5, color=colors[i])
plt.title('Clustered Time Series')
plt.xlabel('Time')
plt.ylabel('Value')
plt.show()

聚類后的時(shí)間序列分布。不同顏色表示不同的簇,K-means根據(jù)DTW距離成功分離出特征相似的序列。

4. 簇中心與對(duì)齊路徑可視化

提取每個(gè)簇的中心序列,并展示與其他序列的DTW對(duì)齊路徑。

# 提取簇中心
centers = model.cluster_centers_

# 可視化簇中心
plt.figure(figsize=(10, 6))
for i, center in enumerate(centers):
plt.plot(center.ravel(), label=f'Cluster {i+1} Center', linewidth=2)
plt.title('Cluster Centers')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

# 對(duì)齊路徑可視化
from tslearn.metrics import dtw_path

plt.figure(figsize=(10, 6))
series_idx = 0 # 第一簇中的第一條序列
path, _ = dtw_path(data[series_idx], centers[labels[series_idx]])
x_path, y_path = zip(*path)
plt.plot(data[series_idx], label='Sample Series', color='blue')
plt.plot(centers[labels[series_idx]], label='Cluster Center', color='red')
plt.scatter(x_path, y_path, color='black', alpha=0.5, s=10, label='Alignment Path')
plt.title('DTW Alignment Path')
plt.legend()
plt.show()

簇中心的動(dòng)態(tài)變化趨勢(shì),各中心代表簇內(nèi)數(shù)據(jù)的主特征。

單個(gè)序列與簇中心的DTW對(duì)齊路徑,展示了DTW對(duì)時(shí)間序列形狀的彈性匹配能力。

優(yōu)化與調(diào)參

1. 優(yōu)化點(diǎn)

2. 調(diào)參流程

  1. 設(shè)置簇?cái)?shù) :通過(guò)手肘法或輪廓系數(shù)選擇合適的簇?cái)?shù)。
  2. 距離度量:對(duì)比DTW與歐幾里得距離在不同數(shù)據(jù)集上的效果。
  3. 初始參數(shù):采用多次運(yùn)行隨機(jī)初始化,選擇代價(jià)最小的結(jié)果。

通過(guò)結(jié)合K-means與DTW算法實(shí)現(xiàn)時(shí)間序列聚類,成功分離了不同特征的序列簇,并直觀展示了聚類效果及對(duì)齊路徑。后面咱們可以嘗試引入深度學(xué)習(xí)(如LSTM自編碼器)進(jìn)一步提升聚類效果,到時(shí)候再給大家分享。

文章轉(zhuǎn)自微信公眾號(hào)@深夜努力寫Python

上一篇:

突破LSTM,消費(fèi)預(yù)測(cè) !!

下一篇:

突破LSTM!結(jié)合ARIMA時(shí)間序列預(yù)測(cè) !!
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)