1:思想
K-means,屬於無監督學習。即輸入數據沒有標籤y,經過一些算法後,找到標籤y。
聚類的目的就是找到每個樣本潛在的標籤y,並將同類別的樣本放到一起。
而k-means聚類:就是把n個點(可以是樣本的一次觀察或一個實例)劃分到k個聚類中,
使得每個點都屬於離他最近的均值(此即聚類中心)對應的聚類,以之作爲聚類的標準。
2:缺點
1)聚類數量k,需要輸入。選擇不恰當,聚類結果很糟糕。
2)收斂到局部最優解,和直觀想象不一樣,這種可以多此選擇初始點,進行多次實驗,取平均來克服。
3:算法
4:練習程序
clear all;
clc ;
%第一類數據
mu1=[0,0,0]; %%多維高斯向量均值
s1=[0.3 0 0;0 0.35 0;0 0 0.3];%%協方差分佈
data1=mvnrnd(mu1,s1,100); %%產生高斯分佈數據
%第二類數據
mu2=[1.25,1.25,1.25]; %%多維高斯向量均值
s2=[0.3 0 0;0 0.35 0;0 0 0.3];%%協方差分佈
data2=mvnrnd(mu2,s2,100); %%產生高斯分佈數據
%第三類數據
mu3=[-1.25,-1.25,-1.25]; %%多維高斯向量均值
s3=[0.3 0 0;0 0.35 0;0 0 0.3];%%協方差分佈
data3=mvnrnd(mu3,s3,100); %%產生高斯分佈數據
data=[data1;data2;data3]; %%原始數據
%%K-means聚類
[u]=KMeans(data,10); %%%
%%顯示聚類後的數據
figure;
hold on;
plot3(data1(:,1),data1(:,2),data1(:,3),'co');
hold on
plot3(data2(:,1),data2(:,2),data2(:,3),'go');
hold on
plot3(data3(:,1),data3(:,2),data3(:,3),'bo');
hold on
plot3(u(:,1),u(:,2),u(:,3),'r+');
%%%data 數據 N質心數量 u聚類質心位置
function [u]=KMeans(data,N)
[m,n]=size(data); %% m是數據個數
maxtemp=zeros(n);
mintemp=zeros(n);
u=zeros(N,n); %%每一行表示一個質心點
%%%初始化質心點
for i=1:n
maxtemp(i)=max(data(:,i)); %%第一列最大
mintemp(i)=min(data(:,i));
for j=1:N
u(j,i)=maxtemp(i)+(mintemp(i)-maxtemp(i))*rand();
end
end
eps=1;
IndexData=ones(m,1); %%存放質心:每個數據所對應的質心索引
while(eps>0.0001) %%%迭代更新質心位置
pre_u=u;
for i=1:N
for j=1:m
temp(j,i)=norm(data(j,:)-u(i,:)); %%每一個數據與N個質心比較 放到m*N矩陣裏
%%temp每一列表示數據離不同質心的距離
end
end
for row=1:m
[value,Index]=min(temp(row,:)); %%找到每一行的最小值的索引
IndexData(row)=Index; %%把它對應的索引放到IndexData
end
%%%計算新的質心位置
for i=1:N
ZhiXin=zeros(1,3);
Count=0;
for j=1:m
if IndexData(j)==i %%計算索引是i的數據點
ZhiXin=ZhiXin+data(j,:); %%質心的計算按照:所有座標點的平均值
Count=Count+1;
end
end
u(i,:)=ZhiXin/Count;
end
eps=norm(pre_u-u);
end
5:結果
當聚類數量選則3,10的時候結果如下:其中,有的時候質心會不確定,程序沒有做優化處理。