原理とpythonの階層的クラスタリングアルゴリズムの実装

アルゴリズムのI.はじめに

主流のクラスタリングアルゴリズムはおおよそ階層的クラスタリングアルゴリズムに分けることができ、クラスタリングアルゴリズムは、式を分割する(グラフ理論、KMEAN)、密度ベースのクラスタリングアルゴリズム(DBSCAN)とグリッドと他のクラスタリングアルゴリズム。

1.1基本概念

  1. 階層的クラスタリング(階層的クラスタリング)は一種のネストされた階層的クラスタリングツリー内のデータ点の異なるカテゴリ間の類似度を計算することにより作成したクラスタリングアルゴリズムは、。クラスタリングツリーで、生データ点の異なるタイプは、ツリーの最下位層である、木の上部には、クラスタのルートノードです。

  2. ボトムアップのマージ、上から下への分割:クラスタリングツリーを作成します。(ここでは最初のものです)

1.2階層的クラスタリングアルゴリズムの合併

階層的クラスタリングアルゴリズムデータポイントの2種類の二つの最も類似したデータポイント、反復プロセス内のすべてのデータポイントの組み合わせの間の類似度を計算することにより合成。簡潔に述べると組み合わさ階層的クラスタリングアルゴリズムは、各データ点の間の距離とそれらの間の類似性のすべてのデータポイントのカテゴリ、距離が小さいほど、高い類似度を計算することによって決定されます。そして、データポイントまたは二つのカテゴリー最寄りのクラスタリングツリーを生成するために組み合わせます。次のように統合プロセスは、次のとおりです。

  1. 我々は得ることができ、距離行列X、表す呼ばれる距離データ点と点との間の距離各データ点は言及されている取得するために、距離データ点を組み合わせる最小になり、データ点の組み合わせを、と呼ばれるG
  2. データ点と結合されたデータ点間距離:計算Gを、そして距離のときに計算される必要がある、およびGの各点の距離を。
  3. データ点の組み合わせを有するデータポイントの組み合わせ主:距離シングルリンケージ、完全連結及び平均リンケージ3。3つのアルゴリズムは、以下で説明するから撮影します

    リンケージシングル
    シングルリンケージ計算方法は、2つのデータの組み合わせは、これら2つのデータポイントの組み合わせの距離ように、2つの最も近いデータポイント間の距離を指しています。この方法では、極端な値の影響を受けやすいです。同様の組成物は、2つのデータポイントは、これらの端点のいずれかに起因する可能性がある近く一緒にグループ化されたデータになっています。

    完全リンケージ
    計算シングルリンケージでコントラスト、2つのデータポイントデータから、これらの2つのデータポイントの組み合わせとして最も離れた2点間の距離の組み合わせへの完全な結合方法。また、完全なリンケージの問題シングルリンケージでコントラストは、2つの異なるデータポイントの組み合わせが一緒に遠くすることができない極端な値に起因し得ます。

    平均リンケージ
    計算平均リンケージは、各データポイントは、他のすべてのデータ点からの距離を計算し2つのデータポイントの組み合わせです。データを組み合わせた2点間の距離のようなすべての距離の平均値。この方法は、計算集約的であるが、結果は最初の2つの方法よりも合理的です。
   

二、Pythonの実現

これは、直接scipy.cluster.hierarchy.linkage使用することができます!

次のコードは、階層的クラスタリングのための番号のセットを達成することです。

# -*- coding: utf-8 -*-
import numpy as np
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
from matplotlib import pyplot as plt

def hierarchy_cluster(data, method='average', threshold=5.0):
    '''层次聚类
    
    Arguments:
        data [[0, float, ...], [float, 0, ...]] -- 文档 i 和文档 j 的距离
    
    Keyword Arguments:
        method {str} -- [linkage的方式: single、complete、average、centroid、median、ward] (default: {'average'})
        threshold {float} -- 聚类簇之间的距离

    Return:
        cluster_number int -- 聚类个数
        cluster [[idx1, idx2,..], [idx3]] -- 每一类下的索引
    '''
    data = np.array(data)

    Z = linkage(data, method=method)
    cluster_assignments = fcluster(Z, threshold, criterion='distance')
    print type(cluster_assignments)
    num_clusters = cluster_assignments.max()
    indices = get_cluster_indices(cluster_assignments)

    return num_clusters, indices



def get_cluster_indices(cluster_assignments):
    '''映射每一类至原数据索引
    
    Arguments:
        cluster_assignments 层次聚类后的结果
    
    Returns:
        [[idx1, idx2,..], [idx3]] -- 每一类下的索引
    '''
    n = cluster_assignments.max()
    indices = []
    for cluster_number in range(1, n + 1):
        indices.append(np.where(cluster_assignments == cluster_number)[0])
    
    return indices


if __name__ == '__main__':
    

    arr = [[0., 21.6, 22.6, 63.9, 65.1, 17.7, 99.2],
    [21.6, 0., 1., 42.3, 43.5, 3.9, 77.6],
    [22.6, 1., 0, 41.3, 42.5, 4.9, 76.6],
    [63.9, 42.3, 41.3, 0., 1.2, 46.2, 35.3],
    [65.1, 43.5, 42.5, 1.2, 0., 47.4, 34.1],
    [17.7, 3.9, 4.9, 46.2, 47.4, 0, 81.5],
    [99.2, 77.6, 76.6, 35.3, 34.1, 81.5, 0.]]

    arr = np.array(arr)
    r, c = arr.shape
    for i in xrange(r):
        for j in xrange(i, c):
            if arr[i][j] != arr[j][i]:
                arr[i][j] = arr[j][i]
    for i in xrange(r):
        for j in xrange(i, c):
            if arr[i][j] != arr[j][i]:
                print(arr[i][j], arr[j][i])

    num_clusters, indices = hierarchy_cluster(arr)


    print "%d clusters" % num_clusters
    for k, ind in enumerate(indices):
        print "cluster", k + 1, "is", ind
## 运行结果
5 clusters
cluster 1 is [1 2]
cluster 2 is [5]
cluster 3 is [0]
cluster 4 is [3 4]
cluster 5 is [6]

結果の可視化:






发布了120 篇原创文章 · 获赞 35 · 访问量 17万+

おすすめ

転載: blog.csdn.net/u012328476/article/details/78978113