深入浅出介绍聚类分析

Python029

深入浅出介绍聚类分析,第1张

聚类分析是生信分析中常用的工具,在转录组分析中经常用到。聚类分析将表达模式相似的基因聚类在一起,以基因集的形式进行后续分析,今天我给大家介绍其相关原理。

聚类方法有很多,常用的有以下几个:

下图的例子展示的是,差异表达基因集的聚类热图。

多是基于R语言heatmap.2函数绘制(gplots程序包),该函数默认使用的聚类方法是计算欧式距离(Euclidean Distance)进行层次聚类(Hierarchical Cluster)。

这个图的是什么意思呢?我们来解释一下。

首先,我们先明确下什么是欧式距离(Euclidean Distance):

欧式距离,也称欧几里得距离,是衡量多维空间的两个点之间的绝对距离,

(1)二维平面,两点a(x1,y1),b(x2,y2) 欧式距离的计算公式为:

(2)三维空间,欧式距离的计算公式为:

(3)n维空间,欧式距离的计算公式为:

那么,体现在基因表达量的矩阵上,则如下:

(1) 首行为样本名;

(2) 首列为基因名;

(3) 数字则为基因在相应样本中的表达量(一般使用标准化后的表达量矩阵)

Gene1与Gene2的欧式距离为:

Gene1与Gene3的欧式距离为:

Gene1与Gene4的欧式距离为:

计算出所有基因两两之间的欧式距离之后,就可以进行聚类啦:

Cluster之间的聚类,则有3种方法:

R语言中hclust函数的默认方法为最长距离法(complete-linkage)。

以上的聚类过程即称之为 层级聚类

层级聚类一般伴随着 系统聚类图 ,系统聚类图分支的长短也体现Cluster形成的早晚,分支越短,形成的越早,基因表达模式也越相近。

聚类分析将基因划分为不同的基因集合,用于反映不同实验条件下样品差异表达基因的变化模式。

功能相关的基因在相同条件下通常具有相似的表达模式,例如被共同的转录因子调控的基因,或其产物构成同一个蛋白复合体的基因,或参与相同生物学过程的基因。对这些基因集进行分析往往可以获得比单基因分析更为可靠的结果。

聚类分析有两种主要计算方法,分别是凝聚层次聚类(Agglomerative hierarchical method)和K均值聚类(K-Means)。 一、层次聚类 层次聚类又称为系统聚类,首先要定义样本之间的距离关系,距离较近的归为一类,较远的则属于不同的类。可用于定义“距离”的统计量包括了欧氏距离 (euclidean)、马氏距离(manhattan)、 两项距离(binary)、明氏距离(minkowski)。还包括相关系数和夹角余弦。 层次聚类首先将每个样本单独作为一类,然后将不同类之间距离最近的进行合并,合并后重新计算类间距离。这个过程一直持续到将所有样本归为一类为止。在计算类间距离时则有六种不同的方法,分别是最短距离法、最长距离法、类平均法、重心法、中间距离法、离差平方和法。 下面我们用iris数据集来进行聚类分析,在R语言中所用到的函数为hclust。首先提取iris数据中的4个数值变量,然后计算其欧氏距离矩阵。然后将矩阵绘制热图,从图中可以看到颜色越深表示样本间距离越近,大致上可以区分出三到四个区块,其样本之间比较接近。 data=iris[,-5] dist.e=dist(data,method='euclidean') heatmap(as.matrix(dist.e),labRow = F, labCol = F) X 然后使用hclust函数建立聚类模型,结果存在model1变量中,其中ward参数是将类间距离计算方法设置为离差平方和法。使用plot(model1)可以绘制出聚类树图。如果我们希望将类别设为3类,可以使用cutree函数提取每个样本所属的类别。 model1=hclust(dist.e,method='ward') result=cutree(model1,k=3) 为了显示聚类的效果,我们可以结合多维标度和聚类的结果。先将数据用MDS进行降维,然后以不同的的形状表示原本的分类,用不同的颜色来表示聚类的结果。可以看到setose品种聚类很成功,但有一些virginica品种的花被错误和virginica品种聚类到一起。

