谱聚类和AP聚类是基于图的两种聚类,在这里我写介绍一下AP聚类,下一篇文章介绍谱聚类。
Affinity Propagation Clustering(简称AP算法)是2007提出的,当时发表在Science上《single-exemplar-based》。特别适合高维、多类数据快速聚类,相比传统的聚类算法,该算法算是比较新的,从聚类性能和效率方面都有大幅度的提升。
将全部样本看作网络的节点,然后通过网络中各条边的消息传递计算出各样本的聚类中心。聚类过程中,共有两种消息在各节点间传递,分别是吸引度( responsibility)和归属度(availability) 。AP算法通过迭代过程不断更新每一个点的吸引度和归属度值,直到产生m个高质量的Exemplar(类似于质心),同时将其余的数据点分配到相应的聚类中。
Exemplar:指的是聚类中心,K-Means中的质心,AP算法不需要事先指定聚类数目,相反它将所有的数据点都作为潜在的聚类中心。
Similarity(相似度):数据点i和点j的相似度记为s(i, j),是指点j作为点i的聚类中心的相似度。一般使用欧氏距离来计算,一般点与点的相似度值全部取为负值;因此,相似度值越大说明点与点的距离越近,便于后面的比较计算。
Preference:数据点i的参考度称为p(i)或s(i,i),是指点i作为聚类中心的参考度,以S矩阵的对角线上的数值s (k, k)作为k点能否成为聚类中心的评判标准,这意味着该值越大,这个点成为聚类中心的可能性也就越大。一般取s相似度值的中值(Scikit-learn中默认为中位数)。聚类的数量受到参考度p的影响,如果认为每个数据点都有可能作为聚类中心,那么p就应取相同的值。如果取输入的相似度的均值作为p的值,得到聚类数量是中等的。如果取最小值,得到类数较少的聚类。
吸引度Responsibility:r(i,k)用来描述点k适合作为数据点i的聚类中心的程度。
归属度Availability:a(i,k)用来描述点i选择点k作为其聚类中心的适合程度。
Damping factor(阻尼系数):主要是起收敛作用的。
在实际计算应用中,最重要的两个参数(也是需要手动指定)是Preference和Damping factor。前者定了聚类数量的多少,值越大聚类数量越多;后者控制算法收敛效果。
步骤1:算法初始,将吸引度矩阵R和归属度矩阵初始化为0矩阵;
步骤2:更新吸引度矩阵
步骤3:更新归属度矩阵
步骤4:根据衰减系数 对两个公式进行衰减
重复步骤2,3,4直至矩阵稳定或者达到最大迭代次数,算法结束。
最终取a+r最大的k作为聚类中心。
1. AP聚类应用中需要手动指定Preference和Damping factor,这其实是原有的聚类“数量”控制的变体。
2.算法较慢。由于AP算法复杂度较高,运行时间相对K-Means长,这会使得尤其在海量数据下运行时耗费的时间很多。
参数设置介绍:
damping : 衰减系数,默认为 0.5
convergence_iter : 迭代次后聚类中心没有变化,算法结束,默认为15.
max_iter : 最大迭代次数,默认200.
copy : 是否在元数据上进行计算,默认True,在复制后的数据上进行计算。
preference : S的对角线上的值
affinity :S矩阵(相似度),默认为euclidean(欧氏距离)矩阵,即对传入的X计算距离矩阵,也可以设置为precomputed,那么X就作为相似度矩阵。
AP应用实例链接
Demo of affinity propagation clustering algorithmscikit-learn.org
训练完AP聚类之后可以获得的结果有
cluster_centers_indices_ : 聚类中心的位置
cluster_centers_ : 聚类中心
labels_ : 类标签
affinity_matrix_ : 最后输出的A矩阵
n_iter_ :迭代次数
到这里AP聚类算法介绍就结束啦,,,
因为AP只是一种聚类算法,所以在机器学习里是non domain-specific的,文章中给出了四个例子,对生物基因的聚类,对人脸的聚类,对文章主题句的提取(这个比较有意思,作者把自己发表的这篇文章提出四句话),和对城市之间航运网络的聚类。
在python的sklearn包里带了AP算法,应用起来也是很方便的:
from sklearn.cluster import AffinityPropagation
from sklearn import metrics
from sklearn.datasets.samples_generator import make_blobs
import pylab as pl
from itertools import cycle
# Generate sample data
centers = [[1, 1], [-1, -1], [1, -1]]
X, labels_true = make_blobs(n_samples=300, centers=centers, cluster_std=0.5,
random_state=0)
# Compute Affinity Propagation
af = AffinityPropagation(preference=-50).fit(X)
cluster_centers_indices = af.cluster_centers_indices_
labels = af.labels_
n_clusters_ = len(cluster_centers_indices)
print('Estimated number of clusters: %d' % n_clusters_)
print("Homogeneity: %0.3f" % metrics.homogeneity_score(labels_true, labels))
print("Completeness: %0.3f" % metrics.completeness_score(labels_true, labels))
print("V-measure: %0.3f" % metrics.v_measure_score(labels_true, labels))
print("Adjusted Rand Index: %0.3f"
% metrics.adjusted_rand_score(labels_true, labels))
print("Adjusted Mutual Information: %0.3f"
% metrics.adjusted_mutual_info_score(labels_true, labels))
print("Silhouette Coefficient: %0.3f"
% metrics.silhouette_score(X, labels, metric='sqeuclidean'))
# Plot result
pl.close('all')
pl.figure(1)
pl.clf()
colors = cycle('bgrcmykbgrcmykbgrcmykbgrcmyk')
pl.title('Estimated number of clusters: %d' % n_clusters_)
for k, col in zip(range(n_clusters_), colors):
class_members = labels == k
cluster_center = X[cluster_centers_indices[k]]
pl.plot(X[class_members, 0], X[class_members, 1], col + '.')
pl.plot(cluster_center[0], cluster_center[1], 'o', markerfacecolor=col,
markeredgecolor='k', markersize=14)
for x in X[class_members]:
pl.plot([cluster_center[0], x[0]], [cluster_center[1], x[1]], col)