You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于scikit-learn KMeans聚类中心绘制聚类边界线的技术咨询

如何为KMeans聚类绘制边界线

嘿,当然可行!作为scikit-learn新手,你可以用几种实用的方法来实现聚类边界的可视化,下面是我整理的几个方案,附代码示例:

1. 用凸包(Convex Hull)绘制紧凑聚类的边界

如果你的聚类是比较紧凑的凸形分布(比如伦敦、牛津这类区域的聚类),凸包是最简单直观的方法——它能画出包裹聚类所有点的最小凸多边形边界。

实现步骤:

  • 导入所需库
  • 提取每个聚类的样本点
  • 计算每个聚类的凸包
  • 绘制凸包的边界线
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from scipy.spatial import ConvexHull

# 假设你已经有了经纬度数据X,以及拟合好的KMeans模型
# X = 你的经纬度数据(形状为(n_samples, 2))
kmeans = KMeans(n_clusters=2, random_state=42).fit(X)
labels = kmeans.labels_
centers = kmeans.cluster_centers_

# 绘制原始数据点和聚类中心
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.6)
plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='X', s=100, label='聚类中心')

# 为每个聚类绘制凸包边界
unique_labels = np.unique(labels)
for label in unique_labels:
    # 提取当前聚类的所有点
    cluster_points = X[labels == label]
    if len(cluster_points) >= 3:  # 至少3个点才能计算凸包
        hull = ConvexHull(cluster_points)
        # 绘制凸包的边
        for simplex in hull.simplices:
            plt.plot(cluster_points[simplex, 0], cluster_points[simplex, 1], 'k--')

plt.legend()
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title('KMeans聚类及凸包边界')
plt.show()

2. 绘制KMeans的决策边界(平滑划分线)

如果你想展示KMeans算法实际的划分逻辑(即每个点属于哪个聚类的分界线),可以通过生成网格点并预测聚类,再用等高线绘制边界。这种方法能得到平滑的划分线,适合展示聚类的整体划分效果。

实现步骤:

  • 生成覆盖数据范围的网格点
  • 用KMeans预测每个网格点的聚类
  • 用contour绘制决策边界
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

# 同样假设你有数据X和拟合好的kmeans模型
kmeans = KMeans(n_clusters=2, random_state=42).fit(X)
labels = kmeans.labels_
centers = kmeans.cluster_centers_

# 绘制原始数据和聚类中心
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.6)
plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='X', s=100, label='聚类中心')

# 生成网格点
x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
                     np.arange(y_min, y_max, 0.01))

# 预测网格点的聚类
Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# 绘制决策边界(用虚线区分)
plt.contour(xx, yy, Z, colors='k', linestyles='--', levels=np.arange(kmeans.n_clusters + 1) - 0.5)

plt.legend()
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title('KMeans聚类及决策边界')
plt.show()

3. 提取边界点并绘制精细边界

如果你的聚类形状不规则,凸包和决策边界都不够精细,可以先找出聚类的边界点(即最近邻属于其他聚类的点),再对这些边界点进行处理(比如凸包或插值)来绘制更贴合实际的边界。

实现步骤:

  • 用最近邻算法找出每个点的最近邻
  • 筛选出最近邻属于不同聚类的点(边界点)
  • 对边界点绘制凸包或直接连接
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.neighbors import NearestNeighbors
from scipy.spatial import ConvexHull

# 假设你有数据X和拟合好的kmeans模型
kmeans = KMeans(n_clusters=2, random_state=42).fit(X)
labels = kmeans.labels_
centers = kmeans.cluster_centers_

# 绘制原始数据和聚类中心
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.4)
plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='X', s=100, label='聚类中心')

# 找出边界点
nbrs = NearestNeighbors(n_neighbors=1).fit(X)
_, indices = nbrs.kneighbors(X)
# 筛选出最近邻不属于同一聚类的点
boundary_mask = labels != labels[indices.flatten()]
boundary_points = X[boundary_mask]
boundary_labels = labels[boundary_mask]

# 为每个聚类的边界点绘制凸包
unique_labels = np.unique(boundary_labels)
for label in unique_labels:
    cluster_boundary = boundary_points[boundary_labels == label]
    if len(cluster_boundary) >= 3:
        hull = ConvexHull(cluster_boundary)
        for simplex in hull.simplices:
            plt.plot(cluster_boundary[simplex, 0], cluster_boundary[simplex, 1], 'k-', linewidth=2)

plt.legend()
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title('KMeans聚类及精细边界')
plt.show()

方法选择建议:

  • 如果聚类是紧凑的凸形 → 用凸包方法,简单高效
  • 如果想展示KMeans的划分逻辑 → 用决策边界方法
  • 如果聚类形状不规则,需要更精细的边界 → 用边界点+凸包方法

内容的提问来源于stack exchange,提问作者Anant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:37:49