博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
K均值聚类算法的MATLAB实现
阅读量:5954 次
发布时间:2019-06-19

本文共 2338 字,大约阅读时间需要 7 分钟。

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);endfor i = 1 : N    D(2,i) = sqrt((X(i) - U2(1,m))^2 + (Y(i) - U2(2,m))^2);endA = 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);    endendindexA = 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)); % 更新两个聚类中心endfigure;plot(A(1,indexA) , A(2,indexA), '*b'); % 作出第一类点的图形hold onplot(B(1,indexB) , B(2,indexB), 'oy'); %作出第二类点的图形hold oncenterx = [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步,从上图来看,分类的效果还是不错的。但是每次运行可能分类的结果会不一样,这是因为这些点是随机生成的,而且也没有明确的分类标准的缘故。

 

热爱编程,热爱机器学习! github:http://www.github.com/Lyrichu github blog:http://Lyrichu.github.io 个人博客站点:http://www.movieb2b.com(不再维护)

转载地址:http://eooxx.baihongyu.com/

你可能感兴趣的文章
Atom 编辑器系列视频课程
查看>>
C#三种定时器
查看>>
范数 L1 L2
查看>>
协同过滤及大数据处理
查看>>
Java8 本地DateTime API
查看>>
jQuery 增加 删除 修改select option
查看>>
[原][osgearth]osgearthviewer读取earth文件,代码解析(earth文件读取的一帧)
查看>>
springboot 常用插件
查看>>
一个基于特征向量的近似网页去重算法——term用SVM人工提取训练,基于term的特征向量,倒排索引查询相似文档,同时利用cos计算相似度...
查看>>
[转]Newtonsoft.Json高级用法
查看>>
35个Java代码性能优化总结
查看>>
Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简述及技术选型介绍
查看>>
剑指offer——35复杂链表的复制
查看>>
DFI、DPI技术
查看>>
hibernate 执行存储过程 方法
查看>>
RapidIOIP核的验证方法研究_王玉欢
查看>>
崩溃日志的实例
查看>>
base64是啥原理
查看>>
字符串中去除连续相同的字符保留一个
查看>>
实战 Windows Server 2012 群集共享卷
查看>>