K-means聚类算法之初识

什么是K-means算法?

在聚类问题中,我们会给定一组未加标签的数据集,同时希望有一个算法,能够自动的将这些数据分成有紧密关系的子集或簇。
K均值(K-means)算法是现在最热门最为广泛运用的聚类算法,它是无监督学习的聚类算法。

K-means的聚类步骤

K-means伪代码(吴恩达老师).png

① 自定义或随机初始化 K个聚簇中心;

② 对每个样本进行簇分配。根据距离哪个聚簇中心最近依次分配到K个不同的聚簇中(使用欧几里得算法);

③ 移动聚类中心。对于每个聚类中心,求出各个簇中所有点的均值。

④ 内循环 ②和③,使样本聚类更均值,通常为50

⑤ 步骤图如下三幅:

无标签的数据集.png
初始化聚类中心并进行簇分配图(X为聚簇中心).png
经过多次内循环后,移动聚类中心和标签聚类的结果图.png

Python代码示例

例如有一道这样的题:


一道来自松哥的作业题.png

K-means的py代码如下:

# -*- coding: utf-8 -*-

import numpy as np

K = 2


def dist(x, y):
    """
    欧几里得距离计算
    """
    return np.sqrt(np.sum((x - y) ** 2))


if __name__ == '__main__':
    arrList = [[1, 1], [2, 1], [1, 2], [2, 2],
               [4, 3], [5, 3], [4, 4], [5, 4]]

    arrMap = {}  # 用来记录样本属于哪个簇

    # TODO 随机初始化K个聚类中心,如果提供了初始中心也可以
    centerList = [[1, 1], [1, 2]]  # 初始中心

    for _ in range(10):  # 内循环

        # TODO 进行样本的簇分配
        for i in range(len(arrList)):
            ci = None  # 离聚簇中心的最短距离
            cc = None  # 簇中心下标(标识属于哪个簇)
            for y in range(len(centerList)):
                tmp = dist(np.array(arrList[i]), np.array(centerList[y]))
                if ci is None:
                    ci = tmp
                    cc = y
                else:
                    ci, cc = (tmp, y) if tmp < ci else (ci, cc)

            arrMap[i] = cc

        # TODO 重新计算聚类中心位置(移动聚类中心)
        count = np.zeros(len(centerList))  # 统计样本数
        zeros = np.zeros((len(centerList), 2))  # 每个簇的和
        for i in range(len(arrList)):
            y = arrMap[i]
            count[y] += 1
            zeros[y] = zeros[y] + arrList[i]

        for i in range(len(zeros)):
            # 每个簇的均值,也是聚簇中心的新位置
            centerList[i] = zeros[i] / count[i]

        # print(count)
        # print(zeros)
        print(centerList)
        print(arrMap)
        print()

    pass

友情链接:松哥的幽默博客

你可能感兴趣的:(K-means聚类算法之初识)