大家好,欢迎来到IT知识分享网。
时间序列聚类概述
时间序列聚类:一种将时间序列数据分为不同组的无监督学习方法。聚类方法旨在找到数据中相似的子集,并将它们归为同一组。对于时间序列数据而言,聚类技术可以发现有相似特征的序列,并将它们划分为同一组,这有助于数据的分类和分析。
时间序列聚类包括两种类型:子序列聚类和时间点聚类。子序列聚类是通过滑动窗口在一个时间序列中提取的一系列子序列上的聚类;时间点聚类基于时间点的时间接近度和对应值的相似性组合的聚类。时间序列聚类通常使用常见的聚类算法,如K-means、Ksahpe 、层次聚类等。
时间序列相识度衡量
动态时间规整
动态时间规整(Dynamic Time Warping,DTW)是一种解决时间序列相似度匹配问题的非常有效的方法。它可以在不同长度和速度的时间序列之间计算距离。
DTW 算法的核心思想是对两个时间序列进行对齐,并计算两个序列之间每个点之间的距离。在对齐的过程中,DTW 可以进行拉伸或压缩时间轴,使得两个序列之间的对应点能够匹配上。因此,DTW 可以处理不同长度和采样率的时间序列数据。
DTW 算法的步骤如下:
- 初始化一个距离矩阵,该矩阵为两个时间序列的长度的二维矩阵。
- 进行动态规划,按照规定的路径更新距离矩阵,从而找到最优的对齐方案。
- 计算两个序列之间的距离,该距离就是对齐后的时间序列之间点之间的距离
from scipy.spatial.distance import euclidean from fastdtw import fastdtw # 定义两个时间序列 x = [1, 2, 3, 4, 5] y = [1, 2, 2, 4, 4, 5] # 使用快速DTW算法进行动态时间规整并计算距离 distance, path = fastdtw(x, y, dist=euclidean) # 打印计算出的距离和对齐路径 print("Distance: ", distance) print("Path: ", path)
欧式距离
对时间序列数据多标量统计特征,如日、月、年的均值、方差、中位数、峰值、偏度等,用欧式距离衡量其相似度
子序列聚类
时间序列子序列聚类(Subsequence Clustering)是一种将时间序列数据按相似性分为不同组的无监督学习方法。与传统时间序列聚类不同,子序列聚类算法不是将整个时间序列进行聚类,而是基于一些已知的子序列特征来进行子序列聚类。
代码中定义了样本数、时间步长和特征维度,并生成了随机时间序列数据。接着,我们定义了子序列长度和步长,使用 extract_subsequences() 函数从原始时间序列数据中提取出子序列数据。然后,我们定义了聚类数目为 3,使用 k-means 算法对子序列数据进行聚类,并获取每个样本所属的类别。最后,我们打印输出了每个类别的样本数量;
import numpy as np from sklearn.cluster import KMeans def extract_subsequences(X, subseq_len, stride): n_samples, n_timesteps, n_features = X.shape subsequences = [] for i in range(n_samples): for j in range(0, n_timesteps - subseq_len + 1, stride): subseq = X[i, j:j+subseq_len, :] subsequences.append(subseq.ravel()) return np.array(subsequences) # 定义样本数、时间步长和特征维度 n_samples, n_timesteps, n_features = 100, 40, 5 # 生成随机时间序列数据 X = np.random.rand(n_samples, n_timesteps, n_features) # 获取子序列数据 subseq_len, stride = 10, 5 X_subseq = extract_subsequences(X, subseq_len=subseq_len, stride=stride) # 定义聚类数目 n_clusters = 3 # 使用 k-means 算法对数据进行聚类 kmeans = KMeans(n_clusters=n_clusters, random_state=0).fit(X_subseq) # 获取每个样本所属的类别 labels = kmeans.labels_ # 打印每个类别的样本数量 unique, counts = np.unique(labels, return_counts=True) print(dict(zip(unique, counts)))
时间点聚类
基于时间序列形状Kshpe聚类
KShape是一种时间序列聚类算法,它可以将时间序列数据分成不同的簇(cluster),使得同一簇内的数据对象的相似度尽可能大。KShape使用了形状距离(Shape distance)来衡量两个时间序列之间的相似度,同时还使用了动态规划(Dynamic Programming)来对每个时间序列进行对齐操作(alignment),以便更准确地计算形状距离。KShape的主要参数包括簇数目(n_clusters)、最大迭代次数(max_iter)和阈值(tol),用户可以根据实际情况进行设置。KShape聚类算法需要先加载tslearn库并调用tslearn.clustering.KShape类。
import numpy as np import matplotlib.pyplot as plt from tslearn.datasets import CachedDatasets from tslearn.preprocessing import TimeSeriesScalerMeanVariance from tslearn.piecewise import SymbolicAggregateApproximation from tslearn.clustering import TimeSeriesKMeans # 加载数据集并对时间序列进行预处理 X_train, y_train, _, _ = CachedDatasets().load_dataset("Trace") X_train = TimeSeriesScalerMeanVariance().fit_transform(X_train[:6]) X_train = SymbolicAggregateApproximation(n_segments=10, alphabet_size_avg=2).fit_transform(X_train) # 定义并训练KMeans聚类器 km = TimeSeriesKMeans(n_clusters=3, verbose=True, random_state=42) y_pred = km.fit_predict(X_train) # 可视化聚类结果 plt.figure(figsize=(10, 10)) for yi in range(3): plt.subplot(3, 1, 1 + yi) for xx in X_train[y_pred == yi]: plt.plot(xx.ravel(), "k-", alpha=.2) plt.plot(km.cluster_centers_[yi].ravel(), "r-") plt.xlim(0, X_train.shape[1]) plt.ylim(-4, 4) plt.title("Cluster %d" % (yi + 1)) plt.tight_layout() plt.show()
基于分段统计特征聚类
时间序列统计特征:
- 基于整个时间序列统计特征有最大值、最小值、均值、方差、偏度、峰度、熵;
- 可以时间序列进行分段,如周、月、年或者自定义分段参数,统计最大值、最小值、均值、方差、偏度、峰度、熵等特征;
- 基于tsfresh时间特征提取特征;
- 基于1,2,3方法选取合适特征,再采用Kmeans、层次聚类、密度聚类等方法聚类;
时间序列计算峰度代码
import pandas as pd # 读取时间序列数据,要求数据第一列为时间,第二列为数值 data = pd.read_csv('time_series.csv', parse_dates=['time'], index_col='time') # 计算时间序列峰度 kurtosis = data.kurtosis()[0] print("该时间序列的峰度为:", kurtosis)
时间序列计算偏度代码
import pandas as pd # 读取时间序列数据,要求数据第一列为时间,第二列为数值 data = pd.read_csv('time_series.csv', parse_dates=['time'], index_col='time') # 计算时间序列偏度 skewness = data.skew()[0] print("该时间序列的偏度为:", skewness)
时间序列计算熵:
t1 =[1,3,1,3,1,3,1,3]
t2 =[1,3,3,1,1,1,3,3]
t1,t2两个序列是不一样的,t1是有规律的,t2相对无序,想描述这种确定与不确定性。可用熵来表示;以下是计算时间序列熵的代码;
from pyentrp import entropy as ent # 读取时间序列数据,要求数据第一列为时间,第二列为数值 data = pd.read_csv('time_series.csv', parse_dates=['time'], index_col='time') # 将时间序列转化为一维数组,并计算其熵 ts = data['value'].values entropy = ent.shannon_entropy(ts) print("该时间序列的熵为:", entropy)
tsfresh 可以自动计算大量的时间序列特性,包含许多特征提取方法和强大的特征选择算法。
# 时间序列特征提取 from tsfresh import extract_features, extract_relevant_features, select_features from tsfresh.feature_extraction import extract_features, EfficientFCParameters from tsfresh.utilities.dataframe_functions import impute from tsfresh.feature_extraction import ComprehensiveFCParameters # extraction_settings = EfficientFCParameters()#计算算所有默认特征和带参数的特征的多种参数组合 extraction_settings = ComprehensiveFCParameters() X = extract_features(data, column_id="id", column_sort='time', default_fc_parameters=extraction_settings, # impute就是自动移除所有NaN的特征 impute_function=impute) X.head()
Kmeans聚类
提供一个Kmeans选取k值函数
from sklearn.metrics import silhouette_score from sklearn.cluster import KMeans from sklearn import preprocessing def get_silhouette_K(data, range_K): K = range(2, range_K) Scores = [] for k in K: kmeans = KMeans(n_clusters=k) kmeans.fit(data) Scores.append(silhouette_score(data, kmeans.labels_, metric='euclidean')) max_idx = Scores.index(max(Scores)) best_k = K[max_idx] plt.plot(K, Scores, 'bx-') plt.xlabel('k') plt.ylabel('silhouette') plt.title('Selecting k with the silhouette Method') plt.show() return best_k
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/83498.html