完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.K-均值聚类法的概述
之前在参加数学建模的过程中用到过这种聚类方法,但是当时只是简单知道了在matlab中如何调用工具箱进行聚类,并不是特别清楚它的原理。最近因为在学模式识别,又重新接触了这种聚类算法,所以便仔细地研究了一下它的原理。弄懂了之后就自己手工用matlab编程实现了,最后的结果还不错,嘿嘿~~~ 简单来说,K-均值聚类就是在给定了一组样本(x1, x2, 。。.xn) (xi, i = 1, 2, 。。. n均是向量) 之后,假设要将其聚为 m(《n) 类,可以按照如下的步骤实现: Step 1: 从 (x1, x2, 。。.xn) 中随机选择 m 个向量(y1,y2,。。.ym) 作为初始的聚类中心(可以随意指定,不在n个向量中选择也可以); Step 2: 计算 (x1, x2, 。。.xn) 到这 m 个聚类中心的距离(严格来说为 2阶范数); Step 3: 对于每一个 xi(i = 1,2,。。.n)比较其到 (y1,y2,。。.ym) 距离,找出其中的最小值,若到 yj 的距离最小,则将 xi 归为第j类; Step 4: m 类分好之后, 计算每一类的均值向量作为每一类新的聚类中心; Step 5: 比较新的聚类中心与老的聚类中心之间的距离,若大于设定的阈值,则跳到 Step2; 否则输出分类结果和聚类中心,算法结束。 OK,废话不多说,直接上Matlab代码。 % 利用K-均值聚类的原理,实现对一组数据的分类。这里以一组二维的点为例。 N = 40; % 点的个数 X = 10*rand(1,N); Y = 10*rand(1,N); % 随机生成一组横纵坐标取值均在(0,10)之间的点,X Y 分别代表横纵坐标 plot(X, Y, ‘r*’); % 绘出原始的数据点 xlabel(‘X’); ylabel(‘Y’); title(‘聚类之前的数据点’); n = 2; %将所有的数据点分为两类 m = 1; %迭代次数 eps = 1e-7; % 迭代结束的阈值 u1 = [X(1),Y(1)]; %初始化第一个聚类中心 u2 = [X(2),Y(2)]; %初始化第二个聚类中心 U1 = zeros(2,100); U2 = zeros(2,100); %U1,U2 用于存放各次迭代两个聚类中心的横纵坐标 U1(:,2) = u1; U2(:,2) = u2; D = zeros(2,N); %初始化数据点与聚类中心的距离 while(abs(U1(1,m) - U1(1,m+1)) 》 eps || abs(U1(2,m) - U1(2,m+1) 》 eps || abs(U2(1,m) - U2(1,m+1)) 》 eps || abs(U2(2,m) - U2(2,m+1)) 》 eps)) m = m +1; % 计算所有点到两个聚类中心的距离 for i = 1 : N D(1,i) = sqrt((X(i) - U1(1,m))^2 + (Y(i) - U1(2,m))^2); end for i = 1 : N D(2,i) = sqrt((X(i) - U2(1,m))^2 + (Y(i) - U2(2,m))^2); end A = zeros(2,N); % A用于存放第一类的数据点 B = zeros(2,N); % B用于存放第二类的数据点 for k = 1: N [MIN,index] = min(D(:,k)); if index == 1 % 点属于第一个聚类中心 A(1,k) = X(k); A(2,k) = Y(k); else % 点属于第二个聚类中心 B(1,k) = X(k); B(2,k) = Y(k); end end indexA = find(A(1,:) ~= 0); % 找出第一类中的点 indexB = find(B(1,:) ~= 0); % 找出第二类中的点 U1(1,m+1) = mean(A(1,indexA)); U1(2,m+1) = mean(A(2,indexA)); U2(1,m+1) = mean(B(1,indexB)); U2(2,m+1) = mean(B(2,indexB)); % 更新两个聚类中心 end figure; plot(A(1,indexA) , A(2,indexA), ‘*b’); % 作出第一类点的图形 hold on plot(B(1,indexB) , B(2,indexB), ‘oy’); %作出第二类点的图形 hold on centerx = [U1(1,m) U2(1,m)]; centery = [U1(2,m) U2(2,m)]; plot(centerx , centery, ‘+g’); % 画出两个聚类中心点 xlabel(‘X’); ylabel(‘Y’); title(‘聚类之后的数据点’); disp([‘迭代的次数为:’,num2str(m)]); 得到的分类结果如下: 50个随机生成的点分为两类迭代只需要4步,从上图来看,分类的效果还是不错的。但是每次运行可能分类的结果会不一样,这是因为这些点是随机生成的,而且也没有明确的分类标准的缘故。 |
|
|
|
只有小组成员才能发言,加入小组>>
921 浏览 1 评论
1077 浏览 1 评论
12502 浏览 0 评论
5921 浏览 3 评论
17713 浏览 6 评论
1020浏览 1评论
1010浏览 1评论
923浏览 1评论
4609浏览 1评论
1082浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 09:59 , Processed in 0.870681 second(s), Total 48, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号