clc,clear
a = [73,40,7;
60,15,5;
61,19,2;
34,18,6;
67,126,10;
91,40,4;
101,40,13;
81,40,6;
88,40,8;
122,40,17;
102,50,17;
87,50,12;
110,50,14;
164,50,17;
40,30,1;
76,40,17;
118,50,9;
160,50,15];
[m,n] = size(a);
d = zeros(m);
d = mandist(a'); % mandist 求矩阵列向量组之间的两两绝对值
d = tril(d); % 截取下三角元素,将矩阵d转为下三角矩阵
nd = nonzeros(d); % 去掉d中的元素,非零元素按列排列
nd = unique(nd) % 去掉重复的非零元素
for i = 1:m-1 % 对非零距离数组nd进行循环
nd_min = min(nd); % 每次迭代选择最小的距离值
[row,col] = find(d == nd_min); % 找到所有等于当前最小距离的行和列索引
tm = union(row,col); %row和col归为一列 合并这些索引形成一个集合tm
tm = reshape(tm,1,length(tm)); % 把数组tm变成列向量
fprintf('第%d次合成,平台高度为%d时的分类结果为:%s \n',...
i,nd_min,int2str(tm));
nd(nd == nd_min) = []; % 从nd中移出已处理的最小距离值,直到没有剩余距离值可处理
if length(nd) == 0
break
end
end
% 计算距离矩阵
dist_matrix = pdist(a,'cityblock'); % 使用曼哈顿距离
% 构建层次聚类树
Z = linkage(dist_matrix); % 使用ward方法,也可以尝试其他方法如'single', 'complete', 'average'
disp('距离矩阵:')
disp(Z)
% 绘制层次聚类图
figure;
dendrogram(Z);
title('亚洲球队聚类图');
1.mandist()
mandist(A, B)
- 是用来求A中每个行向量与B中每个列向量的绝对距离
- 要求:mandist两个参数表示两个矩阵,第一个矩阵的列数 = 第二个矩阵的行数
- 结果维数:行数 = 第一个矩阵的行数, 列数 = 第二个矩阵的列数
eg.一维
a = [1, 2, 3]
b = [-1, 5, 6]
mandist(a, b') = 8
% a(1, 3) b'(3, 1)
% |1- (-1)| +|2 - 5| + |3 - 6| = 8
eg.二维
A = [1, 2, 3
4, 5, 6]
mandist(A, A') = [0, 9
9, 0]
% A' = [1, 4
2, 5
3, 6]
% x(1,1) = |1-1| + |2-2| +|3-3| = 0
% x(1,2) = |1-4| + |2-5| +|3-6| = 9
% x(2,1) = |4-1| + |5-2| +|6-3| = 9
% x(2,2) = |4-4| + |5-5| +|6-6| = 0
2.reshape()
B = reshape(A, m, n)
将矩阵A的元素返回到一个m x n的矩阵B中。如果A中没有m x n个元素,则返回错误。
3.pdist()
成对观测值之间的两两距离,用于计算一个数据中所有点对之间的距离,基本语法:
D = pdist(X, distance)
- X:输入数据矩阵,其中每一行代表一个观测或样本,每一列代表一个特征。例如,如果你又100个样本,每个样本有3个特征,那么X就是一个100x3的矩阵。
- distance:(可选参数)字符串,指定计算距离的方法,包括但不限于
- 'euclidean':欧式距离,是最常见的距离度量,如果第二个参数不写,默认用欧式距离
- 'cityblock':曼哈顿距离,也称街区距离
官网文档:成对观测值之间的两两距离 - MATLAB pdist - MathWorks 中国
4.linkage()
生成具有层次结构的聚类树
Z = linkage(Y, method, metric)
- Y为输入矩阵是pdist函数输出的距离行向量
- method包括但不限于:
- 'single':最短距离法(默认),合并距离最近的两个对象
- 'ward':内平方距离法(最小方差算法),合并使簇内方差增量最小的两个簇
- 'average':平均距离法,合并平均距离最小的两个簇
- metric:(可选参数)当Y是相似性矩阵时,用于指定相似性转换为距离时的度量,默认通常 是'euclidean'。metric参数是用来指定计算距离或相似性的方式。这个参数通常在 距离计算函数(如 pdist)中使用,或者间接地影响到 linkage函数的行为,尤其 是当你直接提供了相似性矩阵给 linkage时。
输出:是一个 包含聚类树信息的(m-1) x 3的矩阵,其中m是输入数据点的数量,每一行代表一个聚类步骤
- 之所以是 n-1行,是因为聚类过程是从 n 个单独的点开始,每次合并两个最接近的点或簇,最终形成一个单一的大簇,一共需要合并 n-1 次才能完成这个过程。
-
每一行代表一个聚类步骤:矩阵的每一行对应于聚类过程中的一步,即一次具体的合并操作。随着行数的增加,聚类步骤逐步进行,最终达到所有数据点合并为一个簇。
-
三列的含义:
- 第一列(索引 i):表示被合并的第一个簇在当前步骤中的临时簇编号(这个编号是按合并顺序分配的,从1开始,每次合并新簇产生就增加一个编号)。
- 第二列(索引 j):表示被合并的第二个簇的临时簇编号。注意,i 总是小于 j,以避免重复计算。
- 第三列(距离 d):表示簇 i 和簇 j 在合并时的距离,这个距离的计算依赖于你在调用 linkage 函数时选择的 method 参数(如最小距离、最大距离、平均距离、Ward's 方法等)。这个距离可以被理解为两个簇间的不相似度或分离程度。
官方文档:聚集分层聚类树 - MATLAB 链接 - MathWorks 中国
5.dendrogram()
dendrogram(Z)
-
Z: 必需参数,是一个由linkage函数生成的(m-1)x3 的矩阵,其中 m 是原始数据点的数量。每一行代表一次聚类合并,包含参与合并的簇索引和合并时的距离。
-
Orientation: 可选参数,指定树状图的方向,可以是'top'(默认),树状图朝上生长)、'bottom'(朝下生长)、'left' 或' right'。
-
ColorThreshold: 用于设置颜色阈值,以此为界线在树状图上标示不同颜色,从而直观地区分簇。当聚类树的垂直距离超过这个阈值时,连接线将改变颜色。
clc,clear
a = [73,40,7;
60,15,5;
61,19,2;
34,18,6;
67,126,10;
91,40,4;
101,40,13;
81,40,6;
88,40,8;
122,40,17;
102,50,17;
87,50,12;
110,50,14;
164,50,17;
40,30,1;
76,40,17;
118,50,9;
160,50,15];
z = linkage(a, 'single', 'cityblock')
dendrogram(z)
T = cluster(z,'maxclust',3)
for i = 1: 3
tm = find(T == i)
fprintf('第%d类的有:%s\n',i,int2str(tm));
end
6.cluster()
T = cluster(z, 'cutoff', d)
根据linkage输出的 Z 进行层次聚类,并且直接指定要分成 d 个簇(类)。cluster函数会根据聚类树(由Z定义)在某个特定高度(cutoff)切割树,返回一个向量T ,其中每个元素表示对应于a中行的簇分配。例如,如果T = [1, 2, 1, 3, 1, ...],这表示第一行和第三行的数据点被分到了第一类(簇1),第二行数据点分到了第二类(簇2),第四行数据点分到了第三类(簇3),依此类推。
find(T == i) 是一个查找操作,它遍历向量T
中的每一个元素,检查哪些元素的值等于当前的循环变量i
。这里的i在循环for i = 1 : 3中依次取值1、2、3,代表我们要分别找出属于第一类、第二类、第三类的所有数据点。