欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

机器学习算法(21)python实现用SciPy进行全连接的凝聚层次聚类算法

程序员文章站 2022-07-14 11:40:46
...

现研究另一种基于原型的聚类算法-全连接的凝聚层次聚类算法。其中三个概念分别代表:
层次聚类:它允许绘制树状图(二进制层次聚类的可视化);不需要预先指定集群数目。
凝聚聚类:首先从每个集群包括单个样本开始,合并最接近的集群,直到只剩下一个集群为止。
全连接方法:计算两个集群中最不相似的成员之间的距离,然后合并两个集群即比较最不相似的成员然后合并。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, squareform
from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import dendrogram

# 随机生成样本
np.random.seed(123)
variables = ['X', 'Y', 'Z']
labels = ['ID_0', 'ID_1', 'ID_2', 'ID_3', 'ID_4']

X = np.random.random_sample([5, 3])*10
df = pd.DataFrame(X, columns=variables, index=labels)
print(df)

# 用SciPy的spatial.distance子模块的pdist函数计算距离矩阵作为层次聚类算法的输入
row_dist = pd.DataFrame(squareform(pdist(df, metric='euclidean')),  # 欧氏距离
                        columns=labels,
                        index=labels)
print(row_dist)

# 调用SciPy中的cluster.hiera-rchy子模块的linkage函数来应用全连接凝聚方法处理集群,
# 处理结果将返回在所谓的连接矩阵中。
# print(help(linkage))  # 查看方法
row_clusters = linkage(pdist(df, metric='euclidean'),
                       method='complete', metric='euclidean')  # 全连接+欧氏距离,返回值:连接矩阵
'''
连接矩阵:
连接矩阵由若干行组成,其中每行代表一个合并。
第一列和第二列代表每个集群中相似度最低的成员,第三列报告这些成员之间的距离。
最后一列返回每个集群成员的个数
'''
print(pd.DataFrame(row_clusters,
             columns=['row label 1', 'row label 2',
                      'distance', 'no. of items in clust.'],
             index=['cluster %d' % (i + 1)
                    for i in range(row_clusters.shape[0])]))

# 层次聚类树状图
row_dendr = dendrogram(row_clusters,
                       labels=labels,
                       # make dendrogram black (part 2/2)
                       # color_threshold=np.inf
                       )
plt.tight_layout()
plt.ylabel('Euclidean distance')
#plt.savefig('images/11_11.png', dpi=300,
#            bbox_inches='tight')
# plt.show()

# 把树状图附加到热度图
fig = plt.figure(figsize=(8, 8), facecolor='white')  # facecolor:背景颜色
# add_axes为新增子区域,该区域可以座落在figure内任意位置,且该区域可任意设置大小
# 可以用来做一些子图,图中图
axd = fig.add_axes([0.09, 0.1, 0.2, 0.6])
row_dendr2 = dendrogram(row_clusters, orientation='left')  # orientation:指定方向
df_rowclust = df.iloc[row_dendr2['leaves'][::-1]]

# 根据排序后的DataFrame构建热度图
# 热度图中行的顺序反映了树状图中样本的聚类情况
# 热度图中每个样本的颜色编码和特征为数据集做很好的概括
axm = fig.add_axes([0.23, 0.1, 0.6, 0.6])  # x-pos, y-pos, width, height
'''interpolation:使用的插值方法
   cmap:hot_r,其中_r的意思是就是按照颜色越深,数值越大,
   如果想数值越大,颜色越浅,只需要去掉_r,直接为hot就行。
   同时这个hot是热图配色的其中一个主题,主题色参数可选:
        hot 从黑平滑过度到红、橙色和黄色的背景色,然后到白色。
        cool 包含青绿色和品红色的阴影色。从青绿色平滑变化到品红色。
        gray 返回线性灰度色图。
        bone 具有较高的蓝色成分的灰度色图。该色图用于对灰度图添加电子的视图。
        white 全白的单色色图。 
        spring 包含品红和黄的阴影颜色。 
        summer 包含绿和黄的阴影颜色。
        autumn 从红色平滑变化到橙色,然后到黄色。 
        winter 包含蓝和绿的阴影色。
'''
cax = axm.matshow(df_rowclust, interpolation='nearest', cmap='hot_r')

# 去除坐标轴的间隔标记和隐藏坐标轴的轴线来美化修树状图
axd.set_xticks([])
axd.set_yticks([])
# 隐藏树状图边框
for i in axd.spines.values():
    i.set_visible(False)
# 添加颜色条
fig.colorbar(cax)
axm.set_xticklabels([''] + list(df_rowclust.columns))
axm.set_yticklabels([''] + list(df_rowclust.index))
#plt.savefig('images/11_12.png', dpi=300)
plt.show()
print(axd.spines.values())

运行结果:
X Y Z
ID_0 6.964692 2.861393 2.268515
ID_1 5.513148 7.194690 4.231065
ID_2 9.807642 6.848297 4.809319
ID_3 3.921175 3.431780 7.290497
ID_4 4.385722 0.596779 3.980443
ID_0 ID_1 ID_2 ID_3 ID_4
ID_0 0.000000 4.973534 5.516653 5.899885 3.835396
ID_1 4.973534 0.000000 4.347073 5.104311 6.698233
ID_2 5.516653 4.347073 0.000000 7.244262 8.316594
ID_3 5.899885 5.104311 7.244262 0.000000 4.382864
ID_4 3.835396 6.698233 8.316594 4.382864 0.000000
row label 1 row label 2 distance no. of items in clust.
cluster 1 0.0 4.0 3.835396 2.0
cluster 2 1.0 2.0 4.347073 2.0
cluster 3 3.0 5.0 5.899885 3.0
cluster 4 6.0 7.0 8.316594 5.0

odict_values([<matplotlib.spines.Spine object at 0x00000138B5584DF0>, <matplotlib.spines.Spine object at 0x00000138B5584EE0>, <matplotlib.spines.Spine object at 0x00000138B5584FD0>, <matplotlib.spines.Spine object at 0x00000138B559B100>])

运行结果图:
机器学习算法(21)python实现用SciPy进行全连接的凝聚层次聚类算法

机器学习算法(21)python实现用SciPy进行全连接的凝聚层次聚类算法