Подтвердить что ты не робот

Переупорядочение матричных элементов для отражения кластеризации столбцов и строк в naiive python

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

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

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

Разъяснения

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

4b9b3361

Ответ 1

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

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)

Ответ 2

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

>>> 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_idx и x_idx не являются списками, а являются массивами numpy, вы можете использовать np.argsort аналогичным образом.

Ответ 3

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

pip install pydendroheatmap

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