手动实现 K-Means
本课属于 Coddy Machine Learning 学习旅程的“无监督学习”单元。第 3 课,共 51 课。
K-means 重复两步组成的一轮,以找到 k 个簇。分配:每个点都加入离它最近的中心。移动:每个中心移动到其所对应点的均值处。三个冰淇淋推车:
NumPy 中的一轮操作,其中 dists 是距离表,每个中心对应一列:
labels = dists.argmin(axis=1) # 分配
for c in range(k):
centers[c] = X[labels == c].mean(axis=0) # 移动argmin(axis=1) 会给出每一行中最小值对应的列,也就是离该行最近的中心。一轮又一轮之后,中心会逐渐稳定;当没有中心再移动时,k-means 就完成了。
挑战
简单一家 T 恤制造商根据今天的顾客重新调整 S、M 和 L 码的尺寸。旧尺码表用来设置初始中心,distances(people, centers) 会生成距离表,程序会读取要运行的轮数。
- 每一轮:为每个人分配尺码,然后移动每个中心。
- 打印每种尺码的中心,以及最后一轮分配到该尺码的人数,如下所示。
对于另一家制造商:
Rounds run: 2
S: chest 87.3 cm, length 65.1 cm, 14 people
M: chest 95.0 cm, length 68.9 cm, 31 people
L: chest 104.8 cm, length 72.6 cm, 45 people亲手试试
import numpy as np
# 不要修改下面的代码行
rng = np.random.default_rng(12)
chest = np.concatenate([rng.normal(88, 3, 30), rng.normal(98, 3.5, 35), rng.normal(110, 4, 25)])
length = np.concatenate([rng.normal(66, 1.8, 30), rng.normal(70, 2, 35), rng.normal(75, 2.2, 25)])
# 90 位顾客,每人一行:胸围和衣长,单位为 cm
people = np.round(np.column_stack([chest, length]), 1)
# 旧尺码表给出了 S、M、L 的初始中心点
sizes = ["S", "M", "L"]
centers = np.array([[85.0, 64.0], [90.0, 67.0], [96.0, 69.0]])
rounds = int(input())
# 距离表:每人一行,每个中心点一列
def distances(X, centers):
table = np.zeros((len(X), len(centers)))
for c in range(len(centers)):
table[:, c] = np.sqrt(((X - centers[c]) ** 2).sum(axis=1))
return table
# 在下面编写你的代码
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
无监督学习中的所有课
自己练习: Python 在线编译器