层次聚类和实例分析_层次聚类分析_长沙有肥鱼的博客-程序员宅基地

技术标签: 聚类  python  机器学习  AI数学  人工智能  

层次聚类

层次聚类(Hierarchical Clustering)是聚类算法的一种,通过计算不同类别数据点间的相似度来创建一棵有层次的嵌套聚类树。在聚类树中,不同类别的原始数据点是树的最低层,树的顶层是一个聚类的根节点。创建聚类树有自下而上合并和自上而下分裂两种方法。

作为一家公司的人力资源部经理,你可以把所有的雇员组织成较大的簇,如主管、经理和职员;然后你可以进一步划分为较小的簇,例如,职员簇可以进一步划分为子簇:高级职员,一般职员和实习人员。所有的这些簇形成了层次结构,可以很容易地对各层次上的数据进行汇总或者特征化。

如何划分才是合适的呢?

直观来看,上图中展示的数据划分为2个簇或4个簇都是合理的,甚至,如果上面每一个圈的内部包含的是大量数据形成的数据集,那么也许分成16个簇才是所需要的。

论数据集应该聚类成多少个簇,通常是在讨论我们在什么尺度上关注这个数据集。层次聚类算法相比划分聚类算法的优点之一是可以在不同的尺度上(层次)展示数据集的聚类情况。

基于层次的聚类算法(Hierarchical Clustering)可以是凝聚的(Agglomerative)或者分裂的(Divisive),取决于层次的划分是“自底向上”还是“自顶向下”。 

自底向上的合并算法

层次聚类的合并算法通过计算两类数据点间的相似性,对所有数据点中最为相似的两个数据点进行组合,并反复迭代这一过程。简单的说层次聚类的合并算法是通过计算每一个类别的数据点与所有数据点之间的距离来确定它们之间的相似性,距离越小,相似度越高。将距离最近的两个数据点或类别进行组合,生成聚类树。

相似度的计算

层次聚类使用欧式距离来计算不同类别数据点间的距离(相似度)。

实例:数据点如下

                                              

 分别计算欧式距离值(矩阵)

 将数据点B与数据点C进行组合后,重新计算各类别数据点间的距离矩阵。数据点间的距离计算方式与之前的方法一样。这里需要说明的是组合数据点(B,C)与其他数据点间的计算方法。当我们计算(B,C)到A的距离时,需要分别计算B到A和C到A的距离均值。

经过计算数据点D到数据点E的距离在所有的距离值中最小,为1.20。这表示在当前的所有数据点中(包含组合数据点),D和E的相似度最高。因此我们将数据点D和数据点E进行组合。并再次计算其他数据点间的距离。

后面的工作就是不断的重复计算数据点与数据点,数据点与组合数据点间的距离。这个步骤应该由程序来完成。这里由于数据量较小,我们手工计算并列出每一步的距离计算和数据点组合的结果。

两个组合数据点间的距离

计算两个组合数据点间距离的方法有三种,分别为Single Linkage,Complete Linkage和Average Linkage。在开始计算之前,我们先来介绍下这三种计算方法以及各自的优缺点。

  • Single Linkage:方法是将两个组合数据点中距离最近的两个数据点间的距离作为这两个组合数据点的距离。这种方法容易受到极端值的影响。两个很相似的组合数据点可能由于其中的某个极端的数据点距离较近而组合在一起。

  • Complete Linkage:Complete Linkage的计算方法与Single Linkage相反,将两个组合数据点中距离最远的两个数据点间的距离作为这两个组合数据点的距离。Complete Linkage的问题也与Single Linkage相反,两个不相似的组合数据点可能由于其中的极端值距离较远而无法组合在一起。

  • Average Linkage:Average Linkage的计算方法是计算两个组合数据点中的每个数据点与其他所有数据点的距离。将所有距离的均值作为两个组合数据点间的距离。这种方法计算量比较大,但结果比前两种方法更合理。

我们使用Average Linkage计算组合数据点间的距离。下面是计算组合数据点(A,F)到(B,C)的距离,这里分别计算了(A,F)和(B,C)两两间距离的均值。

 树状图

 层次聚类python

