数学建模社区-数学中国

标题: 【聚类算法】带你轻松搞懂K-means聚类(含代码以及详细解释) [打印本页]

作者: 杨利霞    时间: 2022-9-13 12:26
标题: 【聚类算法】带你轻松搞懂K-means聚类(含代码以及详细解释)
【聚类算法】带你轻松搞懂K-means聚类(含代码以及详细解释)( h3 S: {; O6 N  l4 ?) S- C7 @
% I# b$ n3 Q" r
文章目录9 U9 x+ P1 ]* u/ h
一:K-means聚类算法7 g7 F5 b1 S7 V+ M) r9 y
二:实例分析  n% x7 I+ O( ]" s( I
三:原理与步骤
" ?5 K0 p4 i) y四:Matlab代码以及详解
: N) R. j& X% B3 g- ~: b6 \一:K-means聚类算法) r6 D0 Z/ p) K- C
聚类是一个将数据集中在某些方面相似的数据成员进行分类组织的过程,聚类就是一种发现这种内在结构的技术,聚类技术经常被称为无监督学习。  g2 N) g* j# W" c+ _
k均值聚类是最著名的划分聚类算法,由于简洁和效率使得他成为所有聚类算法中最广泛使用的。给定一个数据点集合和需要的聚类数目k,k由用户指定,k均值算法根据某个距离函数反复把数据分入k个聚类中。
+ t! I4 O+ G: ]! C) a; _' {& h  |: j8 ~1 ~0 L' a
二:实例分析
) S+ ?% q6 E; i( A* k现有50个二维数据点如下图,使用K-Means算法将以下数据实现聚类。  f3 b# V4 _: {  l8 ]+ o- J

; \1 |7 m+ I. V结果展示:: A: W+ \. e& f/ k- ?+ `" W

" R! |) h, k9 ~4 v( H* |% g7 f; E9 T$ z% N; z4 c
三:原理与步骤% w0 {5 s6 k' U0 `8 F, k6 q- I" `
K-means算法是典型的基于距离(欧式距离、曼哈顿距离)的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。& b  G) C% ?0 ?4 S
K-mean算法步骤如下:2 u7 @0 P: J, n) }

6 L! I0 c$ R8 z# J先定义总共有多少个簇类,随机选取K个样本为簇中⼼。
9 ?# Y5 C6 f3 Z9 E7 W3 h分别计算所有样本到随机选取的K个簇中⼼的距离。  J# w# q/ X% b2 @+ ^
样本离哪个中⼼近就被分到哪个簇中⼼。
. g" f- c& @  X2 J$ ?6 K计算各个中⼼样本的均值(最简单的⽅法就是求样本每个点的平均值)作为新的簇心。0 h# }* u' T( j% c2 J1 J& F
重复2、3、4直到新的中⼼和原来的中⼼基本不变化的时候,算法结束。
2 N2 s- _5 I$ N8 H算法结束条件:$ v' U3 [/ H6 R

7 u7 I1 s! q( W当每个簇的质心,不再改变时就可以停止k-menas。
! P& h+ L7 N  z& l5 ^当循环次数达到事先规定的次数时,停止k-means
7 _7 R1 k1 v0 Y' x; r原理示意图:
1 n* G' D, t# M0 z- A" C# e
7 h6 }7 ]3 I( h- B简单小实例:
1 T/ Z; E! O$ k; g2 a5 W' u有以下6个点,初始随机选取两个点作为两个簇的簇中心(这里假设选取的是A3,A4),求最后的簇所属情况。
: }7 E9 V4 [# {) J% d
: ^! {/ P. d; F) @( E) U1️⃣:计算每个点到簇心的距离,将距离近的归为一类。
: f- n8 @) ^! t" C! I
$ A2 q+ B  v/ o& ^5 \6 c- p9 n2️⃣:将红色对应的点和绿色对应的每个点分别求X,Y平均值,最为新的簇心。+ v7 p# d" U* k% c+ y3 E/ \

