基礎演算法(二):Kmeans聚類演算法的基本原理與應用
阿新 • • 發佈:2019-01-04
Kmeans聚類演算法的基本原理與應用
內容說明:主要介紹Kmeans聚類演算法的數學原理,並使用matlab程式設計實現Kmeans的簡單應用,不對之處還望指正。
一、Kmeans數學原理
以往的迴歸分類、樸素貝葉斯分類、SVM分類的樣本的標籤(類別)是已知的,通過大量的訓練樣本訓練得到模型,然後判斷新的樣本所屬已知類別中的哪一類。而Kmeans聚類屬於無監督學習,樣本所屬的類別是未知的,只是根據特徵將樣本分類,且類別空間也是根據需要人為選定的。
Kmeans核心思想:最小化所有樣本到所屬類別中心的歐式距離和,採用迭代的方式實現收斂。
為了將J調整到最小,假設當前情況下J沒有達到最小,那麼可以通過固定每一個類別的中心u,調整每一個樣本的所屬類別c來減小J,也可以通過固定每一個樣本的所屬類別c,調整類別中心來減小J的值。理論上,可以有多組u,c值使得J最小,但實際應用中一般出現較少。
J為非凸函式,所以最後收斂的點有可能是全域性最優,也有可能是區域性最優,說明Kmeans對初始條件比較敏感,可多次給定不同的初始條件計算J值,最後選擇最小的那一組作為最終的結果。下圖為不斷迭代至收斂的過程圖。
二、Kmeans聚類的matlab實現
下面的程式碼主要來自參考資料,只是將三維資料改成二維資料,可以將二維訓練資料類比為學生的語文和數學的成績,通過聚類將300名學生按照成績分別ABC三類,三維資料對應著可以類比為學生的語數外成績。
matlab程式碼實現:
kmeans_test.m
KMeans.mclear close all clc %% 採用隨機函式的方法產生訓練資料 %第一類資料 mu1=[0 0]; %均值 S1=[0.3 0;0 0.35]; %協方差 data1=mvnrnd(mu1,S1,100); %產生高斯分佈資料 %%第二類資料 mu2=[1.25 1.25]; S2=[0.3 0;0 0.35]; data2=mvnrnd(mu2,S2,100); %第三個類資料 mu3=[1.25 -1.25]; S3=[0.3 0;0 0.35]; data3=mvnrnd(mu3,S3,100); %% 顯示訓練資料 plot(data1(:,1),data1(:,2),'+'); hold on; plot(data2(:,1),data2(:,2),'r+'); plot(data3(:,1),data3(:,2),'g+'); grid on; %三類資料合成一個不帶標號的資料類 data=[data1;data2;data3]; %這裡的data是不帶標號的 %k-means聚類 [u re]=KMeans(data,3); %最後產生帶標號的資料,標號在所有資料的最後,意思就是資料再加一維度 [m n]=size(re); %% 最後顯示聚類後的資料 figure; hold on; for i=1:m if re(i,3)==1 plot(re(i,1),re(i,2),'ro'); elseif re(i,3)==2 plot(re(i,1),re(i,2),'go'); else plot(re(i,1),re(i,2),'bo'); end end plot(u(:,1),u(:,2),'k+'); grid on;
%N是資料一共分多少類
%data是輸入的不帶分類標號的資料
%u是每一類的中心
%re是返回的帶分類標號的資料
function [u re]=KMeans(data,N)
[m n]=size(data); %m是資料個數,n是資料維數
ma=zeros(n); %每一維最大的數
mi=zeros(n); %每一維最小的數
u=zeros(N,n); %隨機初始化,最終迭代到每一類的中心位置
for i=1:n
ma(i)=max(data(:,i)); %每一維最大的數
mi(i)=min(data(:,i)); %每一維最小的數
for j=1:N
u(j,i)=ma(i)+(mi(i)-ma(i))*rand(); %隨機初始化,不過還是在每一維[min max]中初始化好些
end
end
while 1
pre_u=u; %上一次求得的中心位置
for i=1:N
tmp{i}=[]; % 公式一中的x(i)-uj,為公式一實現做準備
for j=1:m
tmp{i}=[tmp{i};data(j,:)-u(i,:)];
end
end
quan=zeros(m,N);
for i=1:m %計算每一個樣本i所屬的類別
c=[];
for j=1:N
c=[c norm(tmp{j}(i,:))];
end
[junk index]=min(c);
quan(i,index)=norm(tmp{index}(i,:));
end
for i=1:N %更新類別變化後的類別中心位置
for j=1:n
u(i,j)=sum(quan(:,i).*data(:,j))/sum(quan(:,i));
end
end
if norm(pre_u-u)<0.1 %不斷迭代直到位置不再變化或變化極小
break;
end
end
re=[];
for i=1:m
tmp=[];
for j=1:N
tmp=[tmp norm(data(i,:)-u(j,:))];
end
[junk index]=min(tmp);
re=[re;data(i,:) index];
end
end
執行結果如下,這是按照高斯分佈產生的3*100個二維的訓練資料,可以根據需要替換訓練資料。
這是Kmeans聚類之後的資料,每種顏色對應著一個類別,中心的黑色十字叉為類別中心。
三、Kmeans演算法的實際應用
Kmeans演算法的應用很多,後期會根據自己碰到的具體應用不斷更新。若有錯誤之處,還望不吝指出,謝謝。