import pandas as pd

seeds_df = pd.read_csv('./datasets/seeds-less-rows.csv')
seeds_df.head()

seeds_df.grain_variety.value_counts()  
Kama wheat        14
Rosa wheat        14
Canadian wheat    14
Name: grain_variety, dtype: int64
varieties = list(seeds_df.pop('grain_variety'))

samples = seeds_df.values
samples
array([[14.88  , 14.57  ,  0.8811,  5.554 ,  3.333 ,  1.018 ,  4.956 ],
       [14.69  , 14.49  ,  0.8799,  5.563 ,  3.259 ,  3.586 ,  5.219 ],
       [14.03  , 14.16  ,  0.8796,  5.438 ,  3.201 ,  1.717 ,  5.001 ],
       [13.99  , 13.83  ,  0.9183,  5.119 ,  3.383 ,  5.234 ,  4.781 ],
       [14.11  , 14.26  ,  0.8722,  5.52  ,  3.168 ,  2.688 ,  5.219 ],
       [13.02  , 13.76  ,  0.8641,  5.395 ,  3.026 ,  3.373 ,  4.825 ],
       [15.49  , 14.94  ,  0.8724,  5.757 ,  3.371 ,  3.412 ,  5.228 ],
       [16.2   , 15.27  ,  0.8734,  5.826 ,  3.464 ,  2.823 ,  5.527 ],
       [13.5   , 13.85  ,  0.8852,  5.351 ,  3.158 ,  2.249 ,  5.176 ],
       [15.36  , 14.76  ,  0.8861,  5.701 ,  3.393 ,  1.367 ,  5.132 ],
       [15.78  , 14.91  ,  0.8923,  5.674 ,  3.434 ,  5.593 ,  5.136 ],
       [14.46  , 14.35  ,  0.8818,  5.388 ,  3.377 ,  2.802 ,  5.044 ],
       [11.23  , 12.63  ,  0.884 ,  4.902 ,  2.879 ,  2.269 ,  4.703 ],
       [14.34  , 14.37  ,  0.8726,  5.63  ,  3.19  ,  1.313 ,  5.15  ],
       [16.84  , 15.67  ,  0.8623,  5.998 ,  3.484 ,  4.675 ,  5.877 ],
       [17.32  , 15.91  ,  0.8599,  6.064 ,  3.403 ,  3.824 ,  5.922 ],
       [18.72  , 16.19  ,  0.8977,  6.006 ,  3.857 ,  5.324 ,  5.879 ],
       [18.88  , 16.26  ,  0.8969,  6.084 ,  3.764 ,  1.649 ,  6.109 ],
       [18.76  , 16.2   ,  0.8984,  6.172 ,  3.796 ,  3.12  ,  6.053 ],
       [19.31  , 16.59  ,  0.8815,  6.341 ,  3.81  ,  3.477 ,  6.238 ],
       [17.99  , 15.86  ,  0.8992,  5.89  ,  3.694 ,  2.068 ,  5.837 ],
       [18.85  , 16.17  ,  0.9056,  6.152 ,  3.806 ,  2.843 ,  6.2   ],
       [19.38  , 16.72  ,  0.8716,  6.303 ,  3.791 ,  3.678 ,  5.965 ],
       [18.96  , 16.2   ,  0.9077,  6.051 ,  3.897 ,  4.334 ,  5.75  ],
       [18.14  , 16.12  ,  0.8772,  6.059 ,  3.563 ,  3.619 ,  6.011 ],
       [18.65  , 16.41  ,  0.8698,  6.285 ,  3.594 ,  4.391 ,  6.102 ],
       [18.94  , 16.32  ,  0.8942,  6.144 ,  3.825 ,  2.908 ,  5.949 ],
       [17.36  , 15.76  ,  0.8785,  6.145 ,  3.574 ,  3.526 ,  5.971 ],
       [13.32  , 13.94  ,  0.8613,  5.541 ,  3.073 ,  7.035 ,  5.44  ],
       [11.43  , 13.13  ,  0.8335,  5.176 ,  2.719 ,  2.221 ,  5.132 ],
       [12.01  , 13.52  ,  0.8249,  5.405 ,  2.776 ,  6.992 ,  5.27  ],
       [11.34  , 12.87  ,  0.8596,  5.053 ,  2.849 ,  3.347 ,  5.003 ],
       [12.02  , 13.33  ,  0.8503,  5.35  ,  2.81  ,  4.271 ,  5.308 ],
       [12.44  , 13.59  ,  0.8462,  5.319 ,  2.897 ,  4.924 ,  5.27  ],
       [11.55  , 13.1   ,  0.8455,  5.167 ,  2.845 ,  6.715 ,  4.956 ],
       [11.26  , 13.01  ,  0.8355,  5.186 ,  2.71  ,  5.335 ,  5.092 ],
       [12.46  , 13.41  ,  0.8706,  5.236 ,  3.017 ,  4.987 ,  5.147 ],
       [11.81  , 13.45  ,  0.8198,  5.413 ,  2.716 ,  4.898 ,  5.352 ],
       [11.27  , 12.86  ,  0.8563,  5.091 ,  2.804 ,  3.985 ,  5.001 ],
       [12.79  , 13.53  ,  0.8786,  5.224 ,  3.054 ,  5.483 ,  4.958 ],
       [12.67  , 13.32  ,  0.8977,  4.984 ,  3.135 ,  2.3   ,  4.745 ],
       [11.23  , 12.88  ,  0.8511,  5.14  ,  2.795 ,  4.325 ,  5.003 ]])