9 l% h" e  L+ g8 m. |) @3️⃣:计算每个点到新簇心的距离,继续将对应距离近的点归为一类。
/ t5 v' b! e! k7 ]: a. g3 L; N( ]$ n2 t9 T0 R! d' Z$ {1 a
4️⃣:由于关联点没有发生变化,所以之后的结果不会发生变化。停止计算
- b9 j$ Q0 h2 T% Y, y2 F8 R- L& A5️⃣:得结果红色簇:A1,A3,A5,紫色簇:A2,A4,A6。
( r0 a# Q0 o5 E, Y2 K; ]% T
- Y; X: K7 i( b5 x. x' Y四:Matlab代码以及详解. y6 g2 f. c) ?' I. c
clc;clear;close all;
  ?$ [7 D' d$ O8 p; q4 }9 ~6 Idata(:,1)=[90,35,52,83,64,24,49,92,99,45,19,38,1,71,56,97,63,...
2 x! s# `) b0 r    32,3,34,33,55,75,84,53,15,88,66,41,51,39,78,67,65,25,40,77,...# y; r6 Z' j$ ^
    13,69,29,14,54,87,47,44,58,8,68,81,31];
; T- ]/ U- [: a& ]/ w5 udata(:,2)=[33,71,62,34,49,48,46,69,56,59,28,14,55,41,39,...
2 I2 N0 `$ [- i1 ~- T) Z# S    78,23,99,68,30,87,85,43,88,2,47,50,77,22,76,94,11,80,...
% x- n( t1 v4 d8 D    51,6,7,72,36,90,96,44,61,70,60,75,74,63,40,81,4];9 V8 o; d. J+ K
%50 * 1  R+ s6 f- Q# b0 J/ Y$ R
figure(1)
; @% ~( _) g  q. b
3 ~9 L% J( n- ~; `& `* E" gscatter(data(:,1),data(:,2),'MarkerEdgeColor','r','LineWidth',2)
. o8 j$ b8 ?6 S$ _1 _  \: s%% 原理推导K均值$ c& ]7 W- ^# @# }
[m,n]=size(data);%m = 50,n = 1;
- ]* Z, s" Z; l; J; Y$ Q4 qcluster_num=4;%4个初始中心
# r- I; n- H" _/ M: scluster=data(randperm(m,cluster_num),;%randperm(m,cluster_num)在前m中随机选取cluster_num个  %随机选取中心
: l9 g1 P* a. l8 R+ y/ }$ h%data函数  取数据用
0 k* x# g, S8 z7 E1 E% Sepoch_max=1000;%最大次数; }4 @& p" X5 B( e
therad_lim=0.001;%中心变化阈值
& H3 o' K; O0 [' l, C3 Tepoch_num=0;
- N4 M8 v. F" n. t' u8 |* Rwhile(epoch_num<epoch_max)0 W: L# j' A9 H" C
    epoch_num=epoch_num+1;
& K0 P8 l. S9 \- r9 w    for i=1:cluster_num
2 n) s1 D$ a& ?7 m7 S0 m* O    distance=(data-repmat(cluster(i,,m,1)).^2;% 50 * 2  repmat扩展矩阵9 }$ h6 q- z) b# N
    %.^2是矩阵中的每个元素都求平方,^2是求矩阵的平方或两个相同的矩阵相乘,因此要求矩阵为方阵
: [# k: K0 Q8 m2 y    distance1(:,i)=sqrt(sum((distance),2));%求行和7 Y5 N/ L  P6 C. w
    %distance1(:,i)=sqrt(sum(distance'));% 默认求列和  1表示每一列进行求和,2表示每一行进行求和;
  b( \  w  G0 s, {4 o' M* J    %sqrt(sum(distance')) == 1 * 50
6 b" C$ S5 m# j6 t, k( E% O    %distance1 50 * 4 表示每个点距离第i个点的距离4 `, {) t( y7 v1 f0 t
    end
) ~4 P' q" B' y% W    [~,index_cluster]=min(distance1');%distance1' = 4 * 50,min 求列最值  index_cluster = 最小值所在行号  index_cluster = 1 * 50
  ^8 |1 E1 W) V% I: L$ N    for j=1:cluster_num' U' u' q8 O# P  f/ L
    cluster_new(j,=mean(data(find(index_cluster==j),);% 4 * 2  找到距离对应中心最近的点 横纵坐标各取平均值, N2 @- O9 K) X: Z' C5 G1 p
    end
7 F) d: B! L# U5 Y/ r+ v5 a    if (sqrt(sum((cluster_new-cluster).^2))>therad_lim), Z% Z6 p1 D# C# F) b6 M
        cluster=cluster_new;" k' K: ^7 P7 E5 G
    else
+ H' t# y! x! b5 s0 l6 h. \' e        break;
6 f/ v9 }+ I3 f! n    end8 X% |$ B% h6 W% R! z
end% o  `7 K" |. g9 k( h6 _
%% 画出聚类效果" \, h) k# w  W5 ]5 U! r+ t
figure(2)6 u3 G# R3 m  u' X& M
%subplot(2,1,1)
) f5 J" A$ ~' z6 j$ {a=unique(index_cluster); %找出分类出的个数# B, i- s9 b+ B- c0 Z4 D
C=cell(1,length(a));%1 * 4的元胞
7 Q  m! [9 t! h" T" ]8 s( t; mfor i=1:length(a)" {' g5 H- i( h& e; j0 `
   C(1,i)={find(index_cluster==a(i))};
7 F  b4 N, x- {1 R+ cend
+ H7 g! ~  p  E- R3 G. d& F% Lfor j=1:cluster_num$ k7 c8 ~: e8 T" R( O( O
    data_get=data(C{1,j},;%从data中取每个类的点
" p9 a( [. j2 N, ]# \8 A    scatter(data_get(:,1),data_get(:,2),80,'filled','MarkerFaceAlpha',.6,'MarkerEdgeAlpha',.9);- V" ^) I7 O1 D. y8 U" c3 D8 I* d
    hold on$ |& Y' J0 v2 ~
end, [# x" C' N2 G9 E) Y
plot(cluster(:,1),cluster(:,2),'kp','LineWidth',2);%画出4个聚类中心7 [' R' ^& Q+ K$ G3 w# ~
hold on! B1 e2 ~! D# G' b8 R
sc_t=mean(silhouette(data,index_cluster'));
/ ~, g. u3 F$ Q+ w) E4 Ptitle_str=['原理推导K均值聚类','  聚类数为:',num2str(cluster_num),'  SC轮廓系数:',num2str(sc_t)];: L3 c" \8 G- y4 [9 `" ~- y
title(title_str)
5 ~5 E: Z9 P# h/ g
" @% R$ \6 b& {- A& Y# y————————————————, e7 ?/ g4 P# c9 n/ D
版权声明:本文为CSDN博主「Rookiep」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
6 G! i% C8 b5 X! N% S- H原文链接:https://blog.csdn.net/qq_43727529/article/details/1268133211 g% d, Z4 V- s+ _. y7 @; A
: ], r# T  O1 V5 V9 `6 n5 v

; u9 x1 {6 e# j- G6 G: {3 o3 t5 x: F




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5