k均值聚类算法原理和(TensorFlow)实现

顾名思义,k均值聚类是一种对数据进行聚类的技术,即将数据分割成指定数量的几个类,揭示数据的内在性质及规律。

咱们知道,在机器学习中,有三种不一样的学习模式:监督学习、无监督学习和强化学习:python

  1. 监督学习,也称为有导师学习,网络输入包括数据和相应的输出标签信息。例如,在 MNIST 数据集中,手写数字的每一个图像都有一个标签,表明图片中的数字值。
  2. 强化学习,也称为评价学习,不给网络提供指望的输出,但空间会提供给出一个奖惩的反馈,当输出正确时,给网络奖励,当输出错误时就惩罚网络。
  3. 无监督学习,也称为无导师学习,在网络的输入中没有相应的输出标签信息,网络接收输入,但既没有提供指望的输出,也没有提供来自环境的奖励,神经网络要在这种状况下学习输入数据中的隐藏结构。无监督学习很是有用,由于现存的大多数数据是没有标签的,这种方法能够用于诸如模式识别、特征提取、数据聚类和降维等任务。


k 均值聚类是一种无监督学习方法。

还记得哈利波特故事中的分院帽吗?那就是聚类,将新学生(无标签)分红四类:格兰芬多、拉文克拉、赫奇帕奇和斯特莱林。

人是很是擅长分类的,聚类算法试图让计算机也具有这种相似的能力,聚类技术不少,例如层次法、贝叶斯法和划分法。k 均值聚类属于划分聚类方法,将数据分红 k 个簇,每一个簇有一个中心,称为质心,k 值须要给定。

k 均值聚类算法的工做原理以下:git

  1. 随机选择 k 个数据点做为初始质心(聚类中心)。
  2. 将每一个数据点划分给距离最近的质心,衡量两个样本数据点的距离有多种不一样的方法,最经常使用的是欧氏距离。
  3. 从新计算每一个簇的质心做为新的聚类中心,使其总的平方距离达到最小。
  4. 重复第 2 步和第 3 步,直到收敛。

准备工做

使用 TensorFlow 的 Estimator 类 KmeansClustering 来实现 k 均值聚类,具体实现可参考https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/contrib/learn/python/learn/estimators/kmeans.py,能够直接进行 k 均值聚类和推理。根据 TensorFlow 文档,KmeansClustering 类对象可使用如下__init__方法进行实例化: 



TensorFlow 文档对这些参数的定义以下:github

  • num_clusters:要训练的簇数。
  • model_dir:保存模型结果和日志文件的目录。
  • initial_clusters:指定如何对簇初始化,取值请参阅 clustering_ops.kmeans。
  • distance_metric:聚类的距离度量方式,取值请参阅 clustering_ops.kmeans。
  • random_seed:Python 中的整数类型,用于初始化质心的伪随机序列发生器的种子。
  • use_mini_batch:若是为 true,运行算法时分批处理数据,不然一次使用所有数据集。
  • mini_batch_steps_per_iteration:通过指定步数后将计算的簇中心更新回原数据。更多详细信息参见 clustering_ops.py。
  • kmeans_plus_plus_num_retries:对于在 kmeans++ 方法初始化过程当中采样的每一个点,该参数指定在选择最优值以前从当前分布中提取的附加点数。若是指定了负值,则使用试探法对 O(log(num_to_sample)) 个附加点进行抽样。
  • relative_tolerance:相对偏差,在每一轮迭代之间若损失函数的变化小于这个值则中止计算。有一点要注意就是,若是将 use_mini_batch 设置为 True,程序可能没法正常工做。

配置:请参阅 Estimator。算法

TensorFlow 支持将欧氏距离和余弦距离做为质心的度量,KmeansClustering 类提供了多种交互方法。在这里使用 fit()、clusters() 和 predict_clusters_idx() 方法:网络



根据 TensorFlow 文档描述,须要给 fit() 提供 input_fn() 函数,cluster 方法返回簇质心,predict_cluster_idx 方法返回获得簇的索引。dom

具体作法

  1. 与之前同样,从加载必要的模块开始,这里须要 TensorFlow、NumPy 和 Matplotlib。这里使用鸢尾花卉数据集,该数据集分为三类,每类都是指一种鸢尾花卉,每类有 50 个实例。能够从https://archive.ics.uci.edu/ml/datasets/iris上下载 .csv 文件,也可使用 sklearn 库的数据集模块(scikit-learn)来加载数据:


     
  2. 加载数据集:


     
  3. 绘出数据集查看一下:


     
    代码输出以下:


     
  4. 能够看到数据中并无明显可见的分类。定义 input_fn 来给 fit() 方法输入数据,函数返回一个 TensorFlow 常量,用来指定x的值和维度,类型为 float。


     
  5. 开始使用 KmeansClustering 类,分为 3 类,设置 num_clusters=3。一般状况下事先并不知道最优的聚类数量,在这种状况下,经常使用的方法是采用肘部法则(elbow method)来估计聚类数量:


     
  6. 使用 clusters() 方法找到这些簇,使用 predict_cluster_idx() 方法为每一个输入点计算分配的簇索引:


     
  7. 对建立的簇进行可视化操做,建立一个包装函数 ScatterPlot,它将每一个点的 X 和 Y 值与每一个数据点的簇和簇索引对应起来:


     
    使用下面的函数画出簇:


     
    结果以下:

    其中“+”号表明三个簇的质心。机器学习

解读分析

上面的案例中使用 TensorFlow Estimator 的 k 均值聚类进行了聚类,这里是提早知道簇的数目,所以设置 num_clusters=3。可是在大多数状况下,数据没有标签,咱们也不知道有多少簇存在,这时候可使用肘部法则肯定簇的最佳数量。

肘部法则选择簇数量的原则是减小距离的平方偏差和(SSE),随着簇数量 k 的增长,SSE 是逐渐减少的,直到 SSE=0,当k等于数据点的数量时,每一个点都是本身的簇。

这里想要的是一个较小的 k 值,并且 SSE 也较小。在 TensorFlow 中,可使用 KmeansClustering 类中定义的 score() 方法计算 SSE,该方法返回全部样本点距最近簇的距离之和:函数



 

对于鸢尾花卉数据,若是针对不一样的 k 值绘制 SSE,可以看到 k=3 时,SSE 的变化是最大的;以后变化趋势减少,所以肘部 k 值可设置为 3:学习



k 均值聚类因其简单、快速、强大而被普遍应用,固然它也有不足之处,最大的不足就是用户必须指定簇的数量;其次,算法不保证全局最优;再次,对异常值很是敏感。.net

相关文章
相关标签/搜索