#距离计算的linkage 还有树状图dendrogram
from scipy.cluster.hierarchy import linkage, dendrogram
import matplotlib.pyplot as plt
#进行层次聚类
mergings = linkage(samples, method='complete')
#树状图结果
fig = plt.figure(figsize=(10,6))
dendrogram(mergings,
           labels=varieties,
           leaf_rotation=90,
           leaf_font_size=6,
)
plt.show()

#得到标签结果
#maximum height自己指定
from scipy.cluster.hierarchy import fcluster
labels = fcluster(mergings, 6, criterion='distance')

df = pd.DataFrame({'labels': labels, 'varieties': varieties})
ct = pd.crosstab(df['labels'], df['varieties'])
ct

           

 不同距离的选择会产生不同的结果

import pandas as pd

scores_df = pd.read_csv('./datasets/eurovision-2016-televoting.csv', index_col=0)
country_names = list(scores_df.index)
scores_df.head()
#缺失值填充,没有的就先按满分算吧
scores_df = scores_df.fillna(12)
#归一化
from sklearn.preprocessing import normalize
samples = normalize(scores_df.values)
samples
array([[0.09449112, 0.56694671, 0.        , ..., 0.        , 0.28347335,
        0.        ],
       [0.49319696, 0.        , 0.16439899, ..., 0.        , 0.41099747,
        0.        ],
       [0.        , 0.49319696, 0.12329924, ..., 0.        , 0.32879797,
        0.16439899],
       ...,
       [0.32879797, 0.20549873, 0.24659848, ..., 0.49319696, 0.28769823,
        0.        ],
       [0.28769823, 0.16439899, 0.        , ..., 0.        , 0.49319696,
        0.        ],
       [0.        , 0.24659848, 0.        , ..., 0.        , 0.20549873,
        0.49319696]])
from scipy.cluster.hierarchy import linkage, dendrogram
import matplotlib.pyplot as plt

mergings = linkage(samples, method='single')
fig = plt.figure(figsize=(10,6))
dendrogram(mergings,
           labels=country_names,
           leaf_rotation=90,
           leaf_font_size=6,
)
plt.show()

mergings = linkage(samples, method='complete')
fig = plt.figure(figsize=(10,6))
dendrogram(mergings,
           labels=country_names,
           leaf_rotation=90,
           leaf_font_size=6,
)
plt.show()

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_53660567/article/details/122958202

智能推荐

流放者柯南自建服务器 linux,流放者柯南服务器搭建教程 流放者柯南虚拟机建服务器方法(4)_下载服务端_游侠网...-程序员宅基地

