python实现层次聚类的方法


Posted in Python onNovember 01, 2021

层次聚类算法

顾名思义,层次聚类就是一层一层的进行聚类,可以由上向下把大的类别(cluster)分割,叫作分裂法;也可以由下向上对小的类别进行聚合,叫作凝聚法;但是一般用的比较多的是由下向上的凝聚方法。

分裂法:

分裂法指的是初始时将所有的样本归为一个类簇,然后依据某种准则进行逐渐的分裂,直到达到某种条件或者达到设定的分类数目。用算法描述:
输入:样本集合D,聚类数目或者某个条件(一般是样本距离的阈值,这样就可不设置聚类数目)
输出:聚类结果

1.将样本集中的所有的样本归为一个类簇;
repeat:
    2.在同一个类簇(计为c)中计算两两样本之间的距离,找出距离最远的两个样本a,b;
    3.将样本a,b分配到不同的类簇c1和c2中;
    4.计算原类簇(c)中剩余的其他样本点和a,b的距离,若是dis(a)<dis(b),则将样本点归到c1中,否则归到c2中;
util: 达到聚类的数目或者达到设定的条件

凝聚法:

凝聚法指的是初始时将每个样本点当做一个类簇,所以原始类簇的大小等于样本点的个数,然后依据某种准则合并这些初始的类簇,直到达到某种条件或者达到设定的分类数目。用算法描述:
输入:样本集合D,聚类数目或者某个条件(一般是样本距离的阈值,这样就可不设置聚类数目)
输出:聚类结果

 1.将样本集中的所有的样本点都当做一个独立的类簇;
   repeat:
        2.计算两两类簇之间的距离(后边会做介绍),找到距离最小的两个类簇c1和c2;
        3.合并类簇c1和c2为一个类簇;
   util: 达到聚类的数目或者达到设定的条件

例图:

python实现层次聚类的方法

欧式距离的计算公式

python实现层次聚类的方法

类簇间距离的计算方法有许多种:
(1)就是取两个类中距离最近的两个样本的距离作为这两个集合的距离,也就是说,最近两个样本之间的距离越小,这两个类之间的相似度就越大
(2)取两个集合中距离最远的两个点的距离作为两个集合的距离
(3)把两个集合中的点两两的距离全部放在一起求一个平均值,相对也能得到合适一点的结果。
e.g.下面是计算组合数据点(A,F)到(B,C)的距离,这里分别计算了(A,F)和(B,C)两两间距离的均值。

python实现层次聚类的方法

(4)取两两距离的中值,与取均值相比更加能够解除个别偏离样本对结果的干扰。
(5)求每个集合的中心点(就是将集合中的所有元素的对应维度相加然后再除以元素个数得到的一个向量),然后用中心点代替集合再去就集合间的距离

实现

接下来以世界银行样本数据集进行简单实现。该数据集以标准格式存储在名为WBClust2013.csv的CSV格式的文件中。其有80行数据和14个变量。数据来源

python实现层次聚类的方法

为了使得结果可视化更加方便,我将最后一栏人口数据删除了。并且在实现层次聚类之后加入PCA降维与原始结果进行对比。

from scipy.cluster.hierarchy import linkage, dendrogram, fcluster
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np


data = pd.read_csv('data/WBClust2013.csv')
data.pop('Pop')
# data.pop('RuralWater')
# data.pop('CellPhone')
# data.pop('LifeExp')
data = data[:20]
country = list(data['Country'])
data.pop('Country')

# 以下代码为仅使用层次聚类

plt.figure(figsize=(9, 7))
plt.title("original data")
mergings = linkage(data, method='average')
# print(mergings)
dendrogram(mergings, labels=country, leaf_rotation=45, leaf_font_size=8)
plt.show()
Z = linkage(data, method='average')
print(Z)
cluster_assignments = fcluster(Z, t=3.0, criterion='maxclust')
print(cluster_assignments)
for i in range(1, 4):
    print('cluster', i, ':')
    num = 1
    for index, value in enumerate(cluster_assignments):
        if value == i:
            if num % 5 == 0:
                print()
            num += 1
            print(country[index], end='  ')
    print()

# 以下代码为加入PCA进行对比
class myPCA():

    def __init__(self, X, d=2):
        self.X = X
        self.d = d

    def mean_center(self, data):
        """
        去中心化
        :param data: data sets
        :return:
        """
        n, m = data.shape
        for i in range(m):
            aver = np.sum(self.X[:, i])/n
            x = np.tile(aver, (1, n))
            self.X[:, i] = self.X[:, i]-x

    def runPCA(self):

        # 计算协方差矩阵,得到特征值,特征向量
        S = np.dot(self.X.T, self.X)
        S_val, S_victors = np.linalg.eig(S)
        index = np.argsort(-S_val)[0:self.d]
        Y = S_victors[:, index]
        # 得到输出样本集
        Y = np.dot(self.X, Y)
        return Y

# data_for_pca = np.array(data)
# pcaObject=myPCA(data_for_pca,d=2)
# pcaObject.mean_center(data_for_pca)
# res=pcaObject.runPCA()

