Matlab实现AGNES算法(每行代码标注详细注解)

news/2024/11/19 8:36:01/

在数据分析和机器学习中,聚类是一种常用的无监督学习方法,它可以将数据点按照某种相似度标准进行分组,从而发现数据中的结构和模式。聚类算法有很多种,其中一种比较经典的是AGNES算法,它是一种基于层次的聚类算法,它的全称是Agglomerative Nesting,即凝聚式嵌套。在这篇博客中,我将介绍AGNES算法的原理和意义,并给出一个用Matlab实现的代码示例。

目录

一、什么是AGNES算法

二、AGNES算法的意义

1.AGNES算法的优点

2.AGNES算法的应用场景

三、如何实现AGNES算法

1.AGNES算法大致思路

2.Matlab实现AGNES算法,对照每行代码标注详细注解

四、AGNES算法的总结和建议

这里是希望和大家一起进步的小高,愿意和读者们热情探讨😊


一、什么是AGNES算法

AGNES算法的原理是将数据集中的对象看作是一个图(graph)中的节点(node),然后根据节点之间的距离或者相似度来构建一个邻接矩阵(adjacency matrix)。邻接矩阵表示了图中节点之间是否相连以及相连程度。然后通过使用不同的连接方式(linkage)来计算不同簇之间的距离或者相似度,并且将最近或者最相似的两个簇合并成一个新的簇。这个过程重复进行,直到所有的节点都合并成一个大的簇为止。最后,根据需要划分的簇的个数,从合并过程中产生的树形结构(dendrogram)中切断一条水平线,得到最终的簇划分。

二、AGNES算法的意义

1.AGNES算法的优点

  • 不需要预先指定簇的个数,可以自动发现合适的簇的个数。
  • 可以生成一个树形结构,表示数据点之间的层次关系,方便进行可视化和分析。
  • 可以使用不同的距离度量和链接方法,适应不同的数据特征和需求。

例如,如果我们想要对一些文本数据进行聚类,我们可以使用余弦相似度作为距离度量,并使用平均链接作为链接方法。

2.AGNES算法的应用场景

  • 数据挖掘:可以用于对大量数据进行分组和分类,发现数据中的潜在模式和规律。
  • 信息检索:可以用于对文档或网页进行聚类,提高检索效率和质量。
  • 生物信息学:可以用于对基因或蛋白质进行聚类,揭示生物系统的结构和功能。
  • 图像处理:可以用于对图像进行分割或压缩,提高图像质量和效果。

三、如何实现AGNES算法

1.AGNES算法大致思路

(1)构建邻接矩阵:给定一个数据集X,其中包含n个对象,每个对象有p个属性。首先计算每两个对象之间的距离或者相似度,然后根据一定的规则来构建一个n乘n的邻接矩阵A。常用的规则有以下几种:

  • K近邻法(KNN):对于每个对象,只与其最近的K个对象相连,即A[i,j]=1当且仅当对象i和j是彼此最近的K个对象之一,否则A[i,j]=0。
  • ε-邻域法(ε-neighborhood):对于每个对象,只与其距离小于ε的对象相连,即A[i,j]=1当且仅当对象i和j之间的距离小于ε,否则A[i,j]=0。
  • 全连接法(fully connected):对于每个对象,与所有其他对象相连,即A[i,j]等于对象i和j之间的距离或者相似度。

(2)选择连接方式:根据不同的连接方式来计算不同簇之间的距离或者相似度。常用的连接方式有以下几种:

  • 最小距离法(single linkage):使用两个簇中最近的两个对象之间的距离作为簇之间的距离。
  • 最大距离法(complete linkage):使用两个簇中最远的两个对象之间的距离作为簇之间的距离。
  • 平均距离法(average linkage):使用两个簇中所有对象之间的平均距离作为簇之间的距离。
  • 中心距离法(centroid linkage):使用两个簇中各自计算出来的中心点之间的距离作为簇之间的距离。

(3)合并最近或者最相似的两个簇:根据所选用的连接方式,找出邻接矩阵中最小或者最大的元素,并且将对应的两个簇合并成一个新的簇。同时更新邻接矩阵,删除被合并掉的两个簇的行和列,增加新的簇的行和列,计算新的簇与其他簇之间的距离或者相似度。

(4)重复上一步,直到所有的节点都合并成一个大的簇为止:每次合并后,邻接矩阵的维度减一,直到只剩下一个元素为止。在合并的过程中,记录下每次合并的两个簇的编号和距离或者相似度,以及新产生的簇的编号。这些信息可以用来绘制树形结构(dendrogram)。