关于谱能量,有这样一种解释,你可以试着去算一算信号可以分成能量信号与功率信号,非周期能量信号具有能量谱密度,是傅立叶变换的平方,功率信号具有功率谱密度,其与自相关函数是一对傅立叶变换对,等于傅立叶变换的平方/区间长度。不能混淆。能量信号是没有功率谱的。胡广书老师的书上找到这么一段话,“随机信号在时间上是无限的,在样本上也是无穷多,因此随机信号的能量是无限的,它应是功率信号。功率信号不满足付里叶变换的绝对可积的条件,因此其付里叶变换是不存在的。如确定性的正弦函数的付里叶变换是不存在,只有引入了冲激函数才求得其付里叶变换。因此,对随机信号的频谱分析,不再简单的是频谱,而是功率谱。”对于确定性信号而言,里面存在能量信号,是没有功率谱密度的,也存在功率信号,是有功率谱密度的。所以信号的频谱与是否是确定性信号没有必然联系。以下论点来源于研学论坛:频谱是信号的傅立叶变换。它描述了信号在各个频率上的分布大小。频谱的平方(当能量有限,平均功率为0时称为能量谱)描述了信号能量在各个频率上的分布大小。计算过程中,都是通过样本数据的快速傅立叶变换来计算。但不同的是,信号的频谱是复数,包含幅频响应和相频响应,重复计算时的结果基本相同。而随机信号的功率谱也可以对数据进行FFT,但必须计算模值的平方,因为功率谱是实数。而且换一组样本后,计算的结果略有不同,因为随机信号的样本取值不同。要得到真实的功率谱必须进行多次平均,次数越多越好。根据parseval定理,信号傅氏变换模平方被定义为能量谱,即单位频率范围内包含的信号能量。自然,能量跟功率有一个时间平均的关系,所以,能量谱密度在时间上平均就得到了功率谱。matlab实现经典功率谱估计fft做出来是频谱,psd做出来是功率谱;功率谱丢失了频谱的相位信息;频谱不同的信号其功率谱是可能相同的;功率谱是幅度取模后平方,结果是个实数matlab中自功率谱密度直接用psd函数就可以求,按照matlab的说法,psd能实现Welch法估计,即相当于用改进的平均周期图法来求取随机信号的功率谱密度估计。psd求出的结果应该更光滑吧。1、直接法:直接法又称周期图法,它是把随机序列x(n)的N个观测数据视为一能量有限的序列,直接计算x(n)的离散傅立叶变换,得X(k),然后再取其幅值的平方,并除以N,作为序列x(n)真实功率谱的估计。Matlab代码示例:clearFs=1000%采样频率n=0:1/Fs:1%产生含有噪声的序列xn=cos(2*pi*40*n)+3*cos(2*pi*100*n)+randn(size(n))window=boxcar(length(xn))%矩形窗nfft=1024[Pxx,f]=periodogram(xn,window,nfft,Fs)%直接法plot(f,10*log10(Pxx))2、间接法:间接法先由序列x(n)估计出自相关函数R(n),然后对R(n)进行傅立叶变换,便得到x(n)的功率谱估计。Matlab代码示例:clearFs=1000%采样频率n=0:1/Fs:1%产生含有噪声的序列xn=cos(2*pi*40*n)+3*cos(2*pi*100*n)+randn(size(n))nfft=1024cxn=xcorr(xn,'unbiased')%计算序列的自相关函数CXk=fft(cxn,nfft)Pxx=abs(CXk)index=0:round(nfft/2-1)k=index*Fs/nfftplot_Pxx=10*log10(Pxx(index+1))plot(k,plot_Pxx)3、改进的直接法:对于直接法的功率谱估计,当数据长度N太大时,谱曲线起伏加剧,若N太小,谱的分辨率又不好,因此需要改进。3.1、Bartlett法Bartlett平均周期图的方法是将N点的有限长序列x(n)分段求周期图再平均。Matlab代码示例:clear;Fs=1000n=0:1/Fs:1xn=cos(2*pi*40*n)+3*cos(2*pi*100*n)+randn(size(n))nfft=1024window=boxcar(length(n))%矩形窗noverlap=0%数据无重叠p=0.9%置信概率[Pxx,Pxxc]=psd(xn,nfft,Fs,window,noverlap,p)index=0:round(nfft/2-1)k=index*Fs/nfftplot_Pxx=10*log10(Pxx(index+1))plot_Pxxc=10*log10(Pxxc(index+1))figure(1)plot(k,plot_Pxx)pausefigure(2)plot(k,[plot_Pxx plot_Pxx-plot_Pxxc plot_Pxx+plot_Pxxc])3.2、Welch法Welch法对Bartlett法进行了两方面的修正,一是选择适当的窗函数w(n),并再周期图计算前直接加进去,加窗的优点是无论什么样的窗函数均可使谱估计非负。二是在分段时,可使各段之间有重叠,这样会使方差减小。Matlab代码示例:clearFs=1000n=0:1/Fs:1xn=cos(2*pi*40*n)+3*cos(2*pi*100*n)+randn(size(n))nfft=1024window=boxcar(100)%矩形窗window1=hamming(100)%海明窗window2=blackman(100)%blackman窗noverlap=20%数据无重叠range='half'%频率间隔为[0 Fs/2],只计算一半的频率[Pxx,f]=pwelch(xn,window,noverlap,nfft,Fs,range)[Pxx1,f]=pwelch(xn,window1,noverlap,nfft,Fs,range)[Pxx2,f]=pwelch(xn,window2,noverlap,nfft,Fs,range)plot_Pxx=10*log10(Pxx)plot_Pxx1=10*log10(Pxx1)plot_Pxx2=10*log10(Pxx2)figure(1)plot(f,plot_Pxx)pausefigure(2)plot(f,plot_Pxx1)pausefigure(3)plot(f,plot_Pxx2)