k-Means演算法Matlab實現
阿新 • • 發佈:2019-01-01
clc;
clear;
%讀取資料檔案,生成點矩陣
fileID = fopen('D:\matlabFile\data.txt');
C=textscan(fileID,'%f %f');
fclose(fileID);
%顯示陣列結果
%celldisp(C);
%將cell型別轉換為矩陣型別,這裡只假設原資料為二維屬性,且是二維的座標點
CC_init=cat(2,C{1},C{2});%用來儲存初始載入的值
CC=CC_init;
%獲得物件的數量
num=length(C{1});
%顯示初始分佈圖
%scatter(C{1},C{2},'filled');
%%設定任意k個簇
k=3;
%臨時存放k箇中心點的陣列
C_temp=zeros(k,2);
%判斷所設定的k值是否小於物件的數量
if k<num
%產生隨機的k個整數
randC=randperm(num);
randC=randC(1:k);
%從原陣列中提出這三個點
for i=1:k
C_temp(i,:)=CC(randC(1,i),:);
end
%將原陣列中的這三個點清空
for j=1:k
CC(randC(1,j),:)=zeros(1,2);
end
idZero=find(CC(:,1)==0);
%刪除為零的行
[i1,j1]=find(CC==0);
row=unique(i1);
CC(row,:)=[];
%分配k個二維陣列,用來存放聚類點
%分配行為k的儲存單元
cluster=cell(k,1,1);
%將剔除的三個點加入到對應的三個儲存單元,每個單元的第一行置為0,為了儲存相對應的簇中心
for m=1:k
cluster{m}=cat(1,zeros(1,2),C_temp(m,:));
end
%計算其他點到這k個點的距離,然後分配這些點,第一次遍歷
for ii=1:num-k
%分別計算到三個點的距離
minValue=1000000;%最小值,要根據實際情況設定該值
minNum=-1;%最小值序號
for jj=1:k
if minValue>sqrt((CC(ii,1)-C_temp(jj,1))*(CC(ii,1)-C_temp(jj,1))+(CC(ii,2)-C_temp(jj,2))*(CC(ii,2)-C_temp(jj,2)))
minValue=sqrt((CC(ii,1)-C_temp(jj,1))*(CC(ii,1)-C_temp(jj,1))+(CC(ii,2)-C_temp(jj,2))*(CC(ii,2)-C_temp(jj,2)));
minNum=jj;
end
end
cluster{minNum}=cat(1,cluster{minNum},CC(ii,:));
end
%初次計算簇中心
for n=1:k
c=cluster{n};
c(1,:)=[];
cluster{n}(1,:)=mean(c,1);
end
%下面重複計算簇中心,直到沒有變化為止
flag=1;
count=0;
while flag==1
%將cluster除第一行之外的資料全部清空
for i=1:k
c=cluster{i}(1,:);
cluster{i}=[];
cluster{i}=c;
end
%把所有點重新分簇
for j=1:num
minValue=1000000;%最小值,要根據實際情況設定該值
minNum=-1;%最小值序號
for i=1:k
if minValue>sqrt((CC_init(j,1)-cluster{i}(1,1))*(CC_init(j,1)-cluster{i}(1,1))+(CC_init(j,2)-cluster{i}(1,2))*(CC_init(j,2)-cluster{i}(1,2)))
minValue=sqrt((CC_init(j,1)-cluster{i}(1,1))*(CC_init(j,1)-cluster{i}(1,1))+(CC_init(j,2)-cluster{i}(1,2))*(CC_init(j,2)-cluster{i}(1,2)));
minNum=i;
end
end
cluster{minNum}=cat(1,cluster{minNum},CC_init(j,:));
end
%再次計算簇中心,並與原簇中心進行比較
flag1=1;
for n=1:k
c_base=cluster{n}(1,:);
c=cluster{n};
c(1,:)=[];
cluster{n}(1,:)=mean(c,1);
c_base=c_base-cluster{n}(1,:);
if c_base~=0
flag1=0;
end
end
if flag1==0
flag=1;
else
flag=0;
end
count=count+1;
end
%繪製聚類結果
for i=1:k
scatter(cluster{i}(:,1),cluster{i}(:,2),'filled');
hold on
end
end
clear;
%讀取資料檔案,生成點矩陣
fileID = fopen('D:\matlabFile\data.txt');
C=textscan(fileID,'%f %f');
fclose(fileID);
%顯示陣列結果
%celldisp(C);
%將cell型別轉換為矩陣型別,這裡只假設原資料為二維屬性,且是二維的座標點
CC_init=cat(2,C{1},C{2});%用來儲存初始載入的值
CC=CC_init;
%獲得物件的數量
num=length(C{1});
%顯示初始分佈圖
%scatter(C{1},C{2},'filled');
%%設定任意k個簇
k=3;
%臨時存放k箇中心點的陣列
C_temp=zeros(k,2);
%判斷所設定的k值是否小於物件的數量
if k<num
%產生隨機的k個整數
randC=randperm(num);
randC=randC(1:k);
%從原陣列中提出這三個點
for i=1:k
C_temp(i,:)=CC(randC(1,i),:);
end
%將原陣列中的這三個點清空
for j=1:k
CC(randC(1,j),:)=zeros(1,2);
end
idZero=find(CC(:,1)==0);
%刪除為零的行
[i1,j1]=find(CC==0);
row=unique(i1);
CC(row,:)=[];
%分配k個二維陣列,用來存放聚類點
%分配行為k的儲存單元
cluster=cell(k,1,1);
%將剔除的三個點加入到對應的三個儲存單元,每個單元的第一行置為0,為了儲存相對應的簇中心
for m=1:k
cluster{m}=cat(1,zeros(1,2),C_temp(m,:));
end
%計算其他點到這k個點的距離,然後分配這些點,第一次遍歷
for ii=1:num-k
%分別計算到三個點的距離
minValue=1000000;%最小值,要根據實際情況設定該值
minNum=-1;%最小值序號
for jj=1:k
if minValue>sqrt((CC(ii,1)-C_temp(jj,1))*(CC(ii,1)-C_temp(jj,1))+(CC(ii,2)-C_temp(jj,2))*(CC(ii,2)-C_temp(jj,2)))
minValue=sqrt((CC(ii,1)-C_temp(jj,1))*(CC(ii,1)-C_temp(jj,1))+(CC(ii,2)-C_temp(jj,2))*(CC(ii,2)-C_temp(jj,2)));
minNum=jj;
end
end
cluster{minNum}=cat(1,cluster{minNum},CC(ii,:));
end
%初次計算簇中心
for n=1:k
c=cluster{n};
c(1,:)=[];
cluster{n}(1,:)=mean(c,1);
end
%下面重複計算簇中心,直到沒有變化為止
flag=1;
count=0;
while flag==1
%將cluster除第一行之外的資料全部清空
for i=1:k
c=cluster{i}(1,:);
cluster{i}=[];
cluster{i}=c;
end
%把所有點重新分簇
for j=1:num
minValue=1000000;%最小值,要根據實際情況設定該值
minNum=-1;%最小值序號
for i=1:k
if minValue>sqrt((CC_init(j,1)-cluster{i}(1,1))*(CC_init(j,1)-cluster{i}(1,1))+(CC_init(j,2)-cluster{i}(1,2))*(CC_init(j,2)-cluster{i}(1,2)))
minValue=sqrt((CC_init(j,1)-cluster{i}(1,1))*(CC_init(j,1)-cluster{i}(1,1))+(CC_init(j,2)-cluster{i}(1,2))*(CC_init(j,2)-cluster{i}(1,2)));
minNum=i;
end
end
cluster{minNum}=cat(1,cluster{minNum},CC_init(j,:));
end
%再次計算簇中心,並與原簇中心進行比較
flag1=1;
for n=1:k
c_base=cluster{n}(1,:);
c=cluster{n};
c(1,:)=[];
cluster{n}(1,:)=mean(c,1);
c_base=c_base-cluster{n}(1,:);
if c_base~=0
flag1=0;
end
end
if flag1==0
flag=1;
else
flag=0;
end
count=count+1;
end
%繪製聚類結果
for i=1:k
scatter(cluster{i}(:,1),cluster{i}(:,2),'filled');
hold on
end
end