python实现层次聚类
昨晚到现在一直在研究层次聚类的问题。scipy包含了一些层次聚类的包和函数,但是它的文档实在太坑爹了,http://docs.scipy.org/doc/scipy/reference/cluster.hierarchy.html 这个就是scipy实现层次聚类的包。我感觉还没有完全弄明白它的意思。http://math.stanford.edu/~muellner/fastcluster.html fastcluster 则好多了,它提供的东西没有scipy多,但是它做层次聚类已经够了,而且它的速度也比scipy快,还和scipy是兼容的。http://www2.warwick.ac.uk/fac/sci/sbdtc/people/students/2010/jason_piper/code/ 这篇文章提到的例子就是fastcluster的使用。
Amazon.cn Widgets
http://home.dei.polimi.it/matteucc/Clustering/tutorial_html/hierarchical.html 这篇文章是很好的层次聚类例子。文章中的
BA FI MI NA RM TO BA 0 662 877 255 412 996 FI 662 0 295 468 268 400 MI 877 295 0 754 564 138 NA 255 468 754 0 219 869 RM 412 268 564 219 0 669 TO 996 400 138 869 669 0这是一个距离矩阵。不管是scipy还是fastcluster,都有一个计算距离矩阵的步骤(也可以不用)。距离矩阵是冗余的,因为它是对称的。scipy里面的文档好多的关于数学上的英文,让我都搞糊涂了。distance = spatial.distance.pdist(data),这段代码里,data是一个矩阵,但不是距离矩阵,而是如http://www.shahuwang.com/?p=952 这篇文章中用到的数据形式,而最后算出来的distance只是一个数组,并不是矩阵,而且是一维数组,这是为什么呢?仔细看上面的那个矩阵,就知道我们只需要记录对角线上或者下面的一部分就可以了。废话不说,来看最简单的一个层次聚类实现(我现在主要将scipy的,fastcluster的使用几乎一样):
12from
scipy.cluster.hierarchy
import
fclusterdata
fclusterdata(matData,t
=
0.99
,criterion
=
'inconsistent'
,metric
=
'euclidean'
,method
=
'average'
,R
=
None
)
#这个不需要计算linkage就能直接出结果了
这里用到的matData来自于:http://www.shahuwang.com/?p=952 用到的数据,是矩阵形式的。输出的结果如下:
array([15, 19, 20, 26, 23, 10, 26, 23, 18, 21, 20, 22, 10, 20, 1, 18, 11, 8, 4, 18, 21, 29, 25, 17, 18, 20, 24, 23, 3, 19, 12, 13, 15, 9, 18, 25, 16, 28, 5, 17, 25, 17, 1, 15, 7, 4, 14, 6, 20, 2, 4, 3, 9, 5, 2, 23, 1, 9, 25, 15, 23, 27, 16, 11, 22, 20, 12])结果的意思,就是说我的矩阵的第一个数据现在被分到了第15个类中,后面的也都是这个意思,自己再整理一下,就能输出美观直观的结果了。下面主要来讲一下fclusterdata里面的参数的意思:
matData,这是要聚类的数据,t是一个阈值,小于1大于0,你可以根据输出结果来设置这个阈值。criterion,是一个标准,它主要是确定形成最后结果(如上面的那个array)需要满足什么条件,这个主要和 t 这个阈值进行合作。
http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.fcluster.html#scipy.cluster.hierarchy.fcluster 这里有比较详细的说明,不过貌似我这里就inconsistent能有比较好的结果。metric则是设置两个点之间的距离用什么方式计算,我这里的是欧几里得距离,详细可看维基百科的内容:http://en.wikipedia.org/wiki/Hierarchical_clustering method则是计算两个簇直接满足什么条件就能合并。http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy.cluster.hierarchy.linkage 这里对method有详细的叙述。fclusterdata还有其他几个参数,我还没有搞明白,不过它们不提供的话,会有默认的。
12345678from
scipy.cluster.hierarchy
import
linkage ,fcluster,fclusterdata
import
pandas as pd
data
=
pd.read_csv(
'/home/rickey/文档/学习/数据挖掘与数据仓库/数据挖掘作业/三围数据'
,sep
=
't'
,index_col
=
0
)
matData
=
data.as_matrix()
distance
=
spatial.distance.pdist(matData)
linkresult
=
linkage(distance,method
=
'average'
,metric
=
'euclidean'
)
fcluster(linkresult,t
=
0.99
,criterion
=
'inconsistent'
,depth
=
2
,R
=
None
,monocrit
=
None
)
#这个需要先计算linkage,再出结果
dendrogram(linkresult,get_leaves
=
False
,show_leaf_counts
=
False
)
#这个可以绘制出树形图
这是更复杂一些的实现形式,主要有四个函数要注意,分别是pdist,linkage,fcluster,dendrogram。
这段代码用的数据和前面那段是一样的,结果也是一样的。distance是一个距离数组(距离矩阵的一边角),之前已经说明了pdist的作用了。linkage返回的是一个4×(n-1)的矩阵。比如我的数据是67个,返回的则是一个4×66的矩阵。这个矩阵的意思,scipy文档上用的是这段话:“A 4 by matrix Z is returned. At the -th iteration, clusters with indices Z[i, 0] and Z[i, 1] are combined to form cluster . A cluster with an index less than corresponds to one of the original observations. The distance between clusters Z[i, 0] and Z[i, 1] is given by Z[i, 2]. The fourth value Z[i, 3] represents the number of original observations in the newly formed cluster.”
英语不济,不是很看得明白。大概是说Z[i,0],Z[i,1]是组成n+i簇的之类的吧。
http://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html#scipy.cluster.hierarchy.linkage linkage的用法还是要仔细看文档才行。
fcluster这个函数,则是把linkage算出的结果,形成一个平面数组,形成最后的聚类结果呈现出来。里面的参数和fclusterdata里面的意思是一样的。
fcluster的这段代码和fclusterdata的代码相比,多了一些,不过,好处就是能设置更多的参数。
dendrogram的参数设置非常多,没有完全搞明白,不过它会输出一个字典,和一幅图。字典里面有四个key,而图则是树形图,如下:
不过,我觉得这个图的用途不是很大,数据量一多,就什么都看不到了。
scipy里面关于层次聚类的函数还有不少,我也没有搞懂,这里就不多说了。
python实现层次聚类
最新推荐文章于 2024-08-18 11:24:59 发布