单变量散点图聚类咨询:KMeans报错及红标聚类点实现
散点图聚类问题及错误解决



问题说明
我希望对该散点图进行聚类(y轴为测量的密度,x轴为时间)。请问能否实现图中红色高亮的点?在此场景下使用聚类算法是否合理?
相关代码
df = pd.read_csv(path, sep=';', decimal=",", low_memory=False, skiprows=1).drop(['Session ID'], axis=1) df = df.iloc[17120:] print(df.head()) #print(len(df.index)) #df_len = np.arange(len(df.index)) dens = df['Density'] dens = dens.astype(float) print(dens.dtypes) start_dens = 78800+6000 dens_sub = dens[start_dens:] x = np.arange(1,len(dens_sub)+1) plt.plot(dens_sub) plt.ylim([1040,1070]) plt.show() plt.scatter(x, dens_sub) plt.ylim([1050,1062]) X = x, dens_sub wccs = [] for i in range(1,11): kmeans = KMeans(n_clusters=i, max_iter=100) kmeans.fit(X) wccs.append(kmeans.inertia_)
遇到的错误
ValueError: n_samples=2 should be >= n_clusters=3.
请问我遗漏了什么?
错误原因及解决
核心问题是数据维度定义错误:
X = x, dens_sub生成的是包含两个一维数组的元组,KMeans会把它识别为2个样本(每个样本仅1个特征),而非N个样本(每个样本含时间、密度2个特征)。当循环到n_clusters=3时,样本数小于聚类数,触发报错。
解决方法:将X转换为N行2列的特征矩阵,每个样本对应时间和密度两个特征:
import numpy as np # 替换原X定义 X = np.column_stack((x, dens_sub)) # 或用pandas DataFrame # X = pd.DataFrame({'time': x, 'density': dens_sub})
聚类合理性与红色高亮实现
聚类合理性
- 如果红色高亮的是密度偏离正常范围的点,聚类完全可行:KMeans可以将密度相近的点归为一类,偏离值会被分到单独簇中。
- 注意:聚类是无监督算法,不考虑时间序列的顺序。若异常点和时间趋势强相关(如某段时间突然波动),结合时间窗口的异常检测(如3σ原则、孤立森林)效果会更好,但单纯聚类也能识别密度值异常的点。
红色高亮实现
- 聚类后每个样本会得到簇标签,找到对应红色点的簇(比如密度极值所在簇),即可单独标红:
# 完成聚类 kmeans = KMeans(n_clusters=3, max_iter=100) labels = kmeans.fit_predict(X) # 假设红色点属于簇2(需根据实际聚类结果调整) plt.scatter(x[labels==2], dens_sub[labels==2], color='red', label='高亮点') plt.scatter(x[labels!=2], dens_sub[labels!=2], color='blue', label='普通点') plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者a_cris
相关产品推荐
相关产品推荐

