用MATLAB做聚類分析時非常有用的自定義距離函式和標準化函式
阿新 • • 發佈:2019-01-07
聚類分析中,經常遇到觀測值缺失的情況.
例如統計歷史降水資料時,某個月的資料缺失了,這時用MATLAB做聚類分析時,
就需要自定義距離函式,處理nan的問題.
下面是相關的MATLAB函式,裡面有例子,可自行修改:
上面這個函式,包括了常用的各種距離函式.function [ nandistance ] = nandistfun( X,Y,varargin) % A distance function for pdist,ignoring NaNs % [ nandistance ] = nandistfun( X,Y,varargin) % arguments : % X: 1-by-n vector % Y:m-by-n vector % nandistance::m-by-1, whose kth element is the distance between X and Y(k,:). % % methods = {'euclidean'; 'seuclidean'; 'cityblock'; 'chebychev'; ... % 'mahalanobis'; 'minkowski'; 'cosine'; 'correlation'; ... % 'spearman'; 'hamming'; 'jaccard'}; % % Example: % >> X =[9, nan, 2, 4, 7; 8, 2, 9, nan, 5; 2, 5, 8, nan, 6]; % >> D = pdist(X,@nandistfun) % >> D= pdist(X,@(a,b)nandistfun(a,b,'seu')) % % See also PDIST, SQUAREFORM, LINKAGE, SILHOUETTE, PDIST2. % %Author:Wu Xuping Date:2013-09-21 Version:1.0.0 [xrow,xcolumn]=size(X); [yrow,ycolumn]=size(Y); %可變引數的個數 nVarargs = length(varargin); %初始化距離 nandistance=zeros(yrow,1); if (xrow==1 && xcolumn==ycolumn) for m=1:yrow x1=X;%必須是行向量,不能是空向量 y1=Y(m,:);%必須是行向量,不能是空向量 b=( ~isnan(x1)) & (~isnan(y1)); %提取(x1,y1)中都不是nan的索引 A=[]; A(1,:)=x1(b);%必須是行向量,不能是空向量 A(2,:)=y1(b);%必須是行向量,不能是空向量 %計算距離 if (nVarargs>0) nandistance(m,1) = pdist(A,varargin{:}); else nandistance(m,1) = pdist(A); %預設'euc' end end end end
看完了這個函式的實現方式,我想大家也可以自定義其它型別的距離函數了.
通常做聚類分析時先將資料標準化,matlab提供了zscore函式,不過不支援nans,
這時可以試試下面的函式:
function [ z ] = nanzscore( x ) %[ z ] = nanzscore( x ),ignoring NaNs % 類似於標準化函式[ z ] = zscore( x ),忽略NaNs % Author:wuxuping,Date:2013-09-21 nm=nanmean(x); ns=nanstd(x); [xrow,xcolumn]=size(x); if ((xrow>1 )&&(xcolumn >1)) %如果是多行多列的矩陣 z=zeros(size(x)); for m=1:xrow for n=1:xcolumn z(m,n) = (x(m,n)- nm(n))./ns(n); end end else %如果是單行或單列的向量 if (xrow==1) for m=1:numel(x) z(m) = (x(m)- nm)./ns;%行向量 end else for m=1:numel(x) z(m,1) = (x(m)- nm)./ns;%列向量 end end end
上面的標準化函式用起來和zscore是一樣的,只是忽略所有的NaNs.
下面給出是一般的聚類分析過程例項:
x=dlmread(filename);%80*51,八十個站點,測量了51次降水量,現在對八十個站點的降水型別進行聚類分析 %即將降水型別相同的站點聚為一類;不同類間的降水型別應該很不相同! x=nanzscore( x );%標準化 %標準化主要是測量值可能為多個專案如降水量和能見度等,而降水量和能見度的數值記錄相差可能太大. %標準化其實就是把各種相差很大的量伸縮到同一個量級上來,否則計算距離時會出現大數吃小數的現象. %如果只有降水量,且採用同樣的單位則無需標準化 D = pdist(x,@nandistfun);%計算距離向量,大小為:(1*3160) %Y = squareform(D,'tomatrix')%格式化距離向量為矩陣,方便檢視 Z=linkage(D,'average');%採用平均距離法計算聚類,獲取分層聚類樹 [H,T] =dendrogram(Z,'colorthreshold','default');%繪製聚類圖,返回影象物件H和聚類表T %size(T)應為80*1 numCluster=numel(H);%分類的總數,如果numCluster為29則表明將80個站點分為29個降水型別 set(H,'LineWidth',2);%將所有類的線條都加粗為2 set(H(5),'LineWidth',5);%將第五類的顏色加粗為5 find(T==5)%顯示屬於第五類的索引值
分層聚類樹圖如下:
剩下的問題是就是如何評價聚類的結果,也就是聚類的結果是否合理?對於合理的聚類,
我們知道同類的相似性一定要大,不同類之間的相似性一定要小.這個同樣也可用距離來度量,當然也有用置信係數或風險係數去度量的.
第一種評價方法:對於第i類,我們計算該類中心的位置,然後該類中的所有站點到中心的距離之和的平均值記為di,
然後對所有的di求平均得dm,認為di平均值最小的聚類中同類之間的相似性是最大的,即為最合理的類.
第二種評價方法:將每一類的中心計算出來,然後將各類中心之間的距離累加,記為DM,所得的結果最大則表明該種聚類中,各類之間的差異是最大的.
第三種評價方法綜合考慮同類相似性和異類的差異性,計算max(DM)/min(dm),該值取最大則表示該聚類是最合理的聚類.這在matlab中使用表象係數來求解即可.