运用python进行层次聚类

版权声明:All rights reserved by LK12, reprint please explain the source https://blog.csdn.net/qq_40527086/article/details/83218513

运用python进行层次聚类

学习scipy库 很重要呀
需要引入的类

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.cluster.hierarchy as sch #用于进行层次聚类,画层次聚类图的工具包
import scipy.spatial.distance as ssd
from scipy.cluster.vq import vq,kmeans,whiten
import numpy as np

我们使用的原始数据如下

#生成待聚类的数据点,这里生成了20个点,每个点4维:
points=scipy.randn(20,4)  

接下来的一些代码如下:

#1. 层次聚类
#生成点与点之间的距离矩阵,这里用的欧氏距离:
disMat = sch.distance.pdist(points,'euclidean') 
#进行层次聚类:
Z=sch.linkage(disMat,method='average') 
#将层级聚类结果以树状图表示出来并保存为plot_dendrogram.png
P=sch.dendrogram(Z)
plt.savefig('plot_dendrogram.png')
#根据linkage matrix Z得到聚类结果:
cluster= sch.fcluster(Z, t=1, 'inconsistent') 
print "Original cluster by hierarchy clustering:\n",cluster

#2. k-means聚类
#将原始数据做归一化处理
data=whiten(points)

#使用kmeans函数进行聚类,输入第一维为数据,第二维为聚类个数k.
#有些时候我们可能不知道最终究竟聚成多少类,一个办法是用层次聚类的结果进行初始化.当然也可以直接输入某个数值. 
#k-means最后输出的结果其实是两维的,第一维是聚类中心,第二维是损失distortion,我们在这里只取第一维,所以最后有个[0]
centroid=kmeans(data,max(cluster))[0]  

#使用vq函数根据聚类中心对所有数据进行分类,vq的输出也是两维的,[0]表示的是所有数据的label
label=vq(data,centroid)[0] 
print "Final clustering by k-means:\n",label

函数的具体用法

具体参考官方文档:
scipy.spatial.distance.pdist 官方描述
scipy.spatial.distance.squareform官方描述
scipy.cluster.hierarchy.linkage 官方描述
计算

X= [[2], [8], [0], [4], [1], [9], [9], [0]]
Y = ssd.pdist(X,metric ='seuclidean')
square_Y = ssd.squareform(Y)
Z = sch.linkage(Y, method='complete')#, metric="correlation")

运算得到各值及含义如下:

Y = array([6., 2., 2., 1., 7., 7., 2., 8., 4., 7., 1., 1., 8., 4., 1., 9., 9.,
       0., 3., 5., 5., 4., 8., 8., 1., 0., 9., 9.])  #各样本间距离,取上三角
Z = linkage(X, 'single')  ==> Z:

analysis:
下面序列从数字8开始,因为原始数据有8个,但是序列从0开始计算,所以使用了0~7号的数字序号。
[[  2.   7.   0.   2.] <== x[8] = {x[2], x[7]}  
 [  5.   6.   0.   2.] <== x[9] = {x[5],x[6]}
 [  0.   4.   1.   2.] <== x[10] = {x[0], x[4]}
 [  8.  10.   1.   4.] <== x[11] = {x[8], x[10]} = {x[2], x[7], x[0], x[4]}
 [  1.   9.   1.   3.] <== x[12] = {x[1], x[9]} = {x[1], x[5], x[6]}
 [  3.  11.   2.   5.] <== x[13] = {x[3], x[11]} = {x[3], x[8], x[10]} = {x[3], x[2], x[7], x[0], x[4]}
 [ 12.  13.   4.   8.]]<== x[14] = {x[12], x[13]} = {x[1], x[9], x[3], x[11]} = {x[1], x[5], 
 x[6], x[3], x[8], x[10]} = {x[1], x[5], x[6], x[3], x[2], x[7], x[0], x[4]}

显然,第一列和第二列代表聚集的两类的序列号,第三列代表第一列和第二列序号所代表的集群在聚集时的距离(与层次聚类图的高度相等),第四列代表聚集时所包含的原始数据的个数。

一些函数具体的参数含义

1.linkage(y, method=’single’, metric=’euclidean’) 
共包含3个参数: 
y是距离矩阵,由pdist得到;method是指计算类间距离的方法,比较常用的有3种: 
(1)single:最近邻,把类与类间距离最近的作为类间距 
(2)complete:最远邻,把类与类间距离最远的作为类间距 
(3)average:平均距离,类与类间所有pairs距离的平均


2.fcluster(Z, t, criterion=’inconsistent’, depth=2, R=None, monocrit=None) 
第一个参数Z是linkage得到的矩阵,记录了层次聚类的层次信息; t是一个聚类的阈值-“The threshold to apply when forming flat clusters”,在实际中,感觉这个阈值的选取还是蛮重要的.另外,scipy提供了多种实施阈值的方法(criterion):
[具体参考](https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.fcluster.html#scipy.cluster.hierarchy.fcluster)

3.kmeans(obs, k_or_guess, iter=20, thresh=1e-05, check_finite=True) 
输入obs是数据矩阵,行代表数据数目,列代表特征维度; k_or_guess表示聚类数目;iter表示循环次数,最终返回损失最小的那一次的聚类中心; 
输出有两个,第一个是聚类中心(codebook),第二个是损失distortion,即聚类后各数据点到其聚类中心的距离的加和.

层次聚类详解

猜你喜欢

转载自blog.csdn.net/qq_40527086/article/details/83218513
今日推荐