生信分析_層次聚類
讀取數(shù)據(jù)后,我們就可以進(jìn)行層次聚類圖的繪制了,首先進(jìn)入scipy參考文檔頁(yè)面,然后找到聚類包Clustering package (scipy.cluster)->層次聚類scipy.cluster.hierarchy,在當(dāng)前頁(yè)面下,就可以看到所有層次聚類相關(guān)的函數(shù)了,我們找到可以畫(huà)圖的函數(shù)dendrogram,進(jìn)入該函數(shù)的文檔頁(yè)面,發(fā)現(xiàn)該函數(shù)需要傳入的第一個(gè)參數(shù)是linkage矩陣,這個(gè)矩陣需要函數(shù)linkage,進(jìn)入該函數(shù)的文檔頁(yè)面我們看到linkage的說(shuō)明文檔上面的函數(shù)scipy.cluster.hierarchy.linkage(y, method='single', metric='euclidean', optimal_ordering=False),傳入第一個(gè)參數(shù)是需要進(jìn)行層次聚類的數(shù)據(jù),這里即可用使用開(kāi)始讀取的數(shù)據(jù)變量df,第二個(gè)參數(shù)代表層次聚類選用的方法
import pandas as pd
import seaborn as sns #用于話熱圖的工具包
from scipy.cluster import hierarchy #用于進(jìn)行層次聚類,話層次聚類圖的工具包
from scipy import cluster
import matplotlib.pyplot as plt
from sklearn import decomposition as skldec #用于主成分分析降維的包
df = pd.read_excel("test.xlsx",index_col=0)
#開(kāi)始畫(huà)層次聚類樹(shù)狀圖
Z = hierarchy.linkage(df, method ='ward',metric='euclidean')
hierarchy.dendrogram(Z,labels = df.index)
第三個(gè)參數(shù)代表距離計(jì)算的方法,即上面方法中的dist()
函數(shù)具體的計(jì)算方式,具體方式可以見(jiàn)這個(gè)頁(yè)面。
然后這里我隨便選擇兩個(gè),然后將返回的結(jié)果Z傳入dendrogram
函數(shù),
關(guān)鍵是這個(gè)函數(shù)可以自己定義距離。這就為我們進(jìn)行層次聚類提供了很好的一個(gè)接口,因?yàn)樵谔囟ㄈ蝿?wù)下,scipy函數(shù)里面給出的距離不一定能夠滿足我們自己的實(shí)際需求。為了能夠自定義距離度量,我進(jìn)行了一些測(cè)試,最后得出自定義距離度量函數(shù)需要注意以下幾個(gè)方面:
函數(shù)傳入兩個(gè)參數(shù):比如,自定義函數(shù)為:def selfDisFuc(a,b):
傳入?yún)?shù)類型是<class 'numpy.ndarray'>
傳入?yún)?shù)的維度必須一樣
返回值必須是一個(gè)代表距離的數(shù)
我這處理自定義函數(shù)時(shí),因?yàn)樘幚淼臄?shù)據(jù)維度不一樣,最后只好找到最大維度的數(shù)據(jù),然后將不一樣的所有
數(shù)據(jù)后面補(bǔ)上-1(我的數(shù)據(jù)中不會(huì)出現(xiàn)的一個(gè)數(shù)),然后再處理。
安照上面的三個(gè)規(guī)則,就能寫(xiě)出自己需要的距離衡量函數(shù)了。
#在某個(gè)高度進(jìn)行剪切
label = cluster.hierarchy.cut_tree(Z,height=0.8)
label = label.reshape(label.size,)
#根據(jù)兩個(gè)最大的主成分進(jìn)行繪圖
pca = skldec.PCA(n_components = 0.95) #選擇方差95%的占比
pca.fit(df) #主成分析時(shí)每一行是一個(gè)輸入數(shù)據(jù)
result = pca.transform(df) #計(jì)算結(jié)果
plt.figure() #新建一張圖進(jìn)行繪制
plt.scatter(result[:, 0], result[:, 1], c=label, edgecolor='k') #繪制兩個(gè)主成分組成坐標(biāo)的散點(diǎn)圖
for i in range(result[:,0].size):
plt.text(result[i,0],result[i,1],df.index[i]) #在每個(gè)點(diǎn)邊上繪制數(shù)據(jù)名稱
x_label = 'PC1(%s%%)' % round((pca.explained_variance_ratio_[0]*100.0),2) #x軸標(biāo)簽字符串
y_label = 'PC1(%s%%)' % round((pca.explained_variance_ratio_[1]*100.0),2) #y軸標(biāo)簽字符串
plt.xlabel(x_label) #繪制x軸標(biāo)簽
plt.ylabel(y_label) #繪制y軸標(biāo)簽
#層次聚類的熱圖和聚類圖
sns.clustermap(df,method ='ward',metric='euclidean')
plt.show()
評(píng)價(jià)方法
關(guān)于層次聚類的評(píng)價(jià)問(wèn)題。在官方文檔中有一個(gè)API用來(lái)根據(jù)計(jì)算層次聚類根據(jù)結(jié)果計(jì)算其對(duì)應(yīng)的共表性相關(guān)系數(shù)(Cophenetic Correlation Coefficient)。共表相關(guān)系數(shù)越大,表明效果越好。
下面是計(jì)算共表相關(guān)系數(shù)的API
Y = scipy.spatial.distance.pdist((X,'cityblock'); #計(jì)算距離列表
Z = hierarchy.linkage(Y,'average'); #進(jìn)行層次聚類
cluster.hierarchy.cophenet(Z,Y) #計(jì)算共表相關(guān)系數(shù)
參考:https://people.revoledu.com/kardi/tutorial/Clustering/Cophenetic.htm