# plt.figure(figsize=(9, 7))
# plt.title("after pca")
# mergings = linkage(res,method='average')
# print(mergings)
# dendrogram(mergings,labels=country,leaf_rotation=45,leaf_font_size=8)
# plt.show()
# Z = linkage(res, method='average')
# print(Z)
# cluster_assignments = fcluster(Z, t=3.0, criterion='maxclust')
# print(cluster_assignments)
# for i in range(1,4):
#     print('cluster', i, ':')
#     num = 1
#     for index, value in enumerate(cluster_assignments):
#         if value == i:
#             if num % 5 ==0:
#                 print()
#             num+=1
#             print(country[index],end='  ')
#     print()

两次分类结果都是一样的:

cluster 1 :
China  United States  Indonesia  Brazil  
Russian Federation  Japan  Mexico  Philippines  Vietnam  
Egypt, Arab Rep.  Germany  Turkey  Thailand  France  
United Kingdom  
cluster 2 :
India  Pakistan  Nigeria  Bangladesh  
cluster 3 :
Ethiopia

通过树状图对结果进行可视化

原始树状图:

python实现层次聚类的方法

PCA降维后的结果:

python实现层次聚类的方法

到此这篇关于python实现层次聚类的文章就介绍到这了,更多相关python层次聚类内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
pyqt4教程之widget使用示例分享
Mar 07 Python
小白入门篇使用Python搭建点击率预估模型
Oct 12 Python
python消费kafka数据批量插入到es的方法
Dec 27 Python
windows下numpy下载与安装图文教程
Apr 02 Python
python基于paramiko将文件上传到服务器代码实现
Jul 08 Python
python 同时读取多个文件的例子
Jul 16 Python
python3调用windows dos命令的例子
Aug 14 Python
原生python实现knn分类算法
Oct 24 Python
wxpython自定义下拉列表框过程图解
Feb 14 Python
python设置环境变量的作用整理
Feb 17 Python
pyspark 随机森林的实现
Apr 24 Python
Python爬虫JSON及JSONPath运行原理详解
Jun 04 Python
Python list列表删除元素的4种方法
Nov 01 #Python
Python面向对象编程之类的概念
Nov 01 #Python
python代码实现扫码关注公众号登录的实战
python编程实现清理微信重复缓存文件
Nov 01 #Python
python调用ffmpeg命令行工具便捷操作视频示例实现过程
Nov 01 #Python
Python字典的基础操作
Nov 01 #Python
Python集合的基础操作
Nov 01 #Python
You might like
PHP 替换模板变量实现步骤
2009/08/24 PHP
php access 数据连接与读取保存编辑数据的实现代码
2010/05/12 PHP
Linux编译升级php的详细方法
2013/11/04 PHP
CI框架开发新浪微博登录接口源码完整版
2014/05/28 PHP
laravel5实现微信第三方登录功能
2018/12/06 PHP
在PHP中输出JS语句以及乱码问题的解决方案
2019/02/13 PHP
强悍无比的WEB开发好助手FireBug(Firefox Plugin)
2007/01/16 Javascript
Javascript 代码也可以变得优美的实现方法
2009/06/22 Javascript
JavaScript为对象原型prototype添加属性的两种方式
2010/08/01 Javascript
IE8提示Invalid procedure call or argument 异常的解决方法
2012/09/30 Javascript
js 数值转换为3位逗号分隔的示例代码
2014/02/19 Javascript
Three.js学习之文字形状及自定义形状
2016/08/01 Javascript
CSS3 media queries结合jQuery实现响应式导航
2016/09/30 Javascript
微信小程序(应用号)开发新闻客户端实例
2016/10/24 Javascript
JavaScript遍历Json串浏览器输出的结果不统一问题
2016/11/03 Javascript
Angularjs在360兼容模式下取数据缓存问题的解决办法
2017/06/22 Javascript
webpack中CommonsChunkPlugin详细教程(小结)
2017/11/09 Javascript
使用express+multer实现node中的图片上传功能
2018/02/02 Javascript
JS中promise化微信小程序api
2018/04/12 Javascript
JavaScript常用数学函数用法示例
2018/05/14 Javascript
Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件
2018/06/19 Javascript
详解操作虚拟dom模拟react视图渲染
2018/07/25 Javascript
Vue动画事件详解及过渡动画实例
2019/02/09 Javascript
基于p5.js 2D图像接口的扩展(交互实现)
2020/11/30 Javascript
[06:04]DOTA2国际邀请赛纪录片:Just For LGD
2013/08/11 DOTA
[00:36]DOTA2上海特级锦标赛 Alliance战队宣传片
2016/03/04 DOTA
Python二进制串转换为通用字符串的方法
2018/07/23 Python
Python Gitlab Api 使用方法
2019/08/28 Python
StubHub中国:购买和出售全球活动门票
2020/01/01 全球购物
Crabtree & Evelyn欧盟:豪华洗浴、身体和护发
2021/03/09 全球购物
我们在web应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,如何输出一个某种编码的字符串?
2014/03/30 面试题
学生实习介绍信
2014/01/15 职场文书
药剂专业自荐信范文
2014/04/16 职场文书
2014年环卫工作总结
2014/11/22 职场文书
工作检讨书范文
2015/01/23 职场文书
JavaScript实现酷炫的鼠标拖尾特效
2022/02/18 Javascript