1. 程式人生 > >聚類分析(二)k-means及matlab程式

聚類分析(二)k-means及matlab程式

1.介紹
k-means是一種常見的基於劃分的聚類演算法。劃分方法的基本思想是:給定一個有N個元組或者記錄的資料集,將資料集依據樣本之間的距離進行迭代分裂,劃分為K個簇,其中每個簇至少包含一條實驗資料。
2.k-means原理分析
2.1工作原理
(1)首先,k-means方法從資料集中隨機選擇K個數據中心點,每個點代表初始的聚類中心
在這裡插入圖片描述
(2)計算剩餘各個樣本到每個聚類中心的距離,將每個樣本距離第i個聚類中心的較近的值賦給聚類中心i
在這裡插入圖片描述
分別計算器距離,容易得出隨機聚類中心1離1、2、3最近,隨機聚類中心2離4、5、6最近,隨機聚類中心3離7、8、9最近
(3)重新計算每個聚類中心的值,對K個聚類中心的每個值進行均值劃分,更新K個聚類中心的座標位置
在這裡插入圖片描述


(4)直至K個聚類中心不再變化
示意圖:
在這裡插入圖片描述
本圖轉自:https://blog.csdn.net/Katherine_hsr/article/details/79382249
2.2 K-means演算法設計
輸入:聚類的個數K,資料集,樣本距離計算依據
輸出:K個聚類
演算法處理流程同上工作原理
3.matlab程式 (參考至機器學習周志華第9章)
資料集下載地址:https://download.csdn.net/download/sinat_38648388/10745809
3.1 matlab自主k-means程式設計

%% K-mens方法的matlab實現
%% 資料準備和初始化
clc
clear 
x=[0 0; 1 0; 0 1;1 1;2 1; 1 2; 2 2;3 2;6 6;7 6;8 6;6 7; 7 7;8 7;9 7;7 8;8 8;9 8;8 9;9 9];
z=zeros(2,2);
z1=zeros(2,2);
z=x(1:2,1:2);
%% 尋找聚類中心
while 1
    count=zeros(2,1);
    allsum=zeros(2,2);
    for i=1:20 %對每一個樣本i,計算到2個聚類中心的距離
       temp1=sqrt((z(1,1)-x(i,1)).^2+(z(1,2)-x(i,2)).^2);
       temp2=sqrt((z(2,1)-x(i,1)).^2+(z(2,2)-x(i,2)).^2);
        if(temp1<temp2)
            count(1)=count(1)+1;
            allsum(1,1)=allsum(1,1)+x(i,1);
            allsum(1,2)=allsum(1,2)+x(i,2);
        else
            count(2)=count(2)+1;
            allsum(2,1)=allsum(2,1)+x(i,1);
            allsum(2,2)=allsum(2,2)+x(i,2);
        end
    end
    z1(1,1)=allsum(1,1)/count(1);
    z1(1,2)=allsum(1,2)/count(1);
    z1(2,1)=allsum(2,1)/count(2);
    z1(2,2)=allsum(2,2)/count(2);
    if(z==z1)
        break;
    else
        z=z1;
    end
end
%% 結果顯示
disp(z1);%輸出聚類終須
plot(x(:,1),x(:,2),'k*',...
    'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','k',...
    'MarkerFaceColor',[0.5,0.5,0.5])
hold on
plot(z1(:,1),z1(:,2),'ko',...
        'LineWidth',2,...
    'MarkerSize',10,...
    'MarkerEdgeColor','k',...
    'MarkerFaceColor',[0.5,0.5,0.5])
set(gca,'linewidth',2);
xlabel('特徵x1','fontsize',12);
xlabel('特徵x2','fontsize',12);
title('K-means分類圖','fontsize',12);

3.2matlab k-means整合函式程式設計
matlan中kmeans中的整合函式為kidxs=kmeans(bonds,numClust,‘distance’,dist_k);
其中bonds表示輸入的資料集,numClust表示輸入的類,distance表示選擇樣本聚類依據,型別有
: % methods = {‘euclidean’; ‘seuclidean’; ‘cityblock’; ‘chebychev’; …
% ‘mahalanobis’; ‘minkowski’; ‘cosine’; ‘correlation’; …
% ‘spearman’; ‘hamming’; ‘jaccard’};

%% 匯入資料與資料預處理
clc,clear all,close all
load BondData
settle=floor(date);
%資料預處理
bondData.MaturityN=datenum(bondData.Maturity,'dd-mmm-yyyy');
bondData.settleN=settle * ones(height(bondData),1);
%篩選資料
corp=bondData(bondData.MaturityN > settle &...
    bondData.Type =='Corp' &...
    bondData.Rating >= 'CC'&...
    bondData.YTM < 30 &...
    bondData.YTM >= 0,:);
%設定隨機數生成方式保證結果可重現
rng('default');
%% 探索資料
figure
gscatter(corp.Coupon,corp.YTM,corp.Rating)
set(gca,'linewidth',2);
xlabel('票面利率')
ylabel('到期收益率')
%選擇聚類變數
corp.RatingNum=double(corp.Rating);
bonds=corp{:,{'Coupon','YTM','CurrentYield','RatingNum'}};
%設定類別數量
numClust=3;
%設定用於視覺化聚類效果的變數
VX=[corp.Coupon,double(corp.Rating),corp.YTM];
%% k-means聚類
dist_k='cosine';
kidx=kmeans(bonds,numClust,'distance',dist_k);
%繪製聚類效果圖
%z=VX(kidx(m,n));表示VX的第m個值,聚類出來的第n類
figure
%VX(kidx==m,n)代表VX中第m列,第n類
F1=plot3(VX(kidx==1,1),VX(kidx==1,2),VX(kidx==1,3),'r*',...
    VX(kidx==2,1),VX(kidx==2,2),VX(kidx==2,3),'bo',... 
   VX(kidx==3,1),VX(kidx==3,2),VX(kidx==3,3),'kd' );
set(gca,'linewidth',2);
grid on;
set(F1,'linewidth',2,'MarkerSize',8);
xlabel('票面利率','fontsize',12);
ylabel('評級得分','fontsize',12);
zlabel('到期收益率','fontsize',12);
title('Kmeans方法聚類結果')

%% 評估各類的相關程度
dist_metric_k=pdist(bonds,dist_k);
dd_k=squareform(dist_metric_k);
[~,idx]=sort(kidx);
dd_k=dd_k(idx,idx);
figure
imagesc(dd_k)
set(gca,'linewidth',2);
xlabel('資料點','linewidth',2);
ylabel('資料點','fontsize',12);
title('K-means聚類結果相關程度圖','fontsize',12)
ylabel(colorbar,['距離矩陣:',dist_k])
axis square