请求提供基于scikit-learn绘制时间序列聚类质心的示例
时间序列K-means聚类质心绘制示例(scikit-learn实现)
没问题,我来给你一个完整的可运行示例,一步步实现用scikit-learn对你提供的四个时间序列(A_001到A_004)做K-means聚类,并绘制聚类质心,同时把日期显示在左侧。
1. 数据预处理
首先我们需要处理你提供的特殊格式数据集(分号分隔、逗号作为小数点),转换成pandas可处理的格式:
import pandas as pd import numpy as np from sklearn.cluster import KMeans import matplotlib.pyplot as plt # 你的原始数据集 raw_data = """ "";"A_001";"A_002";"A_003";"A_004" "2011-01-01 00:15:00";71,7703349282297;260,416666666667;45,7217504898759;68,203368683718 "2011-01-01 00:30:00";70,7703349282289;270,833333333333;39,1900718484651;68,203368683718 "2011-01-01 00:45:00";62,200956937799;260,416666666667;45,7217504898759;39,6791443850267 "2013-01-06 07:15:00";15,2284263959391;40,5405405405405;1,73761946133797;95,5284552845528 "2013-01-06 08:00:00";13,9593908629442;41,2517780938834;1,73761946133797;119,918699186992 """ # 读取数据:指定分隔符为分号,小数点为逗号,第一列作为索引 df = pd.read_csv(pd.compat.StringIO(raw_data), sep=';', decimal=',', index_col=0) # 将索引转换为datetime类型,方便后续处理 df.index = pd.to_datetime(df.index)
2. 准备聚类用的时间序列数据
对于时间序列聚类,我们把每个列(A_001、A_002等)看作一个独立的样本,每个样本的特征就是该序列在各个时间点的数值。所以需要把数据集转置,让行变成样本,列变成时间点特征:
# 转置数据集:行是时间序列样本,列是对应时间点的数值 X = df.T.values
3. 执行K-means聚类
这里我们选择聚类数k=2(你可以根据自己的需求调整这个数值):
# 初始化KMeans模型,设置随机种子保证结果可复现 kmeans = KMeans(n_clusters=2, random_state=42) # 拟合数据并获取每个样本的聚类标签 cluster_labels = kmeans.fit_predict(X) # 获取聚类质心:每个质心的维度对应一个时间点的均值 centroids = kmeans.cluster_centers_
4. 绘制质心与原时间序列(日期显示在左侧)
接下来我们用matplotlib绘图,把日期放在y轴左侧,每个时间点对应一行,同时展示原始时间序列的点和聚类质心的趋势线:
# 设置绘图风格 plt.style.use('seaborn-v0_8') fig, ax = plt.subplots(figsize=(10, 6)) # 把时间点格式化为字符串,作为y轴标签 timestamps = df.index.strftime('%Y-%m-%d %H:%M:%S').tolist() # 给每个时间点分配y轴位置 y_pos = np.arange(len(timestamps)) # 绘制每个原始时间序列的散点 for i, col_name in enumerate(df.columns): ax.scatter(df[col_name].values, y_pos, label=f'{col_name} (Cluster {cluster_labels[i]})', alpha=0.7, s=80) # 绘制每个聚类的质心线 for cluster_idx in range(kmeans.n_clusters): centroid_values = centroids[cluster_idx] ax.plot(centroid_values, y_pos, marker='o', linestyle='--', linewidth=2, label=f'Cluster {cluster_idx} Centroid', color=f'C{cluster_idx+2}') # 配置y轴:显示日期在左侧 ax.set_yticks(y_pos) ax.set_yticklabels(timestamps) # 设置坐标轴标题 ax.set_xlabel('Numerical Value') ax.set_ylabel('Timestamp') ax.set_title('Time Series Clustering Centroids (Timestamps on Left)') # 把图例放在图外,避免遮挡 ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left') # 调整布局,确保所有元素都显示完整 plt.tight_layout() plt.show()
关键细节说明
- 这里的聚类逻辑是:把每个变量的完整时间序列当作一个样本,KMeans根据这些序列的整体数值分布进行分组,质心代表该组所有序列在各个时间点的平均数值。
- 如果你的时间序列更长,或者有更多变量,只需要替换原始数据,代码逻辑完全通用。
- 你可以尝试调整
n_clusters的值,或者改用其他聚类算法(比如DBSCAN),但KMeans是最容易理解和入门的时间序列聚类方法之一。
内容的提问来源于stack exchange,提问作者user9026419
相关产品推荐
相关产品推荐