(5)根据需要划分的簇的个数,从树形结构中切断一条水平线,得到最终的簇划分:根据树形结构中不同高度的水平线,可以得到不同个数的簇划分。一般来说,水平线越高,划分出来的簇越少,水平线越低,划分出来的簇越多。可以根据实际问题或者数据特点来选择合适的水平线位置。

2.Matlab实现AGNES算法,对照每行代码标注详细注解

% 生成一个包含两个月牙形簇的数据集,共有300个样本,每个样本有两个属性
X = [moon(150,10,50,10);moon(150,10,-50,-10)]; % 使用自定义函数moon生成月牙形数据
y = [ones(150,1);2*ones(150,1)]; % 生成真实的簇标签
scatter(X(:,1),X(:,2),[],y) % 绘制数据集的散点图,不同颜色表示真实的簇标签
title('True labels') % 添加标题% 构建邻接矩阵,使用欧氏距离计算距离
n = size(X,1); % 获取样本数
A = zeros(n,n); % 初始化邻接矩阵
for i = 1:n % 遍历每一个样本for j = i+1:n % 遍历其他样本A(i,j) = norm(X(i,:)-X(j,:)); % 计算欧氏距离A(j,i) = A(i,j); % 由于距离是对称的,所以复制到对角位置end
end% 选择连接方式,这里使用最小距离法(single linkage)
method = 'single';% 初始化合并记录矩阵Z,它有n-1行和3列,每一行记录了一次合并操作
% 第一列和第二列是被合并掉的两个簇的编号,第三列是合并后产生的新簇的编号
Z = zeros(n-1,3);% 初始化当前存在的簇编号向量C,它有n个元素,每个元素表示对应样本所属的簇编号
C = (1:n)';% 初始化当前存在的簇数k,它等于样本数n
k = n;% 合并最近或者最相似的两个簇,重复进行n-1次
for t = 1:n-1 % 遍历每一次合并操作% 根据所选用的连接方式,找出邻接矩阵中最小或者最大的元素,并且获取对应的两个簇编号i和jif strcmp(method,'single') % 如果是最小距离法[min_val,min_idx] = min(A(:)); % 找出邻接矩阵中的最小值和其索引[i,j] = ind2sub(size(A),min_idx); % 将索引转换为行列坐标,即两个簇编号elseif strcmp(method,'complete') % 如果是最大距离法[max_val,max_idx] = max(A(:)); % 找出邻接矩阵中的最大值和其索引[i,j] = ind2sub(size(A),max_idx); % 将索引转换为行列坐标,即两个簇编号elseif strcmp(method,'average') % 如果是平均距离法A_mean = mean(A,2); % 计算邻接矩阵每一行的平均值[min_val,min_idx] = min(A_mean); % 找出平均值中的最小值和其索引,即一个簇编号i = min_idx; % 将索引赋值给iA_row = A(i,:); % 获取邻接矩阵第i行A_row(i) = inf; % 将第i行第i列的元素设为无穷大,避免干扰[min_val,min_idx] = min(A_row); % 找出第i行中的最小值和其索引,即另一个簇编号j = min_idx; % 将索引赋值给jelseif strcmp(method,'centroid') % 如果是中心距离法X_mean = mean(X,1); % 计算数据集每一列的平均值,即所有对象的中心点X_dist = pdist2(X,X_mean); % 计算每个对象与中心点的距离X_dist = X_dist ./ sum(X_dist); % 归一化距离,使其和为1A_centroid = A .* X_dist; % 计算邻接矩阵与距离的加权乘积,即每个元素乘以对应对象与中心点的距离比例A_centroid_mean = mean(A_centroid,2); % 计算加权邻接矩阵每一行的平均值[min_val,min_idx] = min(A_centroid_mean); % 找出平均值中的最小值和其索引,即一个簇编号i = min_idx; % 将索引赋值给iA_centroid_row = A_centroid(i,:); % 获取加权邻接矩阵第i行A_centroid_row(i) = inf; % 将第i行第i列的元素设为无穷大,避免干扰[min_val,min_idx] = min(A_centroid_row); % 找出第i行中的最小值和其索引,即另一个簇编号j = min_idx; % 将索引赋值给jend% 将对应的两个簇合并成一个新的簇,并且更新邻接矩阵,删除被合并掉的两个簇的行和列,增加新的簇的行和列,计算新的簇与其他簇之间的距离或者相似度C(C==j) = i; % 将编号为j的簇的所有对象的簇编号改为i,即将簇j合并到簇i中A(i,:) = min(A(i,:),A(j,:)); % 将邻接矩阵第i行和第j行取最小值,即使用最小距离法更新簇i与其他簇之间的距离A(:,i) = A(i,:)'; % 将邻接矩阵第i列设为第i行的转置,即保持对称性A(j,:) = []; % 删除邻接矩阵第j行A(:,j) = []; % 删除邻接矩阵第j列% 记录合并操作的信息,更新合并记录矩阵ZZ(t,1) = i; % 记录被合并掉的第一个簇的编号Z(t,2) = j; % 记录被合并掉的第二个簇的编号Z(t,3) = k+1; % 记录合并后产生的新簇的编号,从n+1开始递增k = k+1; % 更新当前存在的簇数,每次合并后加一end% 根据需要划分的簇的个数,从树形结构中切断一条水平线,得到最终的簇划分
n_clusters = 2; % 指定需要划分的簇的个数
T = clusterdata(X,'maxclust',n_clusters,'linkage',method); % 使用matlab自带的clusterdata函数进行层次聚类,指定最大簇数和连接方式,得到每个对象所属的簇编号
scatter(X(:,1),X(:,2),[],T) % 绘制聚类结果的散点图,不同颜色表示预测的簇标签
title('AGNES clustering') % 添加标题% 计算AGNES聚类的调整兰德指数(Adjusted Rand Index),用于评估聚类效果,取值范围是[-1,1],越接近1表示越好
ari_agnes = adjusted_rand_score(y, T);
fprintf('ARI of AGNES: %.4f\n',ari_agnes);