下载服务端ConanExiles搭建个人服务器教程(Windows)1. 下载STEAMCMD https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip2. 解压steamcmd.zip3. 运行steamcmd.exe4. 在steamcmd上运行命令:第一步:打开 steamcmd.exe 程序第二步:输入 login anon..._流放者柯南自建服务器

linux卸载phpstudy_centos-程序员宅基地

ubuntu apt-get卸载软件无法卸载干净的解决方法(ubuntu卸载apache)ubuntu apt-get卸载软件无法卸载干净的解决方法(ubuntu卸载apache) 过sudo apt-get install xxxx 安装软件后,总是无法卸载干净,这里以Apache 为例,提供方法: 首先 复制代码 代码如下: sudo apt-get remove apache2 再 复制代码..._linux删除phpstudy

LeetCode503:下一个更大元素 II_leetcode 503-程序员宅基地

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1。示例 1:输入: [1,2,1]输出: [2,-1,2]解释: 第一个 1 的下一个更大的数是 2;数字 2 找不到下一个更大的数; 第二..._leetcode 503

weblogic对xml中BOM处理异常——org.xml.sax.SAXParseException:Content is not allowed in prolog_weblogic saxparseexception-程序员宅基地

weblogic对xml中BOM处理异常,weblogic不能正确识别BOM导致解析xml文件失败。有BOM的xml文件导致部署异常:org.xml.sax.SAXParseException:Content is not allowed in prolog_weblogic saxparseexception

随便推点

【中软国际实训】——Day4-程序员宅基地

ssm项目实例——分页功能基于前项目实现对用户管理功能的完善——实现用户查看中的分页功能项目内容回顾1.功能实现添加bean.PageInfopackage com.zhongruan.bean;import java.util.List;public class PageInfo<T> { private List<T> list; private int size; private int totalPage; priv

Method类的使用和概述-程序员宅基地

一、Method类代表类中的一个方法的定义,一个Method由修饰符,返回值,方法名称,参数列表组合而成。二、Method提供的方法1、getName();获得方法名。2、getModifiers();获得修饰符。3、getReturnTypes();返回值类型。返回class4、getParameterTypes();返回Class[],参数类型的数组。5、invoke(Object obj,Object…args);三、如何获得Method呢?1、Class方法。2、Method G_method类

运载火箭弹道飞行程序matlab,机载运载火箭飞行程序设计及仿真-程序员宅基地

1引言“快速、机动、廉价、可靠”是未来航天运输系统的发展目标。相对于现有的地基发射运载火箭而言,机载运载火箭空中发射是一种发射方式的改革[1]。这种发射方式利用载机将运载火箭携带至一定的高度后以一定的方式将其投放,使运载器在点火之前就获得了飞机给予的初始势能和动能,这样就可以减少运载火箭所携带的推进剂,提高运载火箭的效能,有效地降低发射成本,同时具备较强的机动性与生存能力,其性能优势明显[2]。运...

flag在python中用法_Python3(进阶)-FLAG的用法-程序员宅基地

[MediaPipe]源代码分析:\u2026\u2026menghaocheng(回复):ctt8888[\/回复)我没学过这个计算器,所以它应该得到支持。我不是特别擅长glsl,你可以自己研究。[MediaPipe]源代码分析:\u2026\u2026ctt8888(回复):ctt8888[\/回复]我不知道问题在哪里了吗?它不支持单通道?期待你的回复(MediaPipe)源代码分析:\u20..._python3 flag

高薪招聘能讲课的JAVA程序员,专、兼职均可-程序员宅基地

发布日期: 16小时之前 工作地点: 北京 招收人数: 若干

解决Xshell连接Linux服务器总掉线的问题-程序员宅基地

Xshell连接linux服务器总掉线,解决办法如下:1、登录服务器后# cd /etc/ssh/# vim sshd_config找到 ClientAliveInterval 0和ClientAliveCountMax 3并将注释符号(”#”)去掉,将ClientAliveInterval对应的0改成3600,保存。ClientAliveInterval 指定了服务器端向客户端请...