基于日期梯度图例的PCA与Kmeans聚类散点图绘制及性能测试
油井故障预测场景下的Kmeans聚类可视化与性能评估
一、添加基于日期的渐变式图例
要实现按日期渐变的图例,核心是将日期转换为可映射颜色的数值,再通过Matplotlib的颜色条展示日期刻度。以下是修正并优化后的完整代码:
import numpy as np import pandas as pd import matplotlib.pyplot as plt from matplotlib.dates import num2date from sklearn.preprocessing import StandardScaler, normalize from sklearn.decomposition import PCA from sklearn.cluster import KMeans # 读取数据,Date列为索引 ccData = pd.read_csv("/Users/frun/Desktop/flum/E-43.csv", index_col=0) print("Rows :", ccData.shape[0]) print("Columns :", ccData.shape[1]) # 移除无名列 ccData.drop(ccData.columns[ccData.columns.str.contains('unnamed', case=False)], axis=1, inplace=True) # 标准化与归一化 scaler = StandardScaler() scaled_ccData = scaler.fit_transform(ccData) norm_ccData = normalize(scaled_ccData) # PCA降维到2维 pca_final = PCA(n_components=2) pca_ccData = pca_final.fit_transform(norm_ccData) # Kmeans聚类 kmeans = KMeans(n_clusters=3, random_state=0) cluster_labels = kmeans.fit_predict(pca_ccData) # ---------------------- 处理日期生成渐变颜色 ---------------------- # 将索引(日期)转换为datetime类型 ccData.index = pd.to_datetime(ccData.index) # 转换为Matplotlib可识别的序数时间戳(用于颜色映射) date_nums = ccData.index.map(pd.Timestamp.toordinal) # ---------------------- 绘制带日期渐变的散点图 ---------------------- plt.figure(figsize=(10,6)) # 散点颜色由日期序数决定,使用色盲友好的渐变配色 scatter = plt.scatter(pca_ccData[:,0], pca_ccData[:,1], c=date_nums, cmap=plt.cm.viridis, alpha=0.7) # 添加颜色条并设置可读的日期刻度 cbar = plt.colorbar(scatter) # 生成5个均匀分布的刻度点 cbar.set_ticks(np.linspace(date_nums.min(), date_nums.max(), 5)) # 将数值时间戳转换为YYYY-MM-DD格式 cbar.set_ticklabels([num2date(t).strftime('%Y-%m-%d') for t in cbar.get_ticks()]) cbar.set_label('日期') plt.xlabel("PC1") plt.ylabel("PC2") plt.title("PCA降维后散点图(颜色渐变代表日期)") plt.show() # ---------------------- 带日期渐变的聚类决策边界图(可选) ---------------------- h = .01 x_min, x_max = pca_ccData[:,0].min() - 1, pca_ccData[:,0].max() + 1 y_min, y_max = pca_ccData[:,1].min() - 1, pca_ccData[:,1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) Z = kmeans.predict(np.array(list(zip(xx.ravel(), yy.ravel())))) Z = Z.reshape(xx.shape) plt.figure(figsize=(10,6)) plt.clf() plt.imshow(Z, interpolation='nearest', extent=(xx.min(), xx.max(), yy.min(), yy.max()), cmap=plt.cm.summer, aspect='auto', origin='lower') # 叠加带日期渐变的散点 scatter = plt.scatter(pca_ccData[:,0], pca_ccData[:,1], c=date_nums, cmap=plt.cm.viridis, edgecolor='k', markersize=4) cbar = plt.colorbar(scatter) cbar.set_ticks(np.linspace(date_nums.min(), date_nums.max(), 5)) cbar.set_ticklabels([num2date(t).strftime('%Y-%m-%d') for t in cbar.get_ticks()]) cbar.set_label('日期') plt.xlabel("PC1") plt.ylabel("PC2") plt.title("Kmeans聚类决策边界(颜色渐变代表日期)") plt.show()
关键说明:
- 修正了库导入和
KMeans大小写的语法错误 - 将日期转换为序数数值,作为颜色映射的核心依据
- 使用
viridis渐变配色(色盲友好),可替换为plasma、coolwarm等其他渐变方案 - 自定义颜色条刻度,将数值转换为可读的日期格式,让图例更直观
二、Kmeans聚类模型的性能测试
针对无监督聚类场景,可从内部量化指标和业务场景关联两个维度评估:
1. 内部量化指标(无标签场景)
这类指标基于数据分布的紧凑性与分离度:
(1)轮廓系数(Silhouette Score)
衡量样本与自身聚类的相似度、与其他聚类的差异,取值范围[-1,1],越接近1聚类效果越好。
from sklearn.metrics import silhouette_score sil_score = silhouette_score(pca_ccData, cluster_labels) print(f"轮廓系数:{sil_score:.4f}")
(2)Calinski-Harabasz指数(CH指数)
计算聚类间离散度与聚类内离散度的比值,数值越大说明聚类效果越好。
from sklearn.metrics import calinski_harabasz_score ch_score = calinski_harabasz_score(pca_ccData, cluster_labels) print(f"Calinski-Harabasz指数:{ch_score:.4f}")
(3)Davies-Bouldin指数
衡量每个聚类与最相似聚类的平均相似度,取值越小说明聚类效果越好。
from sklearn.metrics import davies_bouldin_score db_score = davies_bouldin_score(pca_ccData, cluster_labels) print(f"Davies-Bouldin指数:{db_score:.4f}")
2. 业务场景关联评估(油井故障预测)
结合故障预测需求,可做以下分析:
- 若有历史故障记录,统计不同聚类中故障样本的占比,或故障发生前的时长分布
- 分析每个聚类对应的设备特征(振动、温度、压力等),判断是否有聚类对应异常状态,且该状态与故障发生相关
- 跟踪后续数据,观察特定聚类的样本是否更容易出现故障,验证聚类的实际业务价值
内容的提问来源于stack exchange,提问作者numq
相关产品推荐
相关产品推荐

