Menu
CoddyTech

K-Means 失效时

本课属于 Coddy Machine Learning 学习旅程的“无监督学习”单元。第 14 课,共 51 课。

K-means 会把每个簇看作围绕中心的圆形团块。飞镖靶的中心是靶心,周围有一圈圆环,而 K-means 会把它们一分为二:

两张展示 140 支飞镖的图表。左图是真实情况:紧密的靶心簇位于宽大的圆环内。右图展示 k = 2 时的 K-means 结果:一条直的虚线边界将靶盘、圆环和靶心分成左右两半,每一半都有一个中心十字

每个点都会归入离它最近的中心,因此两个簇之间的边界是位于两个中心正中间的一条直线。没有一条直线能把环和它的中心部分分开。

细长、弯曲或非常不均匀的数据组都会以同样的方式影响 k-means。它仍然会返回簇,所以一定要查看图表。

challenge icon

挑战

中等

无人机发现两条弯曲沙洲上有 200 只海豹。起始代码会在 left 面板上绘制真实分布。

  1. 使用 k-means 将海豹聚成 2 类。
  2. 在 right 面板上绘制每个簇,分别标记为 cluster 0 或 cluster 1。
  3. 用黑色的 "X" 标记标出中心,并标记为 centers。添加图例,然后显示图表。

Coddy 会描述你的图表,并统计留在各自沙洲上的海豹数量。下面是两群海豹的示例:

两张图表。左图是真实分布:一群分布范围很广,右侧有一小群聚集得很紧。右图是 k-means,k = 2:小群的簇也包含了大群右侧的边缘,黑色叉号标出了两个中心

亲手试试

import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.cluster import KMeans

# 无人机拍到 200 只海豹在两条弯曲的沙洲上休息(位置以 100 m 为单位)
X, sandbar = make_moons(n_samples=200, noise=0.07, random_state=4)


# 在 ax 上绘制沙洲的实际分布
def draw_truth(ax):
    ax.scatter(X[sandbar == 0, 0], X[sandbar == 0, 1], s=12, label="north bar")
    ax.scatter(X[sandbar == 1, 0], X[sandbar == 1, 1], s=12, label="south bar")
    ax.set_title("The truth")
    ax.legend()


fig, (left, right) = plt.subplots(1, 2, figsize=(9, 4))
draw_truth(left)
right.set_title("K-means, k = 2")

# 在下方编写你的代码
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

无监督学习中的所有课

自己练习: Python 在线编译器