最近在學習 k-means聚類算法,網上有很多關於用MATLAB對這一算法的實現,下面對這一知識點進行了總結,希望大家可以採納,歡迎留言。
在聚類分析中希望能有一種算法能夠自動的將相同的元素分爲緊密關係的子集或簇。聚類屬於無監督學習中的一種方法,也是一種在許多領域中用於統計數據分析的常用技術。K-means算法是使用的最廣泛的一種算法。
1.算法步驟:
1)首先選擇一些類/組,並隨機初始化它們各自的中心點。中心點是與每個數據點向量長度相同的位置。這就需要我們提前預知類的數量(即中心點的數量)。
2)計算每個數據點到中心點的距離,數據點距離哪個中心點最近就劃分到哪一類中。
3)計算每一類中中心點作爲新的中心點。
4)重複以上步驟,直到每一類中心在每次迭代後變化不大爲止。也可以多次隨機初始化中心點,然後選擇運行結果最好的一個。
2.注意事項:
1)K-means中的K表示簇的個數
2)質心:均值,即向量各維度取平均即可。計算距離是使用歐式距離的計算公式:
3)優化目標:,就是使每個樣本點到簇心的距離的和最小。
優勢:簡單、快速、適合常規數據集。
劣勢:K值難確定,複雜度與樣本呈線性關係。(即樣本越多,計算的越多)
3.用MATLAB實現K-means算法,有三類數據集,設置K=3
clear all;
close all;
clc;
%第一類數據
a=[0 0 ];
S1=[.1 0 ;0 .1];
data1=mvnrnd(a,S1,100); %產生高斯分佈數據
%第二類數據
b=[1.2 1.2 ];
S2=[.1 0 ;0 .1];
data2=mvnrnd(b,S2,100);
% 第三類數據
c=[-1.2 1.2 ];
S3=[.1 0 ;0 .1];
data3=mvnrnd(c,S3,100);
%顯示數據
plot(data1(:,1),data1(:,2),'r+');
hold on;
plot(data2(:,1),data2(:,2),'b*');
plot(data3(:,1),data3(:,2),'go');
grid on;
%三類數據合成一個不帶標號的數據類
data=[data1;data2;data3];
%K-means聚類
N=3;%設置聚類數目
[m,n]=size(data);
re=zeros(m,n+1);
center=zeros(N,n);%初始化聚類中心
re(:,1:n)=data(:,:);
for x=1:N
center(x,:)=data( randi(300,1),:);%第一次隨機產生聚類中心
end
while 1
distence=zeros(1,N);
num=zeros(1,N);
new_center=zeros(N,n);
for x=1:m
for y=1:N
distence(y)=norm(data(x,:)-center(y,:));%計算到每個類的距離
end
[~, temp]=min(distence);%求最小的距離
re(x,n+1)=temp;
end
k=0;
for y=1:N
for x=1:m
if re(x,n+1)==y
new_center(y,:)=new_center(y,:)+re(x,1:n);
num(y)=num(y)+1;
end
end
new_center(y,:)=new_center(y,:)/num(y);
if norm(new_center(y,:)-center(y,:))<0.1
k=k+1;
end
end
if k==N
break;
else
center=new_center;
end
end
[m, n]=size(re);
%最後顯示聚類後的數據
figure;
hold on;
for i=1:m
if re(i,n)==1
plot(re(i,1),re(i,2),'r+');
plot(center(1,1),center(1,2),'ko');
elseif re(i,n)==2
plot(re(i,1),re(i,2),'b*');
plot(center(2,1),center(2,2),'ko');
elseif re(i,n)==3
plot(re(i,1),re(i,2),'go');
plot(center(3,1),center(3,2),'ko');
else
plot(re(i,1),re(i,2),'m*');
plot(center(4,1),center(4,2),'ko');
end
end
grid on
展示如下:
聚類之後:
望可以幫助你們。