机器学习-聚类之K均值(K-means)算法原理及实战

版权声明:转载请注明出处 https://blog.csdn.net/zhouchen1998/article/details/89035533

K-means算法

  • 前言
    • 机器学习方法主要分为监督学习和非监督学习两种。监督学习方法是在样本标签类别已知的情况下进行的,可以统计出各类样本的概率分布、特征空间分布区域等描述量,然后利用这些参数进行分类器设计。在实际应用中,很多情况是无法预先知道样本标签的,因而只能利用非监督机器学习方法进行分析。聚类分析就是典型的非监督学习方法,它在没有给定划分类别的情况下,根据数据自身的距离或者相似度进行样本分组。
    • 给定元素集合D,每个元素具有n个观测属性,对这些属性使用某种算法将D划分成K个子集,要求每个子集内部的元素相似度尽可能高,不同子集的元素相似度尽可能低。聚类分析是一种非监督观察式学习方法,聚类之前不需要知道类别甚至不需要知道类别数量。目前,聚类分析广泛使用于统计学、生物学、数据库技术和市场营销等领域。
    • 聚类分析可以分为两大类,一类是基于概率密度函数估计的直接方法,其原理是设法找到给类别在特征空间的分布参数再进行分类。另一类是基于样本之间相似性度量的间接聚类方法,其原理是设法找出不同类别的核心或者初始类核,再依据样本与这些核心之间的相似性度量将样本聚集为不同类别。
  • 简介
    • 聚类算法很多,如K-means(K均值)、K中心聚类、密度聚类、谱系聚类、最大期望聚类等。这里重点介绍K-meas聚类算法,该算法的基本思想是以空间中K个点为中心进行聚类,对最靠近它们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直到得到最好的聚类结果。K-means算法实现简单、计算速度快、原理易于理解、具有理想的聚类效果,因此该算法是公认的经典数据挖掘算法之一。
  • 原理
    • 下面就以欧式距离为例,说明K-means如何完成聚类,步骤如下。
      • 在n个观测中,随机挑选代表K个簇的种子点,这些种子点即为聚类的初始中心。
      • 分别计算每个数据点到K个中心点的距离,离哪个中心点距离最近就将该数据点分配到哪个簇中。
      • 重新计算每个簇数据的坐标均值,将新的均值作为新的聚类中心。
      • 重复之前两步,知道簇的中心点坐标不变或达到规定的循环次数,形成最终的K个聚类。
    • 必然牵扯的问题
      • K值的选择
        • 肘部法、交叉验证、信息标准、影像法和G-means算法等。
      • 距离度量
        • 欧式距离(需要先标准化)和余弦相似度
      • 迭代结束
        • 目标函数最优或迭代次数上限
    • 算法缺点
      • 需要实现指定K值,必须对分析的数据比较熟悉或者交叉验证才能确定K值。
      • 对噪声数据或者离群点数据敏感,少量的异常数据会对均值产生极大影响。
      • 对于不同的初始值,可能导致完全不同的聚类结果,有的初始值会使结果陷入局部最优解,同时在大规模数据集收敛较慢。
    • 一般流程
      • 初始化聚类数K。
      • 读取数据集。
      • 距离度量函数。
      • 随机生成初始质心,选择初始聚类中心。
      • K-means算法实现。
      • 结果可视化。
  • 实战
    • 实战一 生成二维多类数据,使用sklearn进行聚类。
      • 运行结果
    • 实战二 对鱼类数据集进行聚类。
      •   # -*-coding:utf-8-*-
          from sklearn.pipeline import make_pipeline
          from sklearn.preprocessing import StandardScaler
          from sklearn.cluster import KMeans
          import pandas as pd
          
          df = pd.read_csv('data/fish.csv')
          species = list(df['species'])
          del df['species']
          print(df.head())
          # 归一化预处理
          samples = df.values
          scaler = StandardScaler()
          kmeans = KMeans(n_clusters=4)
          pipline = make_pipeline(scaler, kmeans)
          # 训练
          pipline.fit(samples)
          # 预测
          labels = pipline.predict(samples)
          # 创建DataFrame,装入鱼类数据的聚类类别号与真实种类,交叉表显示
          df = pd.DataFrame({'labels': labels, 'species': species})
          ct = pd.crosstab(df['labels'], df['species'])
          print(ct)
        
      • 运行结果
  • 补充说明
    • 参考书为《Python3数据分析与机器学习实战》,对部分错误修改
    • 具体数据集和代码见我的Github,欢迎Star或者Fork

猜你喜欢

转载自blog.csdn.net/zhouchen1998/article/details/89035533
今日推荐