AP聚类

机器学习中一个很重要的方面就是聚类算法。聚类算法说白了就是给你一大堆点的坐标(维度可以是很高的),然后给你一个距离度量的准则(比如欧拉距离,马氏距离什么的),然后你要自动把相近的点放在一个集合里面,归为一类。

继续科普:一个比较传统的聚类算法就是k-Means聚类,算法很简单,哦,说起这件事,我刚刚在整理东西时就发现了一篇讲到k-Means的论文,里面又是一大堆看不懂的符号,我说你们真的有必要那么装逼么??

比如说下面这幅图,有这么多个点,我们强大的大脑可以瞬间分辨出这里有三个团簇,一般术语叫cluster。

但是K-Means算法是怎么实现的呢?

首先我们已经知道有三个类了,所以呢就随机的选三个点(上图最左),作为三个类的中心,也可以叫做代表点,之后呢把图中所有的点归于离他最近的那个点,认为这个点就是属于这一类(上图左二),显然这样分类是不行的,然后我们计算每个类的那些点的中心(或者称为重心),把每个类的代表点的位置移到这个类的重心处(上图右二),然后再把全图中所有点都归于他们最近的那个类代表点,这时有些点的归属就会发生变化,然后不断的这么迭代,知道所有点的归属都不再变化为止,我们就认为这个算法收敛了。

显然这个算法很简单,比较简陋,但是大部分情况下都很实用!!要说缺点的话,第一,我们必须先知道总共有多少个类,其次就是算法最后能否收敛和收敛的速度对开始随机挑的那几个点很敏感。

好吧,扯远了,我这篇博文不是为了讲K-Means的,想介绍的是近邻传播聚类算法。

近邻传播,英文是affinity propagation,它是一种半监督聚类算法。比起传统的像K-Means,它有很多别的算法所望尘莫及的优势,比如不需事先指定类的个数,对初值的选取不敏感,对距离矩阵的对称性没要求等。

AP聚类算法是将每个数据看成图中的一个节点,迭代的过程即是在图中通过传播信息来找到聚类集合。本文计算两个数据点的相似度采用距离的负数,也就是说距离越近,相似度越大。相似矩阵S中i到j的相似度就是刚刚所说的距离的负数。但是主对角线上的那些数表示的是某个点和自身的相似度,但是这里我们不能直接用0来表示。根据算法要求,主对角线上的值s(k,k)一般称为偏向参数,一般情况下对所有k,s(k,k)都相等,取非主对角线上的所有数的中位数。这个值很重要,他的大小与最后得到的类的数目有关,一般而言这个数越大,得到的类的数目就越多。

这里为什么要设定一个偏向参数而不直接用0来算呢,估计是因为AP聚类算法是要用图论的一些东西来理解的,它把所有的点都看成一个图中的节点,通过节点之间的信息传递来达到聚类的效果。具体比较复杂,形象一点说就是我告诉你我和这些人是死党,如果你认为你也是我死党的话,那你就加入我们这一堆人里面来吧!

有一些详细的原理上的东西就不说了,直接说计算过程吧。。聚类就是个不断迭代的过程,迭代的过程主要更新两个矩阵,代表(Responsibility)矩阵R =[r(i,k)]N×N和适选(Availabilities)矩阵A=[a(i,k)]N×N。 这两个矩阵才初始化为0,N是所有样本的数目。r(i,k)表示第k个样本适合作为第i个样本的类代表点的代表程度,a(i,k)表示第i个样本选择第k个样本作为类代表样本的适合程度。迭代更新公式如下:

每次更新后就可以确定当前样本i的代表样本(exemplar)点k,k就是使{a(i,k)+r(i,k)}取得最大值的那个k,如果i=k的话,那么说明样本i就是自己这个cluster的类代表点,如果不是,那么说明i属于k所属的那个cluster。

当然,迭代停止的条件就是所有的样本的所属都不在变化为止,或者迭代了n次都还没有变化(n的值可以自己取)。

说起来还有一种判断点属于属于哪一类的方法,就是找出所有决策矩阵主对角线元素{a(k,k)+r(k,k)}大于0的所有点,这些点全部都是类代表点,之后在决定其余的点属于这里面的一类。这两种方法的结果我没比较过诶,不知是不是一样的。

