本文依据《数据挖掘概念与技术》中的概率层次聚类算法而来,但与其略有不同。概率层次聚类是利用概率模型来度量簇之间的距离,本质是实现簇之间的合并。本算法需要一个前提条件,数据集被事先分为一些簇,并且没有单个点簇的情况,同时,数据是符合正太分布的。另外,与原书不同的是,本文增加了一个参数:簇合并门限。
算法的伪代码如下:
设定簇合并门限th
计算所有簇的最大似然值PC
while 1 寻找可以合并的簇,直到没有为止
for i 遍历现有的簇C
计算第i个簇与其他簇之间的距离temp
end
if temp中的最小距离小于门限th
合并第i与最小距离的簇
重新计算i的最大似然PC(i),并做开方
end
end
本算法的Matlab实现程序为:
clc;
clear;
%加载测试数据文件
fileID = fopen('D:\matlabFile\PHC\PHC.txt');
DS=textscan(fileID,'%f %f ');
fclose(fileID);
%元组类型,为每一个对象创建一个簇
C=cell(length(DS{1,1}),1);
for i=1:length(DS{1,1})
C{i,1}=[DS{1,1}(i),DS{1,2}(i)];
end
%设定簇合并门限
th=1;
%计算每一个簇的最大似然值
PC=zeros(1,1);
for i=1:size(C,1)
PC(i)=CalcMLE(C{i,1});
end
%合并满足条件的簇
while 1
%遍历寻找两个簇,如满足条件就合并
Row=size(C,1);
if Row==1
break;
end
for i=1:Row-1
temp=zeros(Row-i,1);
for j=i+1:Row
%合并第i和第j个簇,形成临时簇
C_temp=cat(2,C{i,1},C{j,1});
%计算合并后的临时簇的最大似然值
PCij=CalcMLE(C_temp);
temp(j-i)=abs(log(PCij/(PC(i)*PC(j))));
end
if min(temp)<th
%寻找最大值的下标
index=find(temp==min(temp));
%合并簇
C{i,1}=cat(2,C{i,1},C{i+index,1});
%计算合并后的簇的最大似然,并作开方处理
PC(i)=sqrt(CalcMLE(C{i,1}));
%删除被合并的簇和最大似然
C(i+index,:)=[];
PC(i+index)=[];
break;
end
end
%循环结束
if i==Row-1
break;
end
end
CalcMLE函数的实现如下:
function P=CalcMLE(X)
%利用系统函数计算均值和方差
Phat=mle(X);
%计算最大似然值
P=1;
for i=1:length(X)
P=P*exp(-(X(i)-Phat(1))^2/(2*Phat(2)^2))/sqrt(2*pi*Phat(2)^2);
end
end
实验数据文件为,请复制后保存为txt格式:
-2.01 -1.9
-1.8 -1.93
5.01 4.9
5.4 5.32
5.44 5.35