层次聚类AgglomerativeClustering()树形图可视化与children_属性解析

层次聚类函数AgglomerativeClustering()

我们主要来讲解层次聚类的可视化画图和层次聚类后返回的children_属性,children_属性的理解需要借助可视化图形

1.层次聚类的可视化画图

1.1步骤:

step1:使用 make _ classification()函数创建一个二分类测试数据集

import numpy as np
from scipy.cluster.hierarchy import dendrogram
from sklearn.cluster import AgglomerativeClustering

X, _ = make_classification(n_samples=5, n_features=2, n_informative=2,
                           n_redundant=0, n_clusters_per_class=1, random_state=4)

  step2:写plot_dendrogram函数,主要功能是计算linkage_matrix,作为用来画树状图的函数dendrogram()中的传入参数

def plot_dendrogram(model, **kwargs):
    #  创建链接矩阵,然后绘制树状图 
    #  创建每个节点的样本计数 
    counts = np.zeros(model.children_.shape[0]) 
    n_samples = len(model.labels_)  
    for i, merge in enumerate(model.children_):
        current_count = 0
        for child_idx in merge:
            if child_idx < n_samples:
                current_count += 1  #  叶子节点 
            else:
                current_count += counts[child_idx-n_samples]
        counts[i] = current_count
    linkage_matrix = np.column_stack([model.children_, model.distances_,
                                      counts]).astype(float)
    print(linkage_matrix)
    #  绘制相应的树状图 
    dendrogram(linkage_matrix, **kwargs)

   step3:定义层次分类算法,并训练,然后调用plot_dendrogram(model, truncate_mode='level', p=3)进行画图

#  设置 distance_threshold = 0 ,以确保我们计算的是完整的树 
model = AgglomerativeClustering(distance_threshold=0, n_clusters=None)
model = model.fit(X)

plt.title('Hierarchical Clustering Dendrogram')
#  绘制树状图的前三个级别 
plot_dendrogram(model, truncate_mode='level', p=3)
plt.xlabel("Number of points in node (or index of point if no parenthesis).")
plt.show()

1.2 结果

由于make _ classification()创建数据集的时候只创建了5个数据,比较简单,层次分类树状图的结果如下:

 

另外我在定义plot_dendrogram函数时,使用print(linkage_matrix)输出了用于画图的参数linkage_matrix,我们来看看这个值等于多少? 

linkage_matrix=:

 [[0.         2.         0.30715513 2.        ]
 [1.         4.         0.47108264 2.        ]
 [3.         5.         2.27391048 3.        ]
 [6.         7.         2.55945507 5.        ]]

 以上就是结果,树形图两两相连就是两个点归一个类的意思,比如第0和第2个样本点归到一类,下一次迭代中第3个样本点加入了他们,和他们成为一类

2.children_属性的理解

仔细的朋友一定看到了,linkage_matrix是一个矩阵,如上,那么怎么来理解这个矩阵呢?从代码可以看出,这个矩阵由model.children_, model.distances_和 counts构成,

linkage_matrix = np.column_stack([model.children_, model.distances_, counts]).astype(float)

我们依次来解释:

(1)model.children_:最难懂,如果单独输出model.children_,我们来看看是什么样子

array([[0, 2],
       [1, 4],
       [3, 5],
       [6, 7]], dtype=int64)

英文的解释是这样的:

可以看到,如果[值1,值2 ]中的值小于样本数量,那表示他是叶子节点,也就是原始样本,之前没有参加过归类,数值代表原始样本的索引,如果大于或等于样本数量,那表示他不是叶子节点,他有下游子节点,也就是他是已经归类的结果,下游子节点可通过children_[值-样本数量]找到。

那么model.children_中的值可以看作每次合并成一类的动作,n个样本如果最终全部合并成一类,要经历n-1步。这里5个样本,全部合并成一类要经历4步,所以children_有4行,即4个合并步骤。

下面我们用例子来进一步解释(可以结合上文可视化图看):

本次案例中样本数n_samples=5

  • [0,2]:都小于n_samples,那么都是叶子节点,之前没有归过类,所以直接第0,2样本归一类
  • [1,4]:都小于n_samples,那么都是叶子节点,之前没有归过类,所以直接第1,4样本归一类

    1.2结果图中清晰可见,0—2,1—4相连

  • [3,5]:两个值和n_samples比大小,第一个值3<5 , 意思是第3个样本是叶子节点,之前没有归过类;第二个值5>=5,意思是他已经归过类,包含一部分节点,这个类位置在children_[5-5]=children_[0],即[0,2]。这一步就是把第3个样本和[0,2]归成一类。

    1.2结果图中清晰可见,3与(0—2)相连

  • [6,7]:两个值和n_samples比大小,两个值都大于等于n_samples,那么这次归并是两个已经归过类的类,归成一类,这两个类的位置在children_[6-5]=children_[1]和children_[7-5]=children_[2],即[1,4] 、[3,5]。这一步就是把[1,4] 、[3,5]归成一类

    1.2结果图中清晰可见,(1—4)与(3—5(0—2))相连

综上来说,实际上children_ 的[  ]内的两个数值,可以理解为两个类归为一类的过程,每一个数字可以代表从没有归过类的叶子节点,也可以代表已经归过类的一个类

(2)model.distances_

顾名思义,是距离,两个类归为一类的时候,两个类之间的距离,例如:[0.     2.     0.30715513         2.  ] ,0.30715513就代表第0,2样本之间的距离,再例如:[6.     7.      2.55945507       5. ],2.55945507就代表 (1,4 )和 (3 ,0 ,2)两个类之间的距离

顺便说一句,这里的距离计算方式有很多,看选择,例如可以质心、重心、均值等    

(3)counts

这个是用代码敲出来计算的,计算的是两个类合并成一类后,包含多少节点,例如:[0.     2.     0.30715513         2.  ],2.就代表第0 和2个样本合并后的类包含2个节点,再例如:[6.     7.      2.55945507       5. ],5.就代表(1,4 )和 (3 ,0 ,2)两个类合并成一个类后包含5个节点(样本点)

讲的还算清晰吧,当然linkage_matrix矩阵可以直接求(用某个函数),但是我对比了,其中代表children_这个属性的值理解和直接求model.children_的值再拼接有一点出入,查找子节点类别的时候,children_[值-样本数量-1] 而不是children_[值-样本数量]

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值