聚类分析

image-20240129194932249

聚类不知道类别

K-means聚类算法

image-20240129194952521

流程图:

image-20240129195121059

优缺点分析

image-20240129195132844

K-means++算法

image-20240129195226437

操作

image-20240129195330285
image-20240129195405248

系统(层次)聚类

image-20240129195509250

距离计算

image-20240129195530809
image-20240129200236007
image-20240129200246282
image-20240129200254274
image-20240129200321590
image-20240129200335096

注意

image-20240129200430566
image-20240129200448939

会生成聚类谱系图,以此判断选择几类

image-20240129200741109
image-20240129200821668

详细操作见下博客

SPSS操作(四):系统聚类分析_聚类分析spss操作-CSDN博客

DBSCAN 算法

image-20240129201052622

基本概念

image-20240129201312072
image-20240129201355010

代码

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
69
70
71
72
73
74
75
76
77
clc;
clear;
close all;

%% Load Data

load mydata;


%% Run DBSCAN Clustering Algorithm

epsilon=0.5;
MinPts=10;
IDX=DBSCAN(X,epsilon,MinPts);




function [IDX, isnoise]=DBSCAN(X,epsilon,MinPts)

C=0;

n=size(X,1);
IDX=zeros(n,1); % 初始化全部为0,即全部为噪音点

D=pdist2(X,X);

visited=false(n,1);
isnoise=false(n,1);

for i=1:n
if ~visited(i)
visited(i)=true;

Neighbors=RegionQuery(i);
if numel(Neighbors)<MinPts
% X(i,:) is NOISE
isnoise(i)=true;
else
C=C+1;
ExpandCluster(i,Neighbors,C);
end

end

end

function ExpandCluster(i,Neighbors,C)
IDX(i)=C;

k = 1;
while true
j = Neighbors(k);

if ~visited(j)
visited(j)=true;
Neighbors2=RegionQuery(j);
if numel(Neighbors2)>=MinPts
Neighbors=[Neighbors Neighbors2]; %#ok
end
end
if IDX(j)==0
IDX(j)=C;
end

k = k + 1;
if k > numel(Neighbors)
break;
end
end
end

function Neighbors=RegionQuery(i)
Neighbors=find(D(i,:)<=epsilon);
end

end

当然,让我逐行解释这段MATLAB代码:

  1. clc; clear; close all;
    • clc:清除命令窗口。
    • clear:清除工作区中的所有变量。
    • close all:关闭所有打开的图形窗口。
  2. load mydata;
    • 从名为 'mydata' 的文件中加载数据到工作区。这里的假设是 'mydata' 包含一个表示数据点的变量 X
  3. epsilon=0.5; MinPts=10;
    • 定义DBSCAN算法的参数,epsilon 是邻域半径,MinPts 是邻域内最小数据点数。
  4. IDX=DBSCAN(X,epsilon,MinPts);
    • 调用DBSCAN函数,对数据 X 进行密度聚类,返回聚类结果 IDX
  5. function [IDX, isnoise]=DBSCAN(X,epsilon,MinPts)
    • 定义DBSCAN算法的主函数,接受输入参数 XepsilonMinPts
  6. C=0;
    • 初始化聚类簇数为0。
  7. n=size(X,1); IDX=zeros(n,1);
    • 获取数据点数量 n,初始化聚类标签 IDX 全部为0,表示所有点都是噪音点。
  8. D=pdist2(X,X);
    • 计算数据点之间的距离矩阵 D
  9. visited=false(n,1); isnoise=false(n,1);
    • 初始化用于标记是否访问过的向量 visited 和标记是否为噪音点的向量 isnoise
  10. for i=1:n
    • 开始对每个数据点进行迭代。
  11. if ~visited(i)
    • 如果当前点未被访问过,则执行以下操作。
  12. visited(i)=true; Neighbors=RegionQuery(i);
    • 将当前点标记为已访问,然后找到与当前点在邻域内的点集合 Neighbors
  13. if numel(Neighbors)<MinPts
    • 如果邻域内点的数量小于 MinPts,则将当前点标记为噪音点。
  14. else
    • 否则,执行以下聚类操作。
  15. C=C+1; ExpandCluster(i,Neighbors,C);
    • 增加聚类簇数,并进行扩展聚类操作。
  16. function ExpandCluster(i,Neighbors,C)
    • 定义扩展聚类的子函数,给定当前点、邻域内点集合和当前簇数。
  17. IDX(i)=C;
    • 将当前点标记为属于当前簇。
  18. while true
    • 进入循环,不断扩展聚类。
  19. j = Neighbors(k);
    • 取出邻域内的第 k 个点。
  20. if ~visited(j)
    • 如果该点未被访问过,则执行以下操作。
  21. visited(j)=true; Neighbors2=RegionQuery(j);
    • 将该点标记为已访问,然后找到与该点在邻域内的点集合 Neighbors2
  22. if numel(Neighbors2)>=MinPts
    • 如果新邻域内的点数量大于等于 MinPts,则将新邻域内的点添加到原邻域中。
  23. Neighbors=[Neighbors Neighbors2];
    • 将新邻域内的点添加到原邻域中。
  24. end
    • 结束新邻域内点的处理。
  25. if IDX(j)==0
    • 如果该点尚未被分配到任何簇,则将其分配到当前簇。
  26. IDX(j)=C;
    • 将该点标记为属于当前簇。
  27. k = k + 1; if k > numel(Neighbors) break; end
    • 处理邻域内的下一个点,直到邻域内的所有点都被处理完。
  28. function Neighbors=RegionQuery(i)
    • 定义邻域查询的子函数,给定当前点的索引 i,返回在邻域内的点的索引集合。
  29. Neighbors=find(D(i,:)<=epsilon);
    • 根据距离矩阵,找到与当前点距离在 epsilon 以内的点。
  30. end
    • 结束邻域查询子函数。
  31. end
    • 结束主函数。

这样,整个代码就实现了DBSCAN聚类算法。