Изменение порядка элементов матрицы для отражения кластеризации столбцов и строк в naiive python - PullRequest
27 голосов
/ 16 марта 2010

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

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

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

Разъяснения

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

Ответы [ 3 ]

41 голосов
/ 10 июня 2010

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

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 )

5 голосов
/ 18 марта 2010

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

>>> 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 аналогичным образом.

2 голосов
/ 14 июля 2015

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

pip install pydendroheatmap

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

...