二分kmeans python实现

今天要对一个1000个个记录,每个记录有n个属性的文本进行聚类,采用的是二分k均值方法。

算法思想:

我参考了Pang-Ning Tan数据挖掘导论里P317

相对于kmeans的优点是不受其初始质心的影响。

#coding utf-8#python 3.4#2015-4-3#Fitz Yin  #yinruyi.hm@gmail.comfrom sklearn.cluster import KMeans
import numpy as np

def makedict(f):
    #建立行号和每行数据间的字典关系
    a = [line.split() for line in f]
    data_dict = {}
    for i in range(len(a)):
        data_dict[i] = a[i]
    return data_dict

def kmeans(data):
    #kmeans算法
    data = np.array(data)
    computer=KMeans(n_clusters=2)
    computer.fit(data)
    labels = computer.labels_
    one_class = []
    zero_class = []
    for i in range(len(labels)):
        if labels[i] == 1:
            one_class.append(i)#0类的行号
        else:
            zero_class.append(i)#1类的行号
    centers = computer.cluster_centers_#找到中心
    cohesion_0,cohesion_1 = -1,-1#初始化,自己和自己的cos是1
    for i in zero_class:
        cohesion_0 += judge_cos(data[i],centers[0])#0类cos评价
    for i in one_class:
        cohesion_1 += judge_cos(data[i],centers[1])#1类cos评价
    return zero_class,one_class,cohesion_0,cohesion_1

def judge_cos(x,y):
    #cos评价函数
    af,bf,ab = 0,0,0
    for i in range(len(x)):
        af = float(x[i])*float(x[i])
        bf = float(y[i])*float(y[i])
        ab = float(x[i])*float(y[i])
    if af == 0 or bf == 0:
        print(‘error‘)
        return 0
        #本例中不出现全是0情况
    else:
        cos_value = ab/(np.sqrt(af)*np.sqrt(bf))
        return cos_value

def gettransdict(split_set,split_number):
    #建立kmeans计算的矩阵和原来矩阵 两个行号之间的字典关系
    a = split_set[split_number][0]
    transdict = {}
    for i in range(len(a)):
        transdict[i] = a[i]
    return transdict

def getsplitset(split_set,split_number):
    #簇中去掉要分的簇
    new_split_set = []
    for i in range(len(split_set)):
        if i == split_number:
            pass
        else:
            new_split_set.append(split_set[i])
    return new_split_set

def getsplitnumber(split_set):
    #找寻待分簇的编号
    split_number = 0
    temp = []
    for i in range(len(split_set)):
        temp.append(split_set[i][1])
    for i in range(len(temp)):
        if temp[split_number] > temp[i]:
            split_number = i
    return split_number

def main():
    f = open(‘train.txt‘,‘r‘,encoding=‘utf-8‘).readlines()
    data_dict = makedict(f)
    k = 3#分类个数
    #sse = 0.001
    split_set = [[[i for i in range(1000)],0]]#此处1000是行号
    split_number = 0#需要分类的簇标号
    while len(split_set) != k:
        transdict = gettransdict(split_set,split_number)#转换字典
        array2kmeans = [data_dict[i] for i in split_set[split_number][0]]#获取二分kmeans计算矩阵
        zero_class,one_class,cohesion_0,cohesion_1 = kmeans(array2kmeans)
        real_zero_class = [transdict[i] for i in zero_class]#分裂后的簇0
        real_one_class = [transdict[i] for i in one_class]#分裂后的簇1
        split_set = getsplitset(split_set,split_number)#将总的簇中去掉分的大的簇
        split_set.append([real_zero_class,cohesion_0])
        split_set.append([real_one_class,cohesion_1])#总的簇中加入分完的小簇
        split_number = getsplitnumber(split_set)#获取下一个循环待分的簇编号
    print(split_set)
    #[[[行号1类],sse1],[[行号2类],sse2],[[行号三类],sse3]]
if __name__ == ‘__main__‘:
    main()
时间: 2024-10-25 12:28:16

二分kmeans python实现的相关文章

二分K-means算法

二分K-means聚类(bisecting K-means) 算法优缺点: 由于这个是K-means的改进算法,所以优缺点与之相同. 算法思想: 1.要了解这个首先应该了解K-means算法,可以看这里这个算法的思想是:首先将所有点作为一个簇,然后将该簇一分为二.之后选择能最大程度降低聚类代价函数(也就是误差平方和)的簇划分为两个簇(或者选择最大的簇等,选择方法多种).以此进行下去,直到簇的数目等于用户给定的数目k为止.2.以上隐含着一个原则是:因为聚类的误差平方和能够衡量聚类性能,该值越小表示

