Python机器学习——Agglomerative层次聚类,,层次聚类(hiera


层次聚类(hierarchical clustering)可在不同层次上对数据集进行划分,形成树状的聚类结构。AggregativeClustering是一种常用的层次聚类算法。
??其原理是:最初将每个对象看成一个簇,然后将这些簇根据某种规则被一步步合并,就这样不断合并直到达到预设的簇类个数。这里的关键在于:如何计算聚类簇之间的距离?
??由于每个簇就是一个集合,因此需要给出集合之间的距离。给定聚类簇Ci,CjCi,Cj,有如下三种距离:

最小距离:dmin(Ci,Cj)=minx?i∈Ci,x?j∈Cjdistance(x?i,x?j)dmin(Ci,Cj)=minx→i∈Ci,x→j∈Cjdistance(x→i,x→j)它是两个簇的样本对之间距离的最小值。最大距离:dmax(Ci,Cj)=maxx?i∈Ci,x?j∈Cjdistance(x?i,x?j)dmax(Ci,Cj)=maxx→i∈Ci,x→j∈Cjdistance(x→i,x→j)它是两个簇的样本对之间距离的最大值。平均距离:davg(Ci,Cj)=1|Ci||Cj|∑x?i∈Ci∑x?j∈Cjdistance(x?i,x?j)davg(Ci,Cj)=1|Ci||Cj|∑x→i∈Ci∑x→j∈Cjdistance(x→i,x→j)它是两个簇的样本对之间距离的平均值。

??当该算法的聚类簇采用dmindmin时,称为单链接single-linkage算法,当该算法的聚类簇采用dmaxdmax时,称为单链接complete-linkage算法,当该算法的聚类簇采用davgdavg时,称为单链接average-linkage算法。

??下面给出算法:

输入:
数据集D=D={x?1,x?2,...,x?Nx→1,x→2,...,x→N}聚类簇距离度量函数聚类簇数量KK输出:簇划分C=C={C1,C2,...,CKC1,C2,...,CK}

算法步骤如下:

初始化:将每个样本都作为一个簇Ci=[x?i],i=1,2,...,NCi=[x→i],i=1,2,...,N迭代:终止条件为聚类簇的数量为K。迭代过程如下:
计算聚类簇之间的距离,找出距离最近的两个簇,将这两个簇合并。

Python实战


??AgglomerativeClustering是scikit-learn提供的层级聚类算法模型,其原型为:

class sklearn.cluster.AgglomerativeClustering(n_clusters=2, affinity=’euclidean’, memory=None, connectivity=None, compute_full_tree=’auto’, linkage=’ward’, pooling_func=<function mean>)
1

参数

n_clusters:一个整数,指定分类簇的数量connectivity:一个数组或者可调用对象或者None,用于指定连接矩阵affinity:一个字符串或者可调用对象,用于计算距离。可以为:’euclidean’,’l1’,’l2’,’mantattan’,’cosine’,’precomputed’,如果linkage=’ward’,则affinity必须为’euclidean’memory:用于缓存输出的结果,默认为不缓存n_components:在 v-0.18中移除compute_full_tree:通常当训练了n_clusters后,训练过程就会停止,但是如果compute_full_tree=True,则会继续训练从而生成一颗完整的树linkage:一个字符串,用于指定链接算法
‘ward’:单链接single-linkage,采用dmindmin‘complete’:全链接complete-linkage算法,采用dmaxdmax‘average’:均连接average-linkage算法,采用davgdavgpooling_func:一个可调用对象,它的输入是一组特征的值,输出是一个数

属性

labels:每个样本的簇标记n_leaves_:分层树的叶节点数量n_components:连接图中连通分量的估计值children:一个数组,给出了每个非节点数量

方法

fit(X[,y]):训练样本fit_predict(X[,y]):训练模型并预测每个样本的簇标记
from sklearn import clusterfrom sklearn.metrics import adjusted_rand_scoreimport numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets.samples_generator import make_blobs"""    产生数据"""def create_data(centers,num=100,std=0.7):    X,labels_true = make_blobs(n_samples=num,centers=centers, cluster_std=std)    return X,labels_true"""    数据作图"""def plot_data(*data):    X,labels_true=data    labels=np.unique(labels_true)    fig=plt.figure()    ax=fig.add_subplot(1,1,1)    colors=‘rgbycm‘    for i,label in enumerate(labels):        position=labels_true==label        ax.scatter(X[position,0],X[position,1],label="cluster %d"%label),        color=colors[i%len(colors)]    ax.legend(loc="best",framealpha=0.5)    ax.set_xlabel("X[0]")    ax.set_ylabel("Y[1]")    ax.set_title("data")    plt.show()
123456789101112131415161718192021222324252627282930313233

技术分享图片

这里写代码片"""    测试函数"""  def test_AgglomerativeClustering(*data):    X,labels_true=data    clst=cluster.AgglomerativeClustering()    predicted_labels=clst.fit_predict(X)    print("ARI:%s"% adjusted_rand_score(labels_true, predicted_labels))"""    考察簇的数量对于聚类效果的影响"""def test_AgglomerativeClustering_nclusters(*data):    X,labels_true=data    nums=range(1,50)    ARIS=[]    for num in nums:        clst=cluster.AgglomerativeClustering(n_clusters=num)        predicted_lables=clst.fit_predict(X)        ARIS.append(adjusted_rand_score(labels_true, predicted_lables))     fig=plt.figure()    ax=fig.add_subplot(1,1,1)    ax.plot(nums,ARIS,marker="+")    ax.set_xlabel("n_clusters")    ax.set_ylabel("ARI")    fig.suptitle("AgglomerativeClustering")    plt.show()   """    考察链接方式对聚类结果的影响"""   def test_agglomerativeClustering_linkage(*data):    X,labels_true=data    nums=range(1,50)    fig=plt.figure()    ax=fig.add_subplot(1,1,1)    linkages=[‘ward‘,‘complete‘,‘average‘]    markers="+o*"    for i,linkage in enumerate(linkages):         ARIs=[]        for num in nums:            clst=cluster.AgglomerativeClustering(n_clusters=num,linkage=linkage)            predicted_labels=clst.fit_predict(X)            ARIs.append(adjusted_rand_score(labels_true, predicted_labels))        ax.plot(nums,ARIs,marker=markers[i],label="linkage:%s"%linkage)    ax.set_xlabel("n_clusters")    ax.set_ylabel("ARI")    ax.legend(loc="best")    fig.suptitle("AgglomerativeClustering")    plt.show()centers=[[1,1],[2,2],[1,2],[10,20]]X,labels_true=create_data(centers, 1000, 0.5)test_AgglomerativeClustering(X,labels_true)plot_data(X,labels_true)test_AgglomerativeClustering_nclusters(X,labels_true)test_agglomerativeClustering_linkage(X,labels_true)
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859

技术分享图片

可以看到当n_clusters=4时,ARI指数最大,因为确实是从四个中心点产生的四个簇。
12

技术分享图片

 可以看到,三种链接方式随分类簇的数量的总体趋势相差无几。但是单链接方式ward的峰值最大

Python机器学习——Agglomerative层次聚类

评论关闭