答案页 · 12 道题

Python k-means 聚类:从距离到收敛练习答案

本页汇总 Python k-means 聚类:从距离到收敛 的 12 道练习。先做练习页,再回到这里核对准确答案和原因。

快速答案

本答案页包含 Python k-means 聚类:从距离到收敛 的 4 道选择题、4 道填空题和 4 道输出预测题,每题都给出准确答案和简短解释。

答案已完整展示,建议先尝试作答,再用本页核对。第一次练习最好从互动练习页开始。

01 · 选择题

在 k-means 中,k 表示什么?

  1. 特征数量
  2. 簇的数量正确答案
  3. 训练标签数量
  4. 学习率

答案: 簇的数量

为什么: k 在循环前确定,决定维护多少个质心。

02 · 选择题

所有点都分配给质心之后会发生什么?

  1. 距离函数会被删除
  2. 每个质心移动到已分配点的均值正确答案
  3. 样本会被打乱
  4. 簇数量翻倍

答案: 每个质心移动到已分配点的均值

为什么: 更新步骤会计算每个簇在各坐标上的均值。

03 · 选择题

为什么在 k-means 前要缩放特征?

  1. 它能保证全局最优
  2. 这样就不需要质心了
  3. 量纲大的特征会主导距离正确答案
  4. 缩放会增加簇数量

答案: 量纲大的特征会主导距离

为什么: 以千为单位的特征会压过零到一之间的特征。

04 · 选择题

运行结果是什么?

def distance(a, b):
    return sum((x - y) ** 2 for x, y in zip(a, b)) ** 0.5

centroids = [(0, 0), (5, 5)]
point = (4, 4)
print(min(range(len(centroids)), key=lambda i: distance(point, centroids[i])))
  1. 1正确答案
  2. 0
  3. 2
  4. 0.5

答案: 1

为什么: 这个点距离第二个质心 (5, 5) 更近。

05 · 填空题

补全欧氏距离的指数。

def distance(a, b):
    return sum((x - y) ** 2 for x, y in zip(a, b)) ** ____

print(round(distance((0, 0), (3, 4)), 1))

答案: 0.5

为什么: 开平方等价于把和提升到 0.5 次方。

06 · 填空题

补全最近质心的键函数。

def distance(a, b):
    return sum((x - y) ** 2 for x, y in zip(a, b)) ** 0.5

centroids = [(0, 0), (5, 5)]
point = (1, 1)
print(min(range(len(centroids)), key=lambda i: ____(point, centroids[i])))

答案: distance

为什么: 键函数用距离函数比较当前点与每个质心。

07 · 填空题

补全质心均值的分母。

points = [(0, 0), (0, 1)]
members = points
x_mean = sum(x for x, _ in members) / ____
print(x_mean)

答案: len(members)

为什么: 均值用坐标和除以簇内成员数量。

08 · 填空题

补全收敛判断。

points = [(0, 0), (5, 5)]
labels = [0, 0]
new_labels = [0, 0]
if new_labels == ____:
    print("stable")

答案: labels

为什么: 当新标签与上一轮标签相同时,循环停止。

09 · 输出预测

这段程序打印出什么?

import math
print(math.dist((0, 0), (3, 4)))

答案: 5.0

为什么: 两点之间的欧氏距离是 5.0。

10 · 输出预测

代码的输出结果是什么?

def distance(a, b):
    return sum((x - y) ** 2 for x, y in zip(a, b)) ** 0.5

centroids = [(0, 0), (5, 5)]
point = (1, 1)
print(min(range(len(centroids)), key=lambda i: distance(point, centroids[i])))

答案: 0

为什么: 这个点离第一个质心最近,所以索引是 0。

11 · 输出预测

屏幕上会显示什么?

points = [(0, 0), (0, 1)]
members = points
centroid = (
    sum(x for x, _ in members) / len(members),
    sum(y for _, y in members) / len(members),
)
print(tuple(round(value, 1) for value in centroid))

答案: (0.0, 0.5)

为什么: (0, 0) 与 (0, 1) 的均值是 (0.0, 0.5)。

12 · 输出预测

这段代码会输出什么?

def distance(a, b):
    return sum((x - y) ** 2 for x, y in zip(a, b)) ** 0.5

points = [(0, 0), (0, 1), (5, 5), (5, 6)]
centroids = [(0, 0), (5, 5)]
labels = None
for _ in range(10):
    new_labels = [min(range(len(centroids)), key=lambda i: (distance(point, centroids[i]), i)) for point in points]
    new_centroids = []
    for index in range(len(centroids)):
        members = [point for point, label in zip(points, new_labels) if label == index]
        new_centroids.append((sum(x for x, _ in members) / len(members), sum(y for _, y in members) / len(members)))
    if new_labels == labels:
        break
    labels = new_labels
    centroids = new_centroids
print(labels)

答案: [0, 0, 1, 1]

为什么: 前两个点属于质心 0,后两个点属于质心 1。

先试一遍题目

打开 Python k-means 聚类:从距离到收敛 练习页,用即时反馈回答同样的 12 道题。

练习本课