02_K-means_非监督学习

声明:本文集的所有文章都只讨论Python如何使用sklearn进行机器学习。且学习的部分截图来自中国大学MOOC上的Python机器学习应用课程以及EduCoder,侵权删。

2020.3.2

新的学期是真的开始了,就是需要早起有点脑壳疼。而机器学习这边的算法补全也会陆陆续续进行,加油ヾ(◍°∇°◍)ノ゙。

K-means

一、距离

在一个N维的空间中,每一个点在当前空间建立的坐标系中,都有一个唯一标识的 坐标向量 ,例如在三维空间中就有一个点 P(x, y, z)。而两个点之间的距离,就是在一定规则下,两个坐标向量的计算。以下将会讲述 欧氏距离曼哈顿距离

  • 欧氏距离
    欧氏距离是指空间中两个坐标向量的 直线距离 ,所求的是两个点的最短距离。公式如下:
欧氏距离
  • 曼哈顿距离
    曼哈顿距离就像是把两个坐标向量当成两间房子,而它们之间隔着很多的十字路口(图片中左右上下这些箭头),计算方法是向量中 各维的差值的绝对值
曼哈顿距离

代码示范 (点击可以查看完整代码)

import numpy as np

def distance(x, y, p=2):
    '''
    input:x(ndarray):第一个样本的坐标
          y(ndarray):第二个样本的坐标
          p(int):等于1时为曼哈顿距离,等于2时为欧氏距离
    output:distance(float):x到y的距离
    '''
    if p == 1:
        distances = np.abs(x - y)
        dis = 0.0
        for dist in distances:
           dis += dist
        distances = dis
    else:
        distances = np.power(x - y, 2)
        dis = 0.0
        for dist in distances:
            dis += dist
        distances = np.sqrt(dis)
    return distances
两种距离

二、质心

质心 是指在样本空间中的所有样本的均值点,可以想象为见缝插针的形式。

见缝插针

它是所有样本的均衡点,也就是说,所有样本离这一点的距离都是一样的。 K-means算法就是通过不同的质心来给样本聚类的,每个样本都被归类到离它最近的样本。

代码示范 (点击可以查看完整代码)

def cal_Cmass(data):
    '''
    input:data(ndarray):数据样本
    output:mass(ndarray):数据样本质心
    '''
    # ********* Begin *********#
    Cmass = [0] * data.shape[1]
    for d in data:
        Cmass += d
    Cmass /= data.shape[0]
    # ********* End *********#
    return Cmass

这里有一点需要特别说明: 被归一化之后的数据, 每一行为一个样本,而列就是所有样本点都具有的特征(属性),也就是样本们的维数。 比如说,有3列,就是有三个特征点,也就是说他们处于一个三维的空间,质心也应该是三维的。还有就是, 质心的每一维的值是样本每维的均值,不需要等于某个样本。

质心

三、K-means算法思想

K-means算法旨在于使用迭代的方法,通过设定好的几个质心来对数据进行聚类。以下是K-means算法的大致步骤:

  1. 设定分类的数量与最大迭代数,并随机生成相应数量的质心第一次的质心是随机的,因为K-means是非监督学习,所以很依赖给出的分类数,分多了分少了都会出现没那么好的结果。而最大迭代数用于防止死循环。
  2. 计算样本点与各质心的距离,分类,生成标签将所有样本点依次跟每个质心计算距离,将其归类到离它最近的质心的一类中,生成一个 标签数组 (一个一维数组,长度为数据源的行数,因为源数据一行为一个样本,所以这个标签数组每一个元素就记录着该样本对应的类别)。
  3. 更新每一类的质心,并再次分类和生成新标签分类计算,求出每一类样本的均值,更新质心。之后每一类都再进行样本跟每一个质心的距离计算,生成新标签。
  4. 如果达到最大迭代数,或者所有质心都基本不再变化,聚类完毕 : 否则,循环2、3两步,直到满足这些条件,退出循环,完成聚类。

代码示范 (点击可以查看完整代码)

# 对整个数据集X进行Kmeans聚类,返回其聚类的标签
def predict(self, X):
    # 从所有样本中随机选取self.k样本作为初始的聚类中心
    # 迭代,直到算法收敛(上一次的聚类中心和这一次的聚类中心几乎重合)或者达到最大迭代次数
    # 将所有进行归类,归类规则就是将该样本归类到与其最近的中心
    # 计算新的聚类中心
    # 如果聚类中心几乎没有变化,说明算法已经收敛,退出迭代
    self.init_random_centroids(X)
    self.create_clusters(self.centroids_list, X)
    for i in range(self.max_iterations):
        new_centroid = self.update_centroids(self.clusters, X)
        if 0.98 < np.sum((new_centroid / self.centroids_list)) < 1.02:
            break
        self.centroids_list = new_centroid
        self.create_clusters(self.centroids_list, X)
    return self.clusters

在这里说明一下,我设置只要两次的所有质心只差小于正负0.02,就可以结束循环了。

K-means

四、Scikit-learn中的K-means

sklearn 中的 K-means 简化了步骤,只需要先使用 fit() 函数来训练,再使用 predict() 来预测生成标签即可

代码示范 (点击可以查看完整代码)

def kmeans_cluster(data):
    '''
    input:data(ndarray):样本数据
    output:result(ndarray):聚类结果
    '''
    km = KMeans(n_clusters=3, random_state=8)
    km.fit(data)
    result = km.predict(data)
    return result
K-means


你可能感兴趣的:(02_K-means_非监督学习)