无监督学习——凝聚聚类
序
凝聚聚类指的是许多基于相同原则构建的聚类算法,这一原则是:算法首先声明每个点是自己的簇,然后合并两个最相似的簇,直到满足某种停止规则为止。scikit-learn中实现的停止规则是簇的个数,因此相似的簇被合并,直到仅剩下指定个数的簇。还有一些链接准则,规定如何度量”最相似的簇“。这种度量总是定义在两个现有的簇之间。
scikit-learn中实现了以下三种选项:
ward:默认选项。ward挑选两个簇来合并,使得所有簇中的方差增加最小。这通常会得到大小差不多相等的簇。
average:average链接将簇中所有点之间的平均距离最小的两个簇合并。
complete:complete链接(也称为最大链接)将簇中点之间最大距离最小的两个簇合并。
ward适用于大多数数据集,在我们的例子中将使用它。如果簇中的成员个数非常不同(比如其中一个比其他所有都大得多),那么average或complete可能效果更好。
接下来,我通过一个实际例子来说明这个算法。
实际操作
1.数据来源
Student Marks:https://www.kaggle.com/shub99/student-marks
这是一个简单的二维数据集,通过学生的学期成绩来判断这名学生最后可不可以升级(毕业)。该数据集包含100条数据记录,共有三个特征维度,分别是期中成绩(MID-SEM-MARKS),期末成绩(END-SEM-MARKS)以及升级结果(“0”:失败;“1”:成功)。
2.数据处理
1 |
|
老规矩,上来先依次导入建模需要的各个模块,并读取文件。
需要注意的是,这份数据集的文件格式是txt,所以用pd.read_csv读取出来的数据是这个样子的:
所以接下来还需要用方法split来依据特定字符“**,**”进行划分,示例代码如下所示:
同时,每条数据记录都是以字符串(string)的格式存储的,因此我们还需要用格式转换方法astype(“float”)来将原本的字符串格式(string)强制转换成浮点型(float),最终代码如下:
1 |
|
3.使用凝聚聚类
我们看一下凝聚聚类对这个数据集的效果如何。要注意,由于算法的工作原理,凝聚算法不能对新数据点作出预测。因此AgglomerativeClustering没有predict方法。为了构造模型并得到训练集上簇的成员关系,可以改用fit_predict方法,代码如下所示:
1 |
|
PS:推荐大家记一下values方法,这个方法可以把dataframe格式的数据完美转化成相应维度的矩阵数据(array),非常好用。
接下来,我们将聚类结果可视化:
1 |
|
可以看到,算法完成了数据集的聚类。但是上面的图片并没有体现出分类的准确性,所以接下来我们通过对比源数据集中的特征分类来评估算法的精度:
这里主要是通过统计已知结果和聚类结果的差值,来评估算法精度。所以最后,我们可以知道算法的精度为83%。
4.层次聚类与树状图
凝聚聚类生成了所谓的层次聚类。聚类过程迭代进行,每个点都从一个单点簇变为属于最终的某个簇。每个中间步骤都提供了数据的一种聚类(簇的个数也不相同)。有时候,同时查看所有可能的聚类是有帮助的。所以接下来,我们考虑用一种工具来将层次聚类可视化。
不幸的是,目前scikit-learn没有绘制这种图像的功能。但可以利用SciPy轻松生成树状图。SciPy的聚类算法接口与scikit-learn的聚类算法稍有不同。SciPy提供了一个函数,接受数据数组X并计算出一个链接数组,它对层次聚类的相似度进行编码,然后我们可以将这个链接数组提供给SciPy的dendrogram函数来绘制树状图。
1 |
|
树状图在底部显示数据点。然后以这些点(表示单点簇)作为叶节点绘制一棵树,每合并两个簇就添加一个新的父节点。
从下往上看,每层的数据点两两合并,依次类推,直到在顶层生成两个分支。这对应于算法中两个最大的簇。
树状图的y轴不仅说明凝聚算法中两个簇何时合并,每个分支的长度还表示被合并的簇之间的距离。同时我们还可以看到,最大的三个簇(绿色,红色,兰色)在合并成两个簇的过程中跨越了相对较远的距离。
不幸的是,凝聚聚类依然无法分析图形复杂的数据集,如下图所示:
但是,DBSCAN可以解决这个问题。碍于篇幅限制,下一篇文章我再来说一说这个算法。
有很多地方做的不是很好,欢迎网友来提出建议,也希望可以遇到些朋友来一起交流讨论。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!