[python] scipy / matplotlib에서 계층 적 클러스터링 멍멍 막을 플로팅하고 주석을 달는 방법



0 Answers

나는 당신이 사용하려고하는 함수의 사용에 관해서 몇 가지 오해가 있다고 생각한다. 저의 요점을 설명하기 위해 완전히 작동하는 코드 스 니펫은 다음과 같습니다.

import matplotlib.pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage
from numpy import array
import numpy as np


mat = array([184, 222, 177, 216, 231,
             45, 123, 128, 200,
             129, 121, 203,
             46, 83,
             83])

dist_mat = mat

linkage_matrix = linkage(dist_mat, 'single')
print linkage_matrix

plt.figure(101)
plt.subplot(1, 2, 1)
plt.title("ascending")
dendrogram(linkage_matrix,
           color_threshold=1,
           truncate_mode='lastp',
           labels=array(['a', 'b', 'c', 'd', 'e', 'f']),
           distance_sort='ascending')

plt.subplot(1, 2, 2)
plt.title("descending")
dendrogram(linkage_matrix,
           color_threshold=1,
           truncate_mode='lastp',
           labels=array(['a', 'b', 'c', 'd', 'e', 'f']),
           distance_sort='descending')


def make_fake_data():
    amp = 1000.
    x = []
    y = []
    for i in range(0, 10):
        s = 20
        x.append(np.random.normal(30, s))
        y.append(np.random.normal(30, s))
    for i in range(0, 20):
        s = 2
        x.append(np.random.normal(150, s))
        y.append(np.random.normal(150, s))
    for i in range(0, 10):
        s = 5
        x.append(np.random.normal(-20, s))
        y.append(np.random.normal(50, s))

    plt.figure(1)
    plt.title('fake data')
    plt.scatter(x, y)

    d = []
    for i in range(len(x) - 1):
        for j in range(i+1, len(x) - 1):
            d.append(np.sqrt(((x[i]-x[j])**2 + (y[i]-y[j])**2)))
    return d

mat = make_fake_data()


plt.figure(102)
plt.title("Three Clusters")

linkage_matrix = linkage(mat, 'single')
print "three clusters"
print linkage_matrix

dendrogram(linkage_matrix,
           truncate_mode='lastp',
           color_threshold=1,
           show_leaf_counts=True)

plt.show()

우선, 모든 고유 쌍 사이의 상대 거리를 기본적으로 설명하는 거리 행렬이 특정 경우에 변경되지 않았으므로 m -> m - 1 계산은 실제로 결과를 변경하지 않았습니다. (위의 예제 코드에서는 모든 거리가 유클리드 거리이므로 모두 2 차원 평면의 점에서 양의 값을 유지합니다.)

두 번째 질문의 경우 dendromgram이 기본적으로 지원한다고 생각하지 않기 때문에 자신이 원하는 것을 수행하기 위해 자신의 주석 루틴을 준비해야 할 것입니다.

마지막 질문의 경우 show_leaf_counts는 truncate_mode = 'lastp'옵션을 사용하여 비 싱글 톤 리프 노드를 표시하려고 할 때만 작동하는 것 같습니다. 근본적으로 잎은 가까이에 모여있어보기가 쉽지 않습니다. 따라서 리프를 표시하는 옵션이 있지만 리프에 몇 개가 모여 있는지 (괄호 안에) 표시하는 옵션이 있습니다.

희망이 도움이됩니다.

Question

scipy 에서 dendrogram 을 사용하여 matplotlib 를 사용하여 계층 적 클러스터링을 다음과 같이 플롯합니다.

mat = array([[1, 0.5, 0.9],
             [0.5, 1, -0.5],
             [0.9, -0.5, 1]])
plt.subplot(1,2,1)
plt.title("mat")
dist_mat = mat
linkage_matrix = linkage(dist_mat,
                         "single")
print "linkage2:"
print linkage(1-dist_mat, "single")
dendrogram(linkage_matrix,
           color_threshold=1,
           labels=["a", "b", "c"],
           show_leaf_counts=True)
plt.subplot(1,2,2)
plt.title("1 - mat")
dist_mat = 1 - mat
linkage_matrix = linkage(dist_mat,
                         "single")
dendrogram(linkage_matrix,
           color_threshold=1,
           labels=["a", "b", "c"],
           show_leaf_counts=True)

제 질문은 : 첫째, mat1-mat mat 가 왜 똑같은 클러스터링을 제공합니까? 두 번째로, 노드의 쌍 사이의 거리를 비교할 수 있도록 dendrogram 사용하여 트리의 각 분기를 따라 거리에 주석을 달 수 있습니까?

마지막으로 show_leaf_counts 플래그가 무시 된 것 같습니다. 각 클래스의 객체 수가 표시되도록 설정하는 방법이 있습니까? 감사.




Related