如何用Python为K-Means聚类绘制凹多边形边界?
实现K-Means聚类的凹多边形边界绘制
你说得没错,scipy.spatial.ConvexHull确实只能生成凸多边形边界,没法满足你需要的向内凹陷的聚类边界需求。这里给你几个实用的工具和方法来实现凹多边形边界:
1. 使用Alpha Shapes(阿尔法形状)
这是生成凹包最常用的方案,它可以通过调整alpha参数控制边界的凹陷程度,完美适配不同聚类的点分布。你可以用第三方库alphashape来快速实现:
步骤:
首先安装库:
pip install alphashape
然后修改你代码中的凸包绘制部分,替换为Alpha形状的逻辑:
import pandas as pd import numpy as np from sklearn.metrics.pairwise import pairwise_distances_argmin import matplotlib.pyplot as plt from alphashape import alphashape # 原数据加载与聚类逻辑不变 df = pd.read_csv('https://raw.githubusercontent.com/MachineIntellect/dataset.ml/master/watermelon/watermelon_4_0.csv') X = df.iloc[:,1:].to_numpy() m0 = X[5] m1 = X[11] m2 = X[23] centroids = np.array([m0, m1, m2]) labels = pairwise_distances_argmin(X, centroids) m0 = X[labels == 0].mean(0) m1 = X[labels == 1].mean(0) m2 = X[labels == 2].mean(0) new_centroids = np.array([m0, m1, m2]) # 绘图设置 plt.xlim(0.1,0.9) plt.ylim(0, 0.8) plt.scatter(X[:,0], X[:,1]) plt.scatter(new_centroids[:,0], new_centroids[:,1], c='r', marker = '+') # 替换凸包为Alpha形状绘制凹边界 for i in range(3): points = X[labels == i] # alpha值越小,边界越容易凹陷;越大越接近凸包,可根据你的数据调整 alpha = 0.12 hull = alphashape(points, alpha) # 提取边界坐标并绘制 x, y = hull.exterior.xy plt.plot(x, y, 'r-') plt.show()
注意:
alpha参数需要根据你的点分布手动调整:如果边界太碎就增大alpha,太凸就减小alpha。- 这个库基于Shapely实现,会返回一个多边形对象,方便后续的边界处理。
2. 其他备选方案
如果你不想引入第三方库,还有两个思路:
- DBSCAN预过滤核心点:先用DBSCAN对每个聚类的点进行密度过滤,只保留核心点,再对核心点构建边界(不过这种方法依赖点的密度分布,不一定适合所有场景)。
- 自定义凹包实现:基于Graham扫描或Jarvis步进法的变种,但需要自己写较多代码,不如Alpha形状高效。
内容的提问来源于stack exchange,提问作者user10253483
相关产品推荐
相关产品推荐

