昨天開始看聚類方法,結果纔看到第一個K-means聚類方法就卡殼了。我先大體瞭解了K-means聚類方法的原理,而後照着老師的代碼逐步實現,就在使用kmeans函數進行聚類時,命令窗口報出了「KMEANS does not accept complex data.」的錯誤,百度也沒有查詢到相關的解決辦法。本身先後經歷了反覆看原理以及kmeans函數的使用方法,但也沒什麼進展。直到後面忽然想起看報告的錯誤的源代碼,不到五分鐘解決了問題。如下爲解決方案:數組
(1)命令窗口報出「錯誤使用 kmeans (line 159) KMEANS does not accept complex data.」錯誤,點擊「line 159」,顯示爲如下錯誤,意思是參數類型不匹配。函數
(2)個人kmeans聚類的那兩行代碼是:spa
bonds = corp(:,{'Coupon','YTM','CurrentYield','RatingNum'});%取出含有'Coupon','YTM','CurrentYield','RatingNum'的列 kidx = kmeans(bonds,numClust,'distance',dist_k);
經過在命令窗口輸入「class(bonds)」發現居然是table類型,確定不能識別啊,因而我使用table2array()函數將其改爲了數組類型,一切問題迎刃而解。code
改後的代碼是:orm
bonds = corp(:,{'Coupon','YTM','CurrentYield','RatingNum'});%取出含有'Coupon','YTM','CurrentYield','RatingNum'的列 % bonds = table2array(bonds); %%%%%!!!!!!!注意:!!!!!! %%%%%問題就在這,必須將以前table類型的bonds轉化爲array類型 %%%%%不然將會報「KMEANS does not accept complex data.」這樣的錯誤 %設置類別數量 kidx = kmeans(bonds,numClust,'distance',dist_k);
(3)經過這個問題,才領悟到一種新的改錯方式,就是查看錯誤報告。看來是以前老師教授的知識沒有吸取啊,只有遇到問題經過不斷嘗試纔可以真正學會。blog
下面介紹一下這個K-means聚類MATLAB實例:it
【題目背景】io
下面是MATLAB源代碼介紹:table
(1)導入數據和預處理數據form
1 load 'BondData.mat'; 2 settle = floor(date);%floor朝無窮大方向取整 3 %數據預處理 4 bondData.MaturityN = datenum(bondData.Maturity,'dd-mmm-yyyy');%將時間化爲數值 5 bondData.SettleN = settle*ones(height(bondData),1); 6 %篩選數據 7 corp = bondData(bondData.MaturityN>settle&... 8 bondData.Type == 'Corp'&... 9 bondData.Rating >='CC'&... 10 bondData.YTM<30&... 11 bondData.YTM>=0,:); 12 %設置隨機數生成方式,保證結果可重現 13 rng('default');
(2)探索數據
1 figure 2 gscatter(corp.Coupon,corp.YTM,corp.Rating) 3 set(gca,'lineWidth',2); 4 xlabel('票面利率') 5 ylabel('到期收益率') 6 %選擇聚類變量 7 corp.RatingNum = double(corp.Rating); 8 bonds = corp(:,{'Coupon','YTM','CurrentYield','RatingNum'});%取出含有'Coupon','YTM','CurrentYield','RatingNum'的列 9 bonds = table2array(bonds);%!!!!!!!! 10 %%%%%!!!!!!!注意:!!!!!! 11 %%%%%問題就在這,必須將以前table類型的bonds轉化爲array類型 12 %%%%%不然將會報「KMEANS does not accept complex data.」這樣的錯誤 13 %設置類別數量 14 numClust = 3; 15 %設置用於可視化聚類效果的變量 16 VX = [corp.Coupon,double(corp.Rating),corp.YTM];
(3)K-means聚類
1 dist_k = 'cosine'; 2 kidx = kmeans(bonds,numClust,'distance',dist_k); 3 %繪製聚類效果圖 4 figure 5 F1 = plot3(VX(kidx==1,1),VX(kidx==1,2),VX(kidx==1,3),'r*',... 6 VX(kidx==2,1),VX(kidx==2,2),VX(kidx==2,3),'bo',... 7 VX(kidx==3,1),VX(kidx==3,3),VX(kidx==3,3),'kd'); 8 set(gca,'lineWidth',2); 9 grid on; 10 set(F1,'lineWidth',2); 11 xlabel('票面利率','fontsize',12); 12 ylabel('評級得分','fontsize',12); 13 ylabel('到期收益率','fontsize',12); 14 title('K-means聚類') 15 %評估各種別的相關程度 16 dist_metric_k = pdist(bonds,dist_k); 17 dd_k = squareform(dist_metric_k); 18 [~,idx] = sort(kidx); 19 dd_k = dd_k(idx,idx); 20 figure 21 imagesc(dd_k) 22 set(gca,'linewidth',2); 23 xlabel('數據點','fontsize',12) 24 ylabel('數據點','fontsize',12) 25 title('K-means聚類結果相關程度圖','fontsize',12); 26 ylabel(colorbar,['距離矩陣:',dist_k]) 27 axis square
運行結果圖以下:
figure1:
figure2:
figure3:
本題中,還遇到了一個小問題,MATLAB沒法識別「Figure」,繪圖應爲「figure」,可對其進行編號,不編號則是會緊接着新彈出一個繪圖界面。