формат scipy linkage

Я написал свою собственную процедуру кластеризации и хотел бы создать дендрограмму. Самый простой способ сделать это – использовать функцию scipy dendrogram. Однако для этого требуется, чтобы вход был в том же формате, что и функция scipy linkage. Я не могу найти пример того, как вывод этого форматируется. Мне было интересно, может ли кто-то там просветить меня.

  • как построить и аннотировать иерархические кластерные дендрограммы в scipy / matplotlib
  • Дендрограмма, созданная scipy-cluster, не показывает
  • 3 Solutions collect form web for “формат scipy linkage”

    Это из документации функции scipy.cluster.hierarchy.linkage () , я думаю, что это довольно четкое описание для выходного формата:

    Возвращается A ( n -1) на 4 матрицы Z. На i-й итерации кластеры с индексами Z [i, 0] и Z [i, 1] объединяются для формирования кластера n + i . Кластер с индексом меньше n соответствует одному из первоначальных наблюдений. Расстояние между кластерами Z [i, 0] и Z [i, 1] задается Z [i, 2]. Четвертое значение Z [i, 3] представляет количество исходных наблюдений во вновь сформированном кластере.

    Вам нужно что-то еще?

    Я согласен с https://stackoverflow.com/users/1167475/mortonjt в том, что документация не полностью объясняет индексацию промежуточных кластеров, в то время как я согласен с https://stackoverflow.com/users/1354844/dkar, что формат в противном случае точно объясняется.

    Используя пример данных из этого вопроса: Учебник для scipy.cluster.hierarchy

    A = np.array([[0.1, 2.5], [1.5, .4 ], [0.3, 1 ], [1 , .8 ], [0.5, 0 ], [0 , 0.5], [0.5, 0.5], [2.7, 2 ], [2.2, 3.1], [3 , 2 ], [3.2, 1.3]]) 

    Матрица связей может быть построена с использованием единственного (т. Е. Ближайших совпадающих точек):

     z = hac.linkage(a, method="single") array([[ 7. , 9. , 0.3 , 2. ], [ 4. , 6. , 0.5 , 2. ], [ 5. , 12. , 0.5 , 3. ], [ 2. , 13. , 0.53851648, 4. ], [ 3. , 14. , 0.58309519, 5. ], [ 1. , 15. , 0.64031242, 6. ], [ 10. , 11. , 0.72801099, 3. ], [ 8. , 17. , 1.2083046 , 4. ], [ 0. , 16. , 1.5132746 , 7. ], [ 18. , 19. , 1.92353841, 11. ]]) 

    Поскольку в документации объясняются кластеры ниже n (здесь: 11), это просто точки данных в исходной матрице A. Промежуточные кластеры, идущие вперёд, индексируются последовательно.

    Таким образом, кластеры 7 и 9 (первое слияние) объединяются в кластер 11, кластеры 4 и 6 в 12. Затем выполняются три линии, объединяющие кластеры 5 (из А) и 12 (из непроявленного промежуточного кластера 12), в результате чего Расстояние внутри кластера (WCD) 0,5. Единственный метод предполагает, что новый WCS равен 0,5, что является расстоянием между A [5] и ближайшей точкой в ​​кластере 12, A [4] и A [6]. Давай проверим:

      In [198]: norm([a[5]-a[4]]) Out[198]: 0.70710678118654757 In [199]: norm([a[5]-a[6]]) Out[199]: 0.5 

    Теперь этот кластер должен быть промежуточным кластером 13, который впоследствии сливается с A [2]. Таким образом, новое расстояние должно быть самым близким между точками A [2] и A [4,5,6].

      In [200]: norm([a[2]-a[4]]) Out[200]: 1.019803902718557 In [201]: norm([a[2]-a[5]]) Out[201]: 0.58309518948452999 In [202]: norm([a[2]-a[6]]) Out[202]: 0.53851648071345048 

    Который, как можно видеть, также проверяет и объясняет промежуточный формат новых кластеров.

    Скупочная документация точна, как отметил dkar … но немного сложно превратить возвращаемые данные в нечто, пригодное для дальнейшего анализа.

    По моему мнению, они должны включать возможность возврата данных в дерево, как структура данных. Следующий код будет проходить через матрицу и построить дерево:

     from scipy.cluster.hierarchy import linkage import numpy as np a = np.random.multivariate_normal([10, 0], [[3, 1], [1, 4]], size=[100,]) b = np.random.multivariate_normal([0, 20], [[3, 1], [1, 4]], size=[50,]) centers = np.concatenate((a, b),) def create_tree(centers): clusters = {} to_merge = linkage(centers, method='single') for i, merge in enumerate(to_merge): if merge[0] <= len(to_merge): # if it is an original point read it from the centers array a = centers[int(merge[0]) - 1] else: # other wise read the cluster that has been created a = clusters[int(merge[0])] if merge[1] <= len(to_merge): b = centers[int(merge[1]) - 1] else: b = clusters[int(merge[1])] # the clusters are 1-indexed by scipy clusters[1 + i + len(to_merge)] = { 'children' : [a, b] } # ^ you could optionally store other info here (eg distances) return clusters print create_tree(centers) 
    Python - лучший язык программирования в мире.