生信分析_层次聚类
读取数据后,我们就可以进行层次聚类图的绘制了,首先进入scipy参考文档页面,然后找到聚类包Clustering package (scipy.cluster)->层次聚类scipy.cluster.hierarchy,在当前页面下,就可以看到所有层次聚类相关的函数了,我们找到可以画图的函数dendrogram,进入该函数的文档页面,发现该函数需要传入的第一个参数是linkage矩阵,这个矩阵需要函数linkage,进入该函数的文档页面我们看到linkage的说明文档上面的函数scipy.cluster.hierarchy.linkage(y, method='single', metric='euclidean', optimal_ordering=False),传入第一个参数是需要进行层次聚类的数据,这里即可用使用开始读取的数据变量df,第二个参数代表层次聚类选用的方法
import pandas as pd
import seaborn as sns #用于话热图的工具包
from scipy.cluster import hierarchy #用于进行层次聚类,话层次聚类图的工具包
from scipy import cluster
import matplotlib.pyplot as plt
from sklearn import decomposition as skldec #用于主成分分析降维的包
df = pd.read_excel("test.xlsx",index_col=0)
#开始画层次聚类树状图
Z = hierarchy.linkage(df, method ='ward',metric='euclidean')
hierarchy.dendrogram(Z,labels = df.index)
第三个参数代表距离计算的方法,即上面方法中的dist()
函数具体的计算方式,具体方式可以见这个页面。
然后这里我随便选择两个,然后将返回的结果Z传入dendrogram
函数,
关键是这个函数可以自己定义距离。这就为我们进行层次聚类提供了很好的一个接口,因为在特定任务下,scipy函数里面给出的距离不一定能够满足我们自己的实际需求。为了能够自定义距离度量,我进行了一些测试,最后得出自定义距离度量函数需要注意以下几个方面:
函数传入两个参数:比如,自定义函数为:def selfDisFuc(a,b):
传入参数类型是<class 'numpy.ndarray'>
传入参数的维度必须一样
返回值必须是一个代表距离的数
我这处理自定义函数时,因为处理的数据维度不一样,最后只好找到最大维度的数据,然后将不一样的所有
数据后面补上-1(我的数据中不会出现的一个数),然后再处理。
安照上面的三个规则,就能写出自己需要的距离衡量函数了。
#在某个高度进行剪切
label = cluster.hierarchy.cut_tree(Z,height=0.8)
label = label.reshape(label.size,)
#根据两个最大的主成分进行绘图
pca = skldec.PCA(n_components = 0.95) #选择方差95%的占比
pca.fit(df) #主成分析时每一行是一个输入数据
result = pca.transform(df) #计算结果
plt.figure() #新建一张图进行绘制
plt.scatter(result[:, 0], result[:, 1], c=label, edgecolor='k') #绘制两个主成分组成坐标的散点图
for i in range(result[:,0].size):
plt.text(result[i,0],result[i,1],df.index[i]) #在每个点边上绘制数据名称
x_label = 'PC1(%s%%)' % round((pca.explained_variance_ratio_[0]*100.0),2) #x轴标签字符串
y_label = 'PC1(%s%%)' % round((pca.explained_variance_ratio_[1]*100.0),2) #y轴标签字符串
plt.xlabel(x_label) #绘制x轴标签
plt.ylabel(y_label) #绘制y轴标签
#层次聚类的热图和聚类图
sns.clustermap(df,method ='ward',metric='euclidean')
plt.show()
评价方法
关于层次聚类的评价问题。在官方文档中有一个API用来根据计算层次聚类根据结果计算其对应的共表性相关系数(Cophenetic Correlation Coefficient)。共表相关系数越大,表明效果越好。
下面是计算共表相关系数的API
Y = scipy.spatial.distance.pdist((X,'cityblock'); #计算距离列表
Z = hierarchy.linkage(Y,'average'); #进行层次聚类
cluster.hierarchy.cophenet(Z,Y) #计算共表相关系数
参考:https://people.revoledu.com/kardi/tutorial/Clustering/Cophenetic.htm