机器学习实战ByMatlab(四)二分K-means算法

前面我们在是实现K-means算法的时候,提到了它本身存在的缺陷: 1.可能收敛到局部最小值 2.在大规模数据集上收敛较慢 对于上一篇博文最后说的,当陷入局部最小值的时候,处理方法就是多运行几次K-means算法,然后选择畸变函数J较小的作为最佳聚类结果.这样的说法显然不能让我们接受,我们追求的应该是一次就能给出接近最优的聚类结果. 其实K-means的缺点的根本原因就是:对K个质心的初始选取比较敏感.质心选取得不好很有可能就会陷入局部最小值. 基于以上情况,有人提出了二分K-means算法来解

二分Kmeans的java实现

刚刚研究了Kmeans.Kmeans是一种十分简单的聚类算法.可是他十分依赖于用户最初给定的k值.它无法发现随意形状和大小的簇.最适合于发现球状簇.他的时间复杂度为O(tkn).kmeans算法有两个核心点:计算距离的公式&推断迭代停止的条件.一般距採用欧式距离等能够随意.推断迭代停止的条件能够有: 1) 每一个簇的中心点不再变化则停止迭代 2)全部簇的点与这个簇的中心点的误差平方和(SSE)的全部簇的总和不再变化 3)设定人为的迭代次数.观察实验效果. 当初始簇心选择不好的时候聚类的效果会非常

二分查找——Python实现

一.排序思想 二分(折半)查找思想请参见:https://www.cnblogs.com/luomeng/p/10585291.html 二.python实现 def binarySearchDemo(arr, key): """ python二分查找非递归方式 :param arr:待排序列,有序集合 :param key:带查找元素 """ low = 0 high = len(arr) - 1 while low <= high: m

线性查找与二分查找(python)

# -*- coding: utf-8 -*- number_list = [0, 1, 2, 3, 4, 5, 6, 7] def linear_search(value, iterable): for index, val in enumerate(iterable): if val == value: return index return -1 assert linear_search(5, number_list) == 5 def linear_search_v2(predicate

Kmeans聚类算法及其 Python实现

python Kmeans聚类之后如何给数据贴上聚类的标签? 用了二分Kmeans 来聚类 质心和聚类的簇都得到了,不知道如何给每一条数据贴上具体的标签? 这个链接下的代码,可以作为参考: http://blog.csdn.net/fzch_struggling/article/details/45009097#算法实验 原文地址:https://www.cnblogs.com/eternallql/p/8127403.html

kmeans算法思想及其python实现

第十章 利用k-均值聚类算法对未标注的数据进行分组 一.导语 聚类算法可以看做是一种无监督的分类方法,之所以这么说的原因是它和分类方法的结果相同,区别它的类别没有预先的定义.簇识别是聚类算法中经常使用的一个概念,使用这个概念是为了对聚类的结果进行定义. 聚类算法几乎可以用于所有的对象,并且簇内的对象越相似,效果越好. 二.K-均值聚类算法的基本概念 K-均值聚类算法它的目的是将数据分成k个簇.它的一般过程是如下: 随机的选择k个数据点作为初始的质心 当任意一个簇的分配结果发生变化的情况下 对于每

KMeans聚类算法思想与可视化

1.聚类分析 1.0 概念 聚类分析简称聚类(clustering),是一个把数据集划分成子集的过程,每一个子集是一个簇(cluster),使得簇中的样本彼此相似,但与其他簇中的样本不相似. 聚类分析不需要事先知道样本的类别,甚至不用知道类别个数,因此它是一种无监督的学习算法,一般用于数据探索,比如群组发现和离群点检测,还可以作为其他算法的预处理步骤. 下面的动图展示的是一个聚类过程,感受一下: 1.1 基本聚类方法 主要的聚类算法一般可以划分为以下几类: 方法 一般特点 划分方法 1.发现球形

scikit-learn学习之K-means聚类算法与 Mini Batch K-Means算法

====================================================================== 本系列博客主要参考 Scikit-Learn 官方网站上的每一个算法进行,并进行部分翻译,如有错误,请大家指正 转载请注明出处 ====================================================================== K-means算法分析与Python代码实现请参考之前的两篇博客: <机器学习实战>k