📜  机器学习中的亲和传播 |查找集群的数量

📅  最后修改于: 2022-05-13 01:54:22.812000             🧑  作者: Mango

机器学习中的亲和传播 |查找集群的数量

Affinity Propagation 通过在数据点之间发送消息直到收敛来创建集群。与 k-means 或 k-medoids 等聚类算法不同,亲和力传播不需要在运行算法之前确定或估计聚类的数量,为此,两个重要的参数是偏好,它控制有多少样本(或原型),以及抑制消息的责任和可用性的阻尼因子,以避免在更新这些消息时出现数值振荡。

使用少量示例描述数据集,“示例”是代表集群的输入集的成员。对之间发送的消息表示一个样本是否适合作为另一个样本的样本,该样本会根据其他对的值进行更新。这种更新迭代地发生直到收敛,此时选择了最终的样本,因此我们获得了最终的聚类。亲和传播算法:

输入:给定一个数据集 D = {d1, d2, d3, .....dn}
s是一个 NxN 矩阵,使得s(i, j)表示 d i和 d j之间的相似性。两个数据点的负平方距离用作点xixj的 s ie , s(i, j)= -||x i -x j || 2 .
s 即s(i, i)的对角线特别重要,因为它代表了输入偏好,这意味着特定输入成为样本的可能性有多大。当它为所有输入设置为相同的值时,它控制算法产生多少类。接近最小可能相似度的值产生较少的类,而接近或大于最大可能相似度的值产生许多类。它通常被初始化为所有输入对的中值相似度。

该算法通过交替两个消息传递步骤来更新两个矩阵:

  • “责任”矩阵 R 的值 r(i, k) 量化了 x k作为 x i的示例相对于 x i的其他候选示例的适合程度。
  • “可用性”矩阵 A 包含值 a(i, k),表示 x i选择 x k作为其样本有多“合适”,同时考虑到其他点对 x k作为样本的偏好。

两个矩阵都初始化为全零。然后该算法迭代地执行以下更新:

  • 一、责任更新四处发送
  • 然后,可用性更新每

执行迭代直到集群边界在多次迭代中保持不变,或者在某个预定数量的迭代之后。样本是从最终矩阵中提取的,它们的“责任+可用性”对自己是积极的(即(r(i, i) + a(i, i)) > 0 )。
下面是使用 scikit-learn 库的 Affinity Propagation 聚类的Python实现:

from sklearn.cluster import AffinityPropagation
from sklearn import metrics
from sklearn.datasets.samples_generator import make_blobs
  
# Generate sample data
centers = [[1, 1], [-1, -1], [1, -1], [-1, -1]]
X, labels_true = make_blobs(n_samples = 400, 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)
# Plot result
import matplotlib.pyplot as plt
from itertools import cycle
  
plt.close('all')
plt.figure(1)
plt.clf()
  
colors = cycle('bgrcmykbgrcmykbgrcmykbgrcmyk')
  
for k, col in zip(range(n_clusters_), colors):
    class_members = labels == k
    cluster_center = X[cluster_centers_indices[k]]
    plt.plot(X[class_members, 0], X[class_members, 1], col + '.')
    plt.plot(cluster_center[0], cluster_center[1], 'o',
             markerfacecolor = col, markeredgecolor ='k',
             markersize = 14)
  
    for x in X[class_members]:
        plt.plot([cluster_center[0], x[0]], 
                 [cluster_center[1], x[1]], col)
  
plt.title('Estimated number of clusters: % d' % n_clusters_)
plt.show()

输出: