原理 :
一个含n个元素的集合D:{x1, x2, …, xn},其中xi = (xi1,xi2,…,xir),即表示每个元素有r个属性(纬度)。kmeans算法就是要将这个集合分成k类,每一类有一个中心,其中k的大小是人为设置的。
kmeans工作流程如下:
- 随意选k个点作为每个类初始的中心点
- 遍历每一个点i,分别计算点i到这k个点的距离,离哪一个点最近就将点i划分成哪一类
- 所有的点都划分完后,求每一类所有点的平均值,作为该类新的中心点
- 然后重复2,3直到中心点不在变化,或者重复2,3到一定次数
优缺点:
优点:简单,高效
缺点:需要人为设置聚类的个数;对一些不规则的分布聚类效果很差;对异常值十分敏感,如下图:
MATLAB实现
链接:https://pan.baidu.com/s/12yO8u1seqvsF5NHd0XwUvA
提取码:o9wm
代码:
[b] = xlsread('aggregate.xlsx',1,'A1:c788');
x = b(:,1);
y = b(:,2);
%c = b(:,3);
data = [x(1:7,1),y(1:7,1)];
%用于记录点到样本的距离
dist = zeros(1,7);
for k = 1:300
%用来记录点被分到那个类中
c = zeros(788,1);
sum = zeros(7,3);
for i = 1:788
for j = 1:7
dist(1,j) = sqrt((x(i,1)-data(j,1))^2+(y(i,1)-data(j,2))^2);
end
[mi,index]=min(dist);
c(i,1) = index;
sum(c(i,1),1)=x(i)+sum(c(i,1),1);
sum(c(i,1),2)=y(i)+sum(c(i,1),2);
sum(c(i,1),3)=sum(c(i,1),3)+1;
end
%重新计算均值
for m = 1:7
data(m,1) = sum(m,1)/sum(m,3);
data(m,2) = sum(m,2)/sum(m,3);
end
end
%画图
for i = 1:788
rand('seed',c(i,1));
color = rand(1,3);
plot(x(i,1),y(i,1),'*','color',color);
hold on;
end