Переупорядочение матричных элементов для отражения кластеризации столбцов и строк в naiive python
Я ищу способ выполнить кластеризацию отдельно для строк матрицы, а не для ее столбцов, переупорядочить данные в матрице, чтобы отразить кластеризацию, и собрать их все вместе. Проблема кластеризации легко решаема, как и создание дендрограммы (например, в этом блоге или в разделе "Программирование коллективного интеллекта"). Однако, как изменить порядок данных для меня остается неясным.
В конце концов, я ищу способ создания графиков, аналогичных приведенному ниже, с использованием наивного Python (с любой "стандартной" библиотекой, такой как numpy, matplotlib и т.д., Но без использования R или других внешних инструментов).
(источник: warwick.ac.uk)
Разъяснения
Меня спросили, что я имел в виду, изменив порядок. Когда вы кластеризуете данные в матрице сначала по строкам матрицы, а затем по ее столбцам, каждая ячейка матрицы может быть идентифицирована по позиции в двух дендрограммах. Если вы переупорядочите строки и столбцы исходной матрицы так, чтобы элементы, расположенные рядом друг с другом в дендрограммах, стали близки друг к другу в матрице, а затем сгенерировали тепловую карту, кластеризация данных может стать очевидной для зрителя (как на рисунке выше)
Ответы
Ответ 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')
(источник: 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