直接聚类法的代码实现

来源:互联网 发布:字符串的排列 java 编辑:程序博客网 时间:2024/06/06 00:30

作者: peghoty 

出处: http://blog.csdn.net/itplus/article/details/10088283 






原来的作者大致介绍了直接聚类法的基本原理,但是没有给出具体的实现代码,我这里测试了一下这种算法,所以实现了一份.代码使用python,按照图中的例子测试了一下,测试通过,算了,没什么难的,文章就标记为转载吧:

"""    目标:    ~~~~~~~~~~~    实现直接聚类算法."""import numpy as np#================辅助函数==================#def get_idx(idx):    ''' 获得下标 '''    x = idx[0][0]    y = idx[1][0]    if y > x:        temp = y        y = x        x = temp    return x, y#=================一些约定=================## 叶子节点是这样的. --> ['leaf', label]# 中心节点是这样的. --> ['cluster', distance, [left tree], [right tree]] distance代表左子树和右子树的距离def get_type(node):    ''' 获取叶子节点的类型 '''    return node[0]def get_label(node):    ''' 获取叶子节点的label '''    assert(get_type(node) == 'leaf')    return node[1]def get_left(node):    ''' 获取左子树 '''    assert(get_type(node) == 'cluster')    return node[2]def get_right(node):    ''' 获取右子树 '''    assert(get_type(node) == 'cluster')    return node[3]def get_distance(node):    ''' 获取距离值 '''    assert(get_type(node) == 'cluster')    return node[1]def make_leaf(label):    ''' 构建叶子节点 '''    return ['leaf', label]def make_cluster(distance, left, right):    ''' 构建中心节点 '''    return ['cluster', distance, left, right]#=================直接聚类=================#def get_leaf_labels(node):    ''' 获取标签的值 '''    # 从node节点出发,遍历叶子节点    node_type = get_type(node)    if node_type == 'leaf':        return [get_label(node)]    elif node_type == 'cluster':        labels = get_leaf_labels(get_left(node))        labels.extend(get_leaf_labels(get_right(node)))        return labelsdef get_classify(distance, node):    ''' 获得分类的数据 '''    node_type = get_type(node)    if node_type == 'leaf':        return [[get_label(node)]]    elif node_type == 'cluster' and get_distance(node) < distance: # 要开始分类了        return [get_leaf_labels(node)]    else:        llabels = get_classify(distance, get_left(node))        rlabels = get_classify(distance, get_right(node))        llabels.extend(rlabels)        return llabelsdef direct_cluster(simi_matrix):    ''' 直接聚类法 '''    # 为了尽量简单,我只用list来构建树    N = len(simi_matrix) # 得到矩阵对应的点的数目    nodes = [make_leaf(label) for label in range(N)] # 构建一堆叶子节点    np.fill_diagonal(simi_matrix, float('Inf')) # 先用最大值填充对角线    root = 0 # 用于记录根节点的下标    while N > 1:        # 然后视图寻找相似度矩阵中最小的那个数的下标        idx = np.where(simi_matrix == simi_matrix.min())        x, y = get_idx(idx) # 得到下标值==> x 和 y 进行了合并        distance = simi_matrix[x][y] # 得到两者的距离        cluster = make_cluster(distance, nodes[x], nodes[y])        nodes[y] = cluster # 更新        root = y # 更新下标值        # 删除x行, y列的元素        simi_matrix[x] = float('Inf')        simi_matrix[:, x] = float('Inf')        N = N - 1    return nodes[root]def test01():    ''' 测试程序是否写得正确 '''    simi_matrix = np.loadtxt(fname='matrix.txt')    simi_matrix = simi_matrix + simi_matrix.T    tree = direct_cluster(simi_matrix)    print(tree)    print(get_classify(4.0, tree))def test02():    ''' 第二个测试函数 '''    simi_matrix = np.array([[0, 1, 2],                            [1, 0, 3],                            [2, 3, 0]], dtype='float')    tree = direct_cluster(simi_matrix)    print(tree)    print(get_classify(4.0, tree))if __name__ == '__main__':    ''' 实际地要来跑一下简单的图像分类 '''    test01()"""    在测试里面通过了."""

当然,那个matrix.txt文件如下:

0000000001.5000000003.12.700000002.11.41.20000005.86.03.64.7000004.74.41.82.91.700005.75.52.94.00.81.00001.30.92.21.25.13.95.0002.61.61.20.54.83.03.31.40
实现还是比较简单的,怎么说呢,这个算法只能说效果还行吧,毕竟仁者见仁智者见智.

0 0