Изменение порядка элементов матрицы для отражения кластеризации столбцов и строк в наивном Python

StackOverflow https://stackoverflow.com/questions/2455761

Вопрос

Я ищу способ выполнить кластеризацию отдельно по строкам матрицы, а затем по ее столбцам, изменить порядок данных в матрице, чтобы отразить кластеризацию, и собрать все это вместе.Проблема кластеризации легко разрешима, как и создание дендрограммы (например, в этот блог или в «Программирование коллективного разума»).Однако как переупорядочить данные для меня остается неясным.

В конце концов, я ищу способ создания графиков, подобных приведенному ниже, с использованием наивного Python (с любой «стандартной» библиотекой, такой как numpy, matplotlib и т. д., но без используя Р или другие внешние инструменты).

dendogram
(источник: warwick.ac.uk)

Разъяснения

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

Это было полезно?

Решение

Смотри мой недавний ответ, частично скопировано ниже, чтобы этот связанный вопрос.

import scipy
import pylab
import scipy.cluster.hierarchy as sch

# Generate features and distance matrix.
x = scipy.rand(40)
D = scipy.zeros([40,40])
for i in range(40):
    for j in range(40):
        D[i,j] = abs(x[i] - x[j])

# Compute and plot dendrogram.
fig = pylab.figure()
axdendro = fig.add_axes([0.09,0.1,0.2,0.8])
Y = sch.linkage(D, method='centroid')
Z = sch.dendrogram(Y, orientation='right')
axdendro.set_xticks([])
axdendro.set_yticks([])

# Plot distance matrix.
axmatrix = fig.add_axes([0.3,0.1,0.6,0.8])
index = Z['leaves']
D = D[index,:]
D = D[:,index]
im = axmatrix.matshow(D, aspect='auto', origin='lower')
axmatrix.set_xticks([])
axmatrix.set_yticks([])

# Plot colorbar.
axcolor = fig.add_axes([0.91,0.1,0.02,0.8])
pylab.colorbar(im, cax=axcolor)

# Display and save figure.
fig.show()
fig.savefig('dendrogram.png')

Dendrogram and distance matrix
(источник: stevetjoa.com)

Другие советы

Я не совсем понимаю, но, похоже, вы пытаетесь переиндексировать каждую ось массива на основе типов индексов дендрограммы.Я предполагаю, что это предполагает наличие некоторой сравнительной логики в разграничении каждой ветви.Если это так, то будет ли это работать (?):

>>> x_idxs = [(0,1,0,0),(0,1,1,1),(0,1,1),(0,0,1),(1,1,1,1),(0,0,0,0)]
>>> y_idxs = [(1,1),(0,1),(1,0),(0,0)]
>>> a = np.random.random((len(x_idxs),len(y_idxs)))
>>> x_idxs2, xi = zip(*sorted(zip(x_idxs,range(len(x_idxs)))))
>>> y_idxs2, yi = zip(*sorted(zip(y_idxs,range(len(y_idxs)))))
>>> a2 = a[xi,:][:,yi]

x_idxs и y_idxs – показатели дендрограммы. a это несортированная матрица. xi и yi ваши новые индексы массива строк/столбцов. a2 это отсортированная матрица, а x_idxs2 и y_idxs2 — это новые отсортированные индексы дендрограммы.Это предполагает, что при создании дендрограммы 0 столбец/строка ветки всегда сравнительно больше/меньше, чем 1 ветвь.

Если ваши y_idxs и x_idxs не являются списками, а являются массивами, вы можете использовать np.argsort аналогичным образом.

Я знаю, что это очень поздно для игры, но я создал объект построения на основе кода из сообщения на этой странице.Он зарегистрирован на pip, поэтому для установки вам просто нужно позвонить

pip install pydendroheatmap

посетите страницу проекта на GitHub здесь: https://github.com/themantalope/pydendroheatmap

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top