另外还有一点就是AP聚类算法迭代过程很容易产生震荡,所以一般每次迭代都加上一个阻尼系数λ

rnew(i,k) = λ*rold(i,k) + (1-λ)*r(i,k)

anew(i,k) = λ*aold(i,k) + (1-λ)*a(i,k)

下图是采用下面的API画出来的聚类结果:

AP聚类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
function idx = AP(S)
N = size(S,1);
A=zeros(N,N);
R=zeros(N,N); % Initialize messages
 
lam=0.9; % Set damping factor
 
same_time = -1;
for iter=1:10000
     % Compute responsibilities
     Rold=R;
     AS=A+S;
     [Y,I]=max(AS,[],2);
     for i=1:N
         AS(i,I(i))=-1000;
     end
     [Y2,I2]=max(AS,[],2);
     R=S-repmat(Y,[1,N]);
     for i=1:N
         R(i,I(i))=S(i,I(i))-Y2(i);
     end
     R=(1-lam)*R+lam*Rold; % Dampen responsibilities
     % Compute availabilities
     Aold=A;
     Rp=max(R,0);
     for k=1:N
         Rp(k,k)=R(k,k);
     end
     A=repmat(sum(Rp,1),[N,1])-Rp;
     dA=diag(A);
     A=min(A,0);
     for k=1:N
         A(k,k)=dA(k);
     end ;
     A=(1-lam)*A+lam*Aold; % Dampen availabilities
 
     if (same_time == -1)
         E=R+A;
         [tt idx_old] = max(E,[],2);
         same_time = 0;
     else
         E=R+A;
         [tt idx] = max(E,[],2);
 
         if (sum(abs(idx_old-idx)) == 0)
             same_time = same_time + 1;
             if (same_time == 10)
                 iter
                 break ;
             end
         end
         idx_old = idx;
end
end
 
E=R+A;
[tt idx] = max(E,[],2);
 
% figure;
% for i=unique(idx)'
%     ii=find(idx==i);
%     h=plot(x(ii),y(ii),'o');
%     hold on;
%     col=rand(1,3);
%     set(h,'Color',col,'MarkerFaceColor',col);
%     xi1=x(i)*ones(size(ii)); xi2=y(i)*ones(size(ii));
%     line([x(ii)',xi1]',[y(ii)',xi2]','Color',col);
% end;
### AP聚类算法简介 AP(Affinity Propagation)聚类算法是一种无监督学习方法,旨在通过消息传递机制来识别数据集中最具代表性的样本作为聚类中心[^1]。该算法的独特之处在于其无需预先指定聚类数量,并且所选的聚类中心一定是来自输入的数据点集合中的成员[^2]。 #### 消息传递过程 在AP算法中,存在两类核心消息:责任度(responsibility) r(i,k),以及可用度(availability) a(i,k)[^3]: - **责任度** \(r(i, k)\): 表达了节点\(i\)倾向于选择节点\(k\)成为自己的 exemplar 的程度; - **可用度** \(a(i, k)\): 反映了节点\(k\)适合作为其他多少个节点exemplar的程度;对于自连接情况(\(i=k\)),则反映了有多少其它节点愿意选取\(k\)为其exemplar。 这两个量共同决定了哪些点最终会被选定为exemplars——即各个簇的核心代表点。 ### Python实现示例 下面给出了一段简单的Python代码片段,展示了如何利用`sklearn.cluster.AffinityPropagation`库函数来进行AP聚类分析: ```python from sklearn.cluster import AffinityPropagation import numpy as np # 假设X是一个形状为[n_samples, n_features]的二维数组,其中包含了待聚类的数据点 X = np.array([[1, 2], [2, 3], [8, 7], [9, 8]]) 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_) ``` 此段代码首先导入必要的模块并定义了一个模拟的数据集`X`。接着创建了一个`AffinityPropagation`实例对象`af`并通过调用`.fit()`方法执行聚类操作。最后打印出了估计得到的聚类数目。 ### 参数说明 - `preference`: 控制着每个数据点对自己成为一个新的聚类中心的可能性,默认值通常设置成负数以减少不必要的新类别生成。 上述例子仅提供了基础框架,在实际应用时可能还需要调整更多参数选项以便更好地适应具体场景需求。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值