ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

EEMD/CEEMDAN时序分解+KMeans聚类实战指南

EEMD/CEEMDAN时序分解+KMeans聚类实战指南 简介本资源是一套基于Python从零实现KMeans聚类算法的完整教学与实践源码包面向数据分析初学者、机器学习入门者及高校课程设计学生旨在帮助读者深入理解无监督聚类的核心原理与工程落地细节。压缩包共204个文件141个CSV数据集、43个PNG聚类可视化图、16个Python核心脚本、2个JPG示意图及1个.gitignore总大小45.42MB其中CSV文件涵盖EEMD、CEEMDAN等多类预处理时序数据PNG/JPG用于展示不同K值下的簇划分效果Python脚本则模块化实现了质心初始化、距离计算、标签分配、质心更新及轮廓系数评估等关键环节。目前已有631人学习下载资源结构清晰、注释充分既可直接运行复现经典聚类流程也支持替换自定义数据进行拓展实验是掌握算法底层逻辑与提升代码实现能力的优质实践材料。1. 这不是另一个“抄 sklearn 的 KMeans 教程”203 个文件里藏着 EEMD/CEEMDAN 时序分解 KMeans 聚类的完整 pipeline 实战包你手头正跑着一段工业传感器时序数据采样率高、噪声强、存在多尺度振荡——直接扔进sklearn.cluster.KMeans结果簇中心漂移、轮廓系数跌破 0.3、业务方指着热力图问“这分的是设备状态还是随机噪声”这个源码包不是教你怎么调n_clusters3的玩具 demo。它是一套已落地验证的时序聚类工程化方案用data_EEMD.csv到data_CEEMDAN8.csv这 12 个不同分解粒度的 CSV 文件实打实走完「EEMD/CEEMDAN 信号分解 → IMF 分量筛选 → 特征重构 → KMeans 质心初始化KMeans→ 多轮迭代收敛 → 轮廓系数Calinski-Harabasz 双指标评估 → PNG 结果可视化」全链路。141 个 CSV 不是凑数而是覆盖了从原始信号、各阶 IMF、残差项到最终聚类标签的每一步中间态43 张 PNG 也不是截图而是kmeans_visualize.py自动生成的簇内距离热力图、质心轨迹动图、IMF 分量贡献度雷达图。它解决的不是“KMeans 原理是什么”而是“为什么我的振动信号聚类总在第 3 次迭代就发散”。适合正在处理轴承故障诊断、风电功率波动归因、或水质监测异常模式识别的工程师——你不需要重造轮子但必须知道轮子在哪一环卡过轴承。2. 从 data_EEMD.csv 到 kmeans_main.py拆解这个包的三层结构与核心模块职责2.1 数据层12 类分解文件命名规则与物理意义映射包内 CSV 文件并非随意堆放其命名严格对应经验模态分解EMD家族算法的输出逻辑data_EEMD.csv标准 EEMD 分解结果含 10 个 IMF 分量 1 个残差项列名为IMF_1,IMF_2, ...,Residualdata_EEMDV2_*.csv如_6,_7,_8,_9V2 版本 EEMD调整了白噪声幅值0.2→0.35和集成次数50→100用于验证分解鲁棒性data_CEEMDAN.csv互补 EEMD 分解消除模态混叠IMF_1高频分量信噪比提升 22%见ceemdan_snr_report.pngk-data-EEMD1.csv关键这是EEMD1.csv经特征工程后的聚类输入文件——包含 7 列IMF_3_std,IMF_5_kurtosis,Residual_energy,IMF_1_max_freq,IMF_2_skewness,IMF_4_entropy,timestamp_bin按 5 分钟切片提示不要直接用data_EEMD.csv原始 IMF 矩阵跑 KMeans。原始分量间存在强相关性IMF_1与IMF_2相关系数达 0.87会导致质心计算失效。必须先通过feature_engineer.py提取统计特征该脚本默认启用scipy.stats的 12 种时域指标但实际只保留 7 个低相关性特征见feature_correlation_matrix.csv。2.2 算法层16 个 Python 文件的分工逻辑与调用链整个聚类流程由kmeans_main.py驱动其内部调用关系如下# kmeans_main.py 核心流程简化版 from data_loader import load_and_preprocess # 加载 k-data-EEMD1.csv执行 MinMaxScaler from kmeans_core import KMeansCustom # 自研类非 sklearn支持 KMeans 初始化 from evaluator import calculate_metrics # 计算 silhouette_score, calinski_harabasz_score from visualizer import plot_cluster_results # 生成 3 类 PNG散点图、热力图、质心轨迹 if __name__ __main__: X load_and_preprocess(k-data-EEMD1.csv) # 输出 shape: (n_samples, 7) model KMeansCustom(n_clusters4, max_iters100, init_methodkmeans) labels model.fit_predict(X) # 返回 (n_samples,) 数组 metrics calculate_metrics(X, labels) plot_cluster_results(X, labels, model.centroids_)kmeans_core.py是真正的“心脏”__init__中init_methodkmeans触发kmeans_plusplus_init()函数该函数不简单选远点而是按概率加权距离平方越大被选中概率越高fit_predict()内部实现while iter max_iters and not converged:循环每次迭代后计算质心位移均值np.mean(np.linalg.norm(new_centroids - old_centroids, axis1))阈值设为1e-4非 sklearn 默认的1e-6因时序特征尺度差异大evaluator.py的calculate_metrics()返回字典{ silhouette: 0.623, # 0.5 表示合理分簇 calinski_harabasz: 1248.7, # 数值越大越好此处 1000 为优 inertia: 387.2, # 簇内平方和用于肘部法则 cluster_sizes: [142, 98, 67, 53] # 各簇样本数避免极端不平衡 }2.3 可视化层PNG 图像生成逻辑与业务可读性设计visualizer.py生成的 43 张 PNG 并非简单 scatter plotcluster_scatter_*.pngX/Y 轴为IMF_3_std和Residual_energy点颜色按簇标签大小按IMF_1_max_freq缩放——高频分量越强点越大直观暴露“高振动能量是否集中在某簇”distance_heatmap_*.png计算每个样本到所属簇质心的欧氏距离按时间顺序排列成热力图横轴为样本索引纵轴为距离值红色区块即异常离群点centroid_trajectory_*.png绘制质心在 7 维特征空间的移动路径每迭代一次画一个箭头最后 5 次迭代的质心用星号标出——若箭头长度持续 0.05说明未收敛需调max_iters3. KMeans 初始化为何在时序数据上失效三个真实踩坑记录与修复方案3.1 现象kmeans_main.py运行 3 次每次silhouette_score差异超 0.2且inertia波动剧烈原因原始kmeans_plusplus_init()函数对data_EEMD1.csv的IMF_1_max_freq列单位Hz范围 0–2500和Residual_energy列单位dB范围 -120-40未做标准化导致距离计算被量纲大的特征主导。KMeans 选初始质心时IMF_1_max_freq的权重占 92%其他特征几乎无影响。解决在data_loader.py的load_and_preprocess()函数末尾强制添加from sklearn.preprocessing import StandardScaler scaler StandardScaler() # 注意不是 MinMaxScaler时序特征分布偏态严重 X_scaled scaler.fit_transform(X) # X 为 (n_samples, 7) 特征矩阵 return X_scaled # 后续所有计算基于此注意StandardScaler对IMF_3_std标准差这类本身已是归一化量的特征会过度压缩但实测发现其均值接近 0、标准差约 0.8仍属合理范围无需单独处理。3.2 现象plot_cluster_results()生成的distance_heatmap.png出现大片纯黑区域原因热力图使用plt.imshow()默认插值方式为bilinear当样本数n_samples3606 小时数据5 分钟切片时插值导致距离值被平滑抹除。实际distance_array中有 127 个样本距离 1.5但热力图显示全部 0.8。解决修改visualizer.py中热力图绘制代码plt.imshow(distance_array.reshape(-1, 1).T, cmapviridis, aspectauto, interpolationnone) # 关键禁用插值 plt.colorbar(labelDistance to centroid)3.3 现象k-data-EEMD1.csv加载后X.shape[0]为 359但labels长度为 360报ValueError: Found array with dim 360. Expected 359原因data_EEMD1.csv第 1 行是列名第 2 行起为数据但pandas.read_csv()默认将首行当列名而k-data-EEMD1.csv实际有 360 行数据含表头即有效数据仅 359 行。feature_engineer.py在生成该文件时误将表头写入了数据行。解决手动打开k-data-EEMD1.csv删除第 1 行即IMF_3_std,IMF_5_kurtosis,...这行或在data_loader.py中强制指定df pd.read_csv(filepath, skiprows1) # 跳过第 1 行 X df.values.astype(float)血泪经验所有k-data-*.csv文件都需检查len(df)是否等于预期样本数。该包中k-data-EEMD1.csv和k-data-EEMDV2_8.csv存在此问题其余 10 个正常。4. 如何用这 12 个分解文件做 K 值选择肘部法则 轮廓系数双验证实战4.1 为什么不能只用肘部法则时序数据的特殊性肘部法则看inertia曲线拐点但data_CEEMDAN.csv分解出的IMF_1高频噪声和IMF_4工频谐波能量差异达 3 个数量级导致inertia随K增加缓慢下降拐点模糊K3到K5的inertia降幅仅 12%。此时单靠肘部法则会误选K7造成过拟合。必须叠加轮廓系数——它衡量样本与自身簇的紧密度 vs 与其他簇的分离度对时序模式敏感。4.2 具体操作用kmeans_tune_k.py跑遍 12 个数据源该脚本位于包根目录核心逻辑# kmeans_tune_k.py from kmeans_core import KMeansCustom from evaluator import calculate_metrics import numpy as np def tune_k_for_dataset(filepath, k_rangerange(2, 10)): X load_and_preprocess(filepath) # 同前返回标准化后特征 results {} for k in k_range: model KMeansCustom(n_clustersk, init_methodkmeans) labels model.fit_predict(X) metrics calculate_metrics(X, labels) results[k] { inertia: metrics[inertia], silhouette: metrics[silhouette], calinski_harabasz: metrics[calinski_harabasz] } return results # 对每个数据源运行 datasets [ k-data-EEMD1.csv, k-data-EEMDV2_6.csv, k-data-CEEMDAN.csv, # ... 其余 9 个 ] all_results {ds: tune_k_for_dataset(ds) for ds in datasets}4.3 结果解读三张表锁定最优 K运行后生成k_tuning_summary.csv关键字段DatasetBest_K_by_SilhouetteBest_K_by_CalinskiConsensus_KNotesk-data-EEMD1.csv444silhouette0.623, CH1248k-data-EEMDV2_8.csv35—silhouette 峰值在 K3 (0.58), CH 峰值在 K5 (1320)需人工判别k-data-CEEMDAN.csv444两指标峰值重合置信度最高提示当Best_K_by_Silhouette ! Best_K_by_Calinski时如EEMDV2_8优先选silhouette更高的 K因为轮廓系数直接反映业务可解释性——K3时cluster_sizes[180,120,60]而K5时出现[95,82,73,65,45]最小簇仅 45 样本难以支撑故障模式分析。4.4 进阶技巧用kmeans_stability.py验证 K 的鲁棒性仅看单次运行结果不够。该脚本对同一数据集重复运行 50 次 KMeans每次random_state不同统计stability_score各次运行中同一样本被分到相同簇的频率均值0.85 为稳定consensus_matrix构建n_samples x n_samples矩阵M[i,j]1若样本 i,j 在 ≥40 次运行中同簇否则 0运行python kmeans_stability.py --dataset k-data-CEEMDAN.csv --k 4输出Stability score for K4: 0.892 Consensus matrix density: 0.341 (higher more stable clustering)若stability_score 0.75说明 K 值受初始化影响过大需换数据源如从EEMD切到CEEMDAN或增加特征维度。5. 把 PNG 可视化变成业务语言三步导出可汇报的聚类结论5.1 从cluster_scatter_*.png提炼设备状态标签cluster_scatter_EEMD1.png中4 个簇的空间分布具有明确物理含义簇 0蓝色IMF_3_std低0.15、Residual_energy高-65 dB→ 设备稳态运行残差能量主导簇 1橙色IMF_3_std高0.25、Residual_energy中-85-70 dB→ 存在中频冲击疑似轴承早期磨损簇 2绿色IMF_1_max_freq1800 Hz、IMF_3_std中 → 高频噪声突增可能为传感器接触不良簇 3红色Residual_energy极低-95 dB、IMF_5_kurtosis8 → 残差能量耗尽IMF_5 尖峰显著对应严重故障阶段这不是主观猜测。label_interpreter.py脚本内置规则引擎if (X[i, 0] 0.15) and (X[i, 2] -65): # IMF_3_std 0.15, Residual_energy -65 label_name Normal elif (X[i, 0] 0.25) and (-85 X[i, 2] -70): label_name Bearing_Wear_Early # ... 其余规则5.2 用distance_heatmap_*.png定位异常时间窗热力图横轴为时间序列索引找到连续 5 个以上红色区块距离 1.2的区间例如sample_index: 120-125对应原始时间戳2023-05-12 14:00:00至14:25:00。此时回查data_EEMD1.csv中该时段IMF_1分量波形 → 发现周期性冲击查k-data-EEMD1.csv中IMF_1_max_freq列 → 该时段值跃升至 2100 Hz结论在 14:00–14:25 发生轴承外圈缺陷建议 48 小时内停机检测5.3 生成《聚类分析报告》的自动化流水线generate_report.py整合全部输出# 读取 metrics、labels、distance_array、centroid_trajectory report { summary: fK{best_k} clusters identified on {dataset}, metrics: {silhouette: 0.623, CH: 1248.7}, cluster_distribution: [142, 98, 67, 53], anomaly_windows: [(120,125), (288,292)], # 时间窗列表 action_items: [ Check bearing at timestamp 2023-05-12 14:00:00, Verify sensor contact at 2023-05-12 19:30:00 ] } # 导出为 PDF用 reportlab和 Excel含原始距离数据运行python generate_report.py --dataset k-data-CEEMDAN.csv --k 410 秒生成带图表、结论、行动项的双格式报告。6. 我再也不敢跳过这三步从血泪翻车现场总结出的 KMeans 时序聚类铁律6.1 铁律一不做 EEMD/CEEMDAN 分解就别碰工业时序聚类去年调试一台齿轮箱振动数据直接用原始信号跑 KMeanssilhouette0.21业务方说“这分的是噪声还是故障”。后来用data_CEEMDAN.csv重跑silhouette升至 0.68簇 2 的IMF_2_skewness显著高于其他簇p0.001对应齿轮断齿的冲击特征。EEMD/CEEMDAN 不是锦上添花是把混沌信号掰开揉碎的手术刀——data_EEMDV2_9.csv里IMF_4分量信噪比比EEMD1.csv高 17%直接让K4的轮廓系数从 0.59 提到 0.63。所以拿到新时序数据第一件事用eemd_decompose.py包内提供跑一遍 CEEMDAN再选k-data-*.csv中信噪比最高的那个。6.2 铁律二StandardScaler是时序特征的后悔药MinMaxScaler是慢性毒药曾用MinMaxScaler处理IMF_1_max_freq0–2500 Hz和Residual_energy-120-40 dBKMeans质心全被IMF_1_max_freq拉偏。换成StandardScaler后各特征对距离计算的贡献权重回归均衡PCA 载荷矩阵显示前 3 主成分累计方差 87%。更关键的是StandardScaler对异常值鲁棒——IMF_5_kurtosis出现 12 个 20 的尖峰MinMaxScaler会把它压缩到 [0,1] 区间顶部而StandardScaler仅将其拉回均值±3σ 范围保留了异常模式的辨识度。6.3 铁律三验证必须用stability_score不能只信单次silhouette有一次用k-data-EEMD1.csv得到silhouette0.65兴奋地交付报告。客户复现时silhouette0.42。查kmeans_stability.py输出stability_score0.61远低于 0.75 阈值。根源是EEMD1分解的IMF_3分量在该批次数据中模态混叠严重导致特征不稳定。立刻切换到k-data-CEEMDAN.csvstability_score0.89silhouette两次运行误差 0.02。单次 silhouette 是快照stability_score 是录像——没看过录像别交快照。从那以后我每次跑 KMeans都强制走一遍kmeans_stability.py哪怕多等 3 分钟。它不保证结果完美但能筛掉 80% 的伪阳性结论。希望帮到你。本文还有配套的精品资源点击获取
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表