**
K-means算法-JAVA实现
**
从D中随机取k个元素,作为k个簇的各自的中心。
分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
将D中全部元素按照新的中心重新聚类。
重复第4步,直到聚类结果不再变化。
将结果输出。
**
一.编程实现
%% Kmeans算法
% 输入:
% data 输入的不带分类标号的数据
% K 数据一共分多少类
% iniCentriods 自行指定初始聚类中心
% iterations 迭代次数
% 输出:
% Idx 返回的分类标号
% centroids 每一类的中心
% Distance 类内总距离
function [Idx,centroids,Distance]=KMeans(data,K,iniCentriods,iterations)
[numOfData,numOfAttr]=size(data); % numOfData是数据个数,numOfAttr是数据维数
centroids=iniCentriods;
%% 迭代
for iter=1:iterations
pre_centroids=centroids;% 上一次求得的中心位置
tags=zeros(numOfData,K);
%% 寻找最近中心,更新中心
for i=1:numOfData
D=zeros(1,K);% 每个数据点与每个聚类中心的标准差
Dist=D;
% 计算每个点到每个中心点的标准差
for j=1:K
Dist(j)=norm(data(i,:)-centroids(j,:),2);
end
[minDistance,index]=min(Dist);% 寻找距离最小的类别索引
tags(i,index)=1;% 标记最小距离所处的位置(类别)
end
%% 取均值更新聚类中心点
for i=1:K
if sum(tags(:,i))~=0
% 未出现空类,计算均值作为下一聚类中心
for j=1:numOfAttr
centroids(i,j)=sum(tags(:,i).*data(:,j))/sum(tags(:,i));
end
else % 如果出现空类,从数据集中随机选中一个点作为中心
randidx = randperm(size(data, 1));
centroids(i,:) = data(randidx(1),:);
tags(randidx,:)=0;
tags(randidx,i)=1;
end
end
if sum(norm(pre_centroids-centroids,2))<0.001 % 不断迭代直到位置不再变化
break;
end
end
%% 计算输出结果
Distance=zeros(numOfData,1);
Idx=zeros(numOfData,1);
for i=1:numOfData
D=zeros(1,K);% 每个数据点与每个聚类中心的标准差
Dist=D;
% 计算每个点到每个中心点的标准差
for j=1:K
Dist(j)=norm(data(i,:)-centroids(j,:),2);
end
[distance,idx]=min(Dist);% 寻找距离最小的类别索引
distance=Dist(idx);
Distance(i)=distance;
Idx(i)=idx;
end
Distance=sum(Distance,1);% 计算类内总距离
end
**
二.聚类结果评价
clear
data=load(‘Iris.txt’);
data=data(:,2:end);
matrix=[5.9016,2.7484,4.3935,1.4339;6.8500,3.0737,5.7421,2.0711;5.0060,3.4280,1.4620,0.2460];
[Idx,C,distance]=KMeans(data,3,matrix,500);
Distance=sum(distance)
c1=Idx(1:50,1);c2=Idx(51:100,1);c3=Idx(101:150,1);
accuracy=(sum(c1=mode(Idx(1:50,1)))+sum(c2=mode(Idx(51:100,1)))+sum(c3==mode(Idx(101:150,1))))/150
**
三.类簇中心点的选取
clear
data=load(‘Iris.txt’);
data=data(:,2:end);
K=3;
%% 产生随机初始点
[numOfData,numOfAttr]=size(data); % numOfData是数据个数,numOfAttr是数据维数
centroids=zeros(K,numOfAttr); % 随机初始化,最终迭代到每一类的中心位置
maxAttr=zeros(numOfAttr); % 每一维最大的数
minAttr=zeros(numOfAttr); % 每一维最小的数
for i=1:numOfAttr
maxAttr(i)=max(data(:,i)); % 每一维最大的数
minAttr(i)=min(data(:,i)); % 每一维最小的数
for j=1:K
centroids(j,i)=maxAttr(i)+(minAttr(i)-maxAttr(i))*rand(); % 随机初始化,选取每一维[min max]中初始化
end
end
[Idx,C,distance]=KMeans(data,K,centroids,500);% 调用KMeans
Distance=sum(distance)% 计算类内距离之和
%% 计算准确率
c1=Idx(1:50,1);c2=Idx(51:100,1);c3=Idx(101:150,1);
Accuracy=(sum(c1=mode(Idx(1:50,1)))+sum(c2=mode(Idx(51:100,1)))+sum(c3==mode(Idx(101:150,1))))/numOfData