K-means算法-JAVA实现

**

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值