早期机器学习 - K-Means
#data-science #ML 14

K-means 聚类

  • 输入类的数目和特征向量,输出类使平方误差最小

方法

# 导入 numpy 和 matplotlib.pyplot
import numpy as np
import matplotlib.pyplot as plt

# 随机生成数据
np.random.seed(0)
# np.vtack: 沿着竖直方向将矩阵堆叠起来
# np.random.normal: 生成正态分布的随机数, loc: 均值, scale: 标准差, size: 生成的随机数的形状, 100行2列
data = np.vstack([
    np.random.normal(loc=[0, 0], scale=1, size=(100, 2)),
    np.random.normal(loc=[5, 5], scale=1, size=(100, 2)),
    np.random.normal(loc=[10, 10], scale=1, size=(100, 2)),
])

# 可视化数据
# plt.scatter(data[:, 0], data[:, 1], s=5) # x 轴是第一列, y 轴是第二列, s: 点的大小
# plt.show()

# 实现 k_means(data, k, max_iters=100) 函数, 返回 labels, centroids
def k_means(data, k, max_iters=100):
    # 随机初始化聚类中心
    centroids = data[np.random.choice(len(data), k, replace=False)]
    for _ in range(max_iters):
        # 计算每个样本点到聚类中心的距离
        distances = np.linalg.norm(data[:, np.newaxis] - centroids, axis=2)
        # 分配聚类
        labels = np.argmin(distances, axis=1)
        # 计算新的聚类中心
        new_centroids = np.array([data[labels == i].mean(axis=0) for i in range(k)])
        # 如果新的聚类中心和旧的聚类中心相同, 则停止迭代
        if np.all(centroids == new_centroids):
            break
        centroids = new_centroids
    return labels, centroids

# 设置聚类数量
k = 3

# 运行 k-means 算法
labels, centroids = k_means(data, k)

# 可视化聚类结果
plt.scatter(data[:, 0], data[:, 1], c=labels, s=5)
plt.scatter(centroids[:, 0], centroids[:, 1], c='r', s=50)
plt.show()

改进

  1. 对于不同的k都尝试聚类 - Bisectional k-means
  2. 排除噪声,尝试多种初值组合

质量评价

  1. RLHF
  2. 纯度 Purity
    1. 对形成的聚类\displaystyle r, 若其中真属于类\displaystyle i的有\displaystyle n_{r}^i, 纯度\displaystyle P(S_{r})=\frac{1}{n_{r}}\max n_{r}^i
    2. 整个结果 \displaystyle Purity = \sum_{r=1}^k \frac{n_{r}}{n}P(S_{r})
  3. F值 F-measure:\displaystyle precision\displaystyle recall 的调和平均
早期机器学习 - K-Means
http://localhost:8090/archives/OqzkL36H
作者
酱紫瑞
发布于
更新于
许可协议