四、AGNES算法的总结和建议

AGNES算法是一种自底向上的层次聚类方法,它可以将数据集中的对象按照相似度逐步合并成一个大的簇。在使用AGNES算法时,我们需要注意以下几点:

  • 选择合适的距离或者相似度度量,根据数据的特点和需求,构建一个反映数据结构的邻接矩阵。
  • 选择合适的连接方式,根据不同的连接方式,计算不同簇之间的距离或者相似度,并且影响合并过程中产生的树形结构。
  • 选择合适的水平线位置,根据实际问题或者数据特点,从树形结构中切断一条水平线,得到最终的簇划分。

以上就是AGNES算法的全部内容啦~有帮助点个小赞收藏起来,会持续更新其他算法的实现

这里是希望和大家一起进步的小高,愿意和读者们热情探讨😊


http://www.ppmy.cn/news/1000029.html

相关文章

速通pytorch库

速通pytorch库(长文) 前言 ​ 本篇文章主要为那些对于pytorch库不熟悉、还没有上手的朋友们准备,梳理pytorch库的主要内容,帮助大家入门深度学习最重要的库之一。 目录结构 文章目录 速通pytorch库(长文)1.…

Kotlin 协程与 Flow

简介 Kotlin的Flow 是 Kotlin 在异步编程方面的一个重要组件,它提供了一种声明式的、可组合的、基于协程的异步编程模型。Flow 的设计灵感来自于 Reactive Streams、RxJava、Flux 和其他异步编程库,但它与 Kotlin 协程无缝集成,并提供了一种更…

Selenium/webdriver原理解析

最近在看一些底层的东西。driver翻译过来是驱动,司机的意思。如果将webdriver比做成司机,竟然非常恰当。 我们可以把WebDriver驱动浏览器类比成出租车司机开出租车。在开出租车时有三个角色: 乘客:他/她告诉出租车司机去哪里&…

力扣:48. 旋转图像(Python3)

题目: 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 来源:力扣(LeetCode) 链接&…

GICI-LIB代码框架学习

一直想要学习多源融合,一直各种琐碎事情耽搁,没有进展。终于,今天以上海交大开源的GNSS/INS/Camera组合导航库为开始。 二话不说,github下载代码后,不编译,不运行,直接vs code打开工程&#xf…

学习gRPC (二)

代码获取 gRPC 仓库的地址:https://github.com/grpc/grpc。可以使用git clone https://github.com/grpc/grpc.git --recursive 拉取最新的代码以及包括其子模块。 在这里我列举几个重要的文件夹 doc (这是整个gRPC 仓库重要文档目录)example (这是各种语言版本例…

Ubuntu下载deb包及其依赖包

一、简介 有时我们需要在离线环境使用提前准备好的deb包,然后只需要在新机器使用dpkg -i安装即可。 二、命令 apt-get download $(apt-rdepends (需要下载的包,可以有多个) | grep -v "^ " | sed s/debconf-2.0/debco…

使用Gunicorn+Nginx部署Flask项目

部署-开发机上的准备工作 确认项目没有bug。用pip freeze > requirements.txt将当前环境的包导出到requirements.txt文件中,方便部署的时候安装。将项目上传到服务器上的/srv目录下。这里以git为例。使用git比其他上传方式(比如使用pycharm&#xff…