前面介绍了普通的k-均值算法,该算法在初始时随机选取k个点作为初始质点,这种方法的坏处在于,如果一开始选择不当,即使后期有所改善,但对效果依旧会有影响。为了对这一方法进行改进,我们提出一种新的方法:二分k-均值方法。
这种方法是在开始时将所有数据视为同一类,然后对每一聚类:计算它的总误差,再将它分为两类,然后计算分类后的质点和误差。若分类后误差小于分类前误差,则找到分裂后误差最小的那个聚类,将其分裂并更新数据归属。
重复这一过程直到聚类数达到给定k值。我写的代码如下:
#二分K-均值算法
#dataSet:数据集
#k:指定聚类数
#splitFeat:用于分割的特征
def biKmeans(dataSet,k,splitFeat = 0):
m,n = np.shape(dataSet)
#保存数据所属聚类及与所属聚类质点距离的矩阵
inDat = np.mat(np.zeros((m,2)))
#一开始将所有点归为一个聚类,并将数据均值作为该聚类的质点
for i in range(m):
inDat[i][0] = 0
#inDat[i][1] =\
sum = calDis(dataSet[i][:], np.mean(dataSet,axis = 0))
#当前聚类数目
kCheck = 1
#当聚类数少于指定聚类数时,迭代分裂
while kCheck < k:
#当前所有聚类分裂后得到的最小误差
bestErr = np.inf
#作为inDat的引用,保存分类后的数据归属及相应误差,最后更新inDat
bestClu = i