2010-03-16 44 views
24

Tôi đang tìm cách thực hiện phân cụm riêng biệt trên các hàng ma trận và hơn cột của nó, sắp xếp lại dữ liệu trong ma trận để phản ánh phân cụm và gộp tất cả . Vấn đề phân cụm có thể dễ dàng giải được, do đó, việc tạo chương trình dendrogram (ví dụ: this blog hoặc trong "Programming collective intelligence"). Tuy nhiên, làm thế nào để sắp xếp lại dữ liệu vẫn chưa rõ ràng cho tôi. Cuối cùng, tôi đang tìm cách tạo đồ thị tương tự như dưới đây bằng cách sử dụng Python ngây thơ (với bất kỳ thư viện "chuẩn" nào như numpy, matplotlib vv, nhưng không có using R hoặc các công cụ bên ngoài khác).Sắp xếp lại các phần tử ma trận để phản ánh phân cụm cột và hàng trong trăn nai

dendogram http://www2.warwick.ac.uk/fac/sci/moac/currentstudents/peter_cock/r/heatmap/no_scaling.png

Làm rõ

tôi đã hỏi những gì tôi có nghĩa là bằng cách sắp xếp lại. Khi bạn cụm dữ liệu trong một ma trận đầu tiên bởi các hàng ma trận, sau đó bởi các cột của nó, mỗi ô ma trận có thể được xác định bởi vị trí trong hai dendrograms. Nếu bạn sắp xếp lại các hàng và các cột của ma trận gốc sao cho các phần tử gần nhau trong các dendrogram trở nên gần nhau trong ma trận, và sau đó tạo ra bản đồ nhiệt, việc phân cụm dữ liệu có thể trở nên rõ ràng đối với người xem (như trong hình trên)

+0

Ý anh là gì bằng cách sắp xếp lại? Trao đổi n hàng lân cận/cols với n khác? –

+0

Bạn muốn sử dụng numpy/scipy khi giao dịch với ma trận cho chắc chắn. Matplotlib cũng bắt chước Matlab rất tốt. Đây là một thỏa thuận: nếu bạn có thể làm điều này trong Matlab, bạn có thể làm điều đó trong scipy cũng (sự khác biệt cú pháp tầm thường nếu có). –

+1

Ooh, +1 cho hình ảnh đẹp ;-) –

Trả lời

36

Xem recent answer của tôi, được sao chép một phần bên dưới, đến this related question.

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 http://up.stevetjoa.com/dendrogram.png

+1

Wow, giải pháp tốt đẹp.Bạn làm cho matplotlib trông đơn giản, mà tôi nghĩ là khá kỳ công.Nhưng làm thế nào để bạn sau đó thêm các nhãn vào trục x và y? Bạn có cần phải sử dụng twinx và twiny, hoặc là có một phương pháp đơn giản hơn – conradlee

+1

Cảm ơn bạn Tôi yêu matplotlib và tôi sử dụng nó rất nhiều iPython giúp bạn khám phá matplotlib và pylab hơn nữa Để thêm nhãn vào các trục của ma trận khoảng cách (hình trung tâm), bạn có thể sử dụng 'set_xticks' và 'set_xticklabels' Xem http: // ma tplotlib.sourceforge.net/api/axes_api.html?highlight=set_xticklabels#matplotlib.axes.Axes.set_xticklabels –

5

Tôi không chắc chắn hoàn toàn hiểu, nhưng có vẻ như bạn đang cố gắng lập chỉ mục lại từng trục của mảng dựa trên các loại chỉ báo chương trình. Tôi đoán rằng giả định có một số logic so sánh trong mỗi phân nhánh chi nhánh. Nếu đây là trường hợp sau đó sẽ làm việc này (?):

>>> 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_idxsy_idxs là indicies dendrogram. a là ma trận chưa được phân loại. xiyi là chỉ báo mảng hàng/cột mới của bạn. a2 là ma trận được sắp xếp trong khi x_idxs2y_idxs2 là các chỉ báo dendrogram mới được sắp xếp. Điều này giả định rằng khi chương trình dendrogram được tạo ra, một cột/hàng chi nhánh 0 luôn luôn lớn hơn/nhỏ hơn so với chi nhánh 1.

Nếu y_idx và x_idx của bạn không phải là danh sách nhưng là mảng có nhiều mảng, thì bạn có thể sử dụng np.argsort theo cách tương tự.

+0

chính xác những gì * trong "zip (* sắp xếp ..." làm? –

+0

bất cứ khi nào tôi thấy 'zip (*', tôi nghĩ "transpose". Xem ở đây để sử dụng '*' để giải nén : http://docs.python.org/tutorial/controlflow.html#unpacking-argument-lists – Paul

+0

và một số cuộc thảo luận khác tại đây: http://stackoverflow.com/questions/19339/a-transpose-unzip-function-in -python – Paul

2

Tôi biết điều này là rất muộn để các trò chơi, nhưng tôi đã thực hiện một đối tượng âm mưu dựa trên mã từ bài trên trang này. Nó đăng ký trên pip, vì vậy để cài đặt bạn chỉ cần gọi

pip install pydendroheatmap 

kiểm tra trang github của dự án ở đây: https://github.com/themantalope/pydendroheatmap

Các vấn đề liên quan