1. k -均值聚类法的概述
,,之前在参加数学建模的过程中用到过这种聚类方法,但是当时只是简单知道了在matlab中如何调用工具箱进行聚类,并不是特别清楚它的原理。最近因为在学模式识别,又重新接触了这种聚类算法,所以便仔细地研究了一下它的原理。弄懂了之后就自己手工用matlab编程实现了,最后的结果还不错,嘿嘿~ ~ ~
,简单来说,K -均值聚类就是在给定了一组样本(x1, x2,…xn) (xi, i=1,2,…n均是向量)之后,假设要将其聚为m (& lt; n)类,可以按照如下的步骤实现:
,步骤1:从,(x1, x2,…xn)中随机选择m个向量(y1, y2,…ym)作为初始的聚类中心(可以随意指定,不在n个向量中选择也可以);
,步骤2:计算,(x1, x2,…xn)到这m个聚类中心的距离(严格来说为2阶范数),
,步骤3:对于每一个xi (i=1、2、…n)比较其到,(y1, y2,…ym),距离,找出其中的最小值,若到yj的距离最小,则将xi归为第j类;
,步骤4:m类分好之后,计算每一类的均值向量作为每一类新的聚类中心;
,第五步:比较新的聚类中心与老的聚类中心之间的距离,若大于设定的阈值,则跳到步骤2;否则输出分类结果和聚类中心,算法结束。
,好了,废话不多说,直接上Matlab代码。
%,利用K -均值聚类的原理,实现对一组数据的分类。这里以一组二维的点为例。 时间=N 40;, %,点的个数 时间=X 10 *兰德(1,N); 时间=Y 10 *兰德(1,N);, %,随机生成一组横纵坐标取值均在(0,10)之间的点,X Y 分别代表横纵坐标 情节(X, Y,, r *);, %,绘出原始的数据点 包含(“X”); ylabel (Y); 标题(“聚类之前的数据点”); 时间=n 2,, %将所有的数据点分为两类 时间=m 1;, %迭代次数 时间=eps 1 e;, %,迭代结束的阈值 u1 =, [X (1), Y(1)];, %初始化第一个聚类中心 u2 =, [X(2),(2)];, %初始化第二个聚类中心 时间=U1 0 (2100); 时间=U2 0 (2100);, % U1, U2 用于存放各次迭代两个聚类中心的横纵坐标 U1 (:, 2),=, U1; U2 (:, 2),=, U2乐队; D =, 0 (2 N);, %初始化数据点与聚类中心的距离,而(abs (U1(1米),安康;U1 (m + 1)),祝辞,eps | |, abs (U1(2米),安康;U1 (2 m + 1),祝辞,eps | |, abs (U2(1米),背后,U2 (m + 1)),祝辞,eps | |, abs (U2(2米),背后,U2 (m + 1)),祝辞,eps)) ,,,m =, m + 1,,,,, %,计算所有点到两个聚类中心的距离for 小姐:=,1,:N ,,,D(我),=,sqrt ((X (i),安康;U1(1米))^ 2,+,(Y (i),安康;U1(2米))^ 2); endfor 小姐:=,1,:N ,,,D(我),=,sqrt ((X (i),背后,U2(1米))^ 2,+,(Y (i),背后,U2(2米))^ 2); 结束 时间=A 0 (2 N);, %,用于存放第一类的数据点 时间=B 0 (2 N);, %, B用于存放第二类的数据点for k =, 1: N ,,,(MIN、索引),=,最小值(D (:, k)),, ,,,if index ==, 1,, %,点属于第一个聚类中心 ,,,,,,,一个(k),=, X (k); ,,,,,,,一个(2 k),=, Y (k),,,,, else ,,,,,,,,,, %,点属于第二个聚类中心 ,,,,,,,B (1 k),=, X (k); ,,,,,,,B (2 k),=, Y (k); ,才能结束 结束 indexA =,发现((1:),~=,0),,%,找出第一类中的点 indexB =,发现(B(1:), ~=, 0),, %,找出第二类中的点 U1 (m + 1),=,意味着((1,indexA)); U1 (m + 1),=,意味着((2,indexA)); U2 (m + 1),=,意味着(B (1, indexB)); U2 (m + 1),=,意味着(B (2, indexB));, %,更新两个聚类中心 结束 图; indexA情节((1),,,(2,indexA),, * b);, %,作出第一类点的图形 于; indexB情节(B (1),,, B (2, indexB),“oy”);, %作出第二类点的图形 于; 时间=centerx [U1(1米),U2(1米)]; 时间=centery [U1(2米),U2(2米)]; 情节(centerx ,, centery,, + g);, %,画出两个聚类中心点 包含(“X”); ylabel (Y); 标题(“聚类之后的数据点”); disp(['迭代的次数为:“,num2str (m)]);
得到的分类结果如下:
, 50个随机生成的点分为两类迭代只需要4步,从上图来看,分类的效果还是不错的。但是每次运行可能分类的结果会不一样,这是因为这些点是随机生成的,而且也没有明确的分类标准的缘故。