2013-09-20 3 views
1

Я выполняю задачу кластеризации, и у меня есть матрица расстояний. Я хочу представить эту матрицу расстояний как 2D-граф. Пожалуйста, дайте мне знать, есть ли способ сделать это онлайн или на языках программирования, таких как R или python. Моя матрица расстояний выглядят следующим образом, enter image description here Я использовал классические Многомерные функции масштабирования (в R) и получил 2D сюжет, который выглядит так: enter image description here Но что я ищу это граф с узлами и взвешенными дугами, работающих между ними ,Визуализируйте матрицу расстояний в виде графика

+0

@ Anony-Mousse: Я испробовал немало вещей, упомянутых в ответах (например, http://vida.io, фрагменты кода на питоне - оба напрасно). Надеюсь, скоро я смогу запустить код python. Кроме того, я параллельно делаю чтение (относящееся к моей работе), поэтому, если вы хотите, чтобы я обновил этот пост/принял ответ так скоро, это НЕ ВОЗМОЖНО. –

+0

Ну, график MDS - хорошее начало. Затем добавьте триангуляцию Деланея или используйте другую эвристику для добавления ребер. –

+0

ОК, сделанный пункт, я обновлю этот вопрос, когда я смогу получить края. –

ответ

7

Возможность 1

Я предполагаю, что вы хотите 2dimensional графика, где расстояние между позициями узлов одинаковы, как это предусмотрено вашим столом.

В python вы можете использовать networkx для таких приложений. Помните, что в общем случае есть мамитоды, что все они являются просто аппроксимациями (как, вообще говоря, невозможно создать двумерную репрезентацию точек с учетом их попарных расстояний). Это своего рода стресс-минимизатин (или энергия -минимизация), пытаясь найти «разумное» представление с аналогичными расстояниями, как предусмотрено.

В качестве примера можно рассмотреть пример четыре точки (с правильно, дискретной метрикой применяется):

 p1 p2 p3 p4 
    --------------- 
    p1 0 1 1 1 
    p2 1 0 1 1 
    p3 1 1 0 1 
    p4 1 1 1 0 

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

Python example

import networkx as nx 
import numpy as np 
import string 

dt = [('len', float)] 
A = np.array([(0, 0.3, 0.4, 0.7), 
       (0.3, 0, 0.9, 0.2), 
       (0.4, 0.9, 0, 0.1), 
       (0.7, 0.2, 0.1, 0) 
       ])*10 
A = A.view(dt) 

G = nx.from_numpy_matrix(A) 
G = nx.relabel_nodes(G, dict(zip(range(len(G.nodes())),string.ascii_uppercase)))  

G = nx.to_agraph(G) 

G.node_attr.update(color="red", style="filled") 
G.edge_attr.update(color="blue", width="2.0") 

G.draw('distances.png', format='png', prog='neato') 

В R вы можете попробовать multidimensional scaling

# Classical MDS 
# N rows (objects) x p columns (variables) 
# each row identified by a unique row name 

d <- dist(mydata) # euclidean distances between the rows 
fit <- cmdscale(d,eig=TRUE, k=2) # k is the number of dim 
fit # view results 

# plot solution 
x <- fit$points[,1] 
y <- fit$points[,2] 
plot(x, y, xlab="Coordinate 1", ylab="Coordinate 2", 
    main="Metric MDS", type="n") 
text(x, y, labels = row.names(mydata), cex=.7) 

Возможность 2

Вы просто хотите, чтобы нарисовать граф с помеченными ребрами

Опять же, networkx может помочь:

import networkx as nx 

# Create a graph 
G = nx.Graph() 

# distances 
D = [ [0, 1], [1, 0] ] 

labels = {} 
for n in range(len(D)): 
    for m in range(len(D)-(n+1)): 
     G.add_edge(n,n+m+1) 
     labels[ (n,n+m+1) ] = str(D[n][n+m+1]) 

pos=nx.spring_layout(G) 

nx.draw(G, pos) 
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels,font_size=30) 

import pylab as plt 
plt.show() 
+0

Является ли networkx не совместимым с python 2.7? я получаю следующую ошибку :( Файл "test.py", строка 16, в G = nx.to_agraph (G) Файл «/usr/local/lib/python2.7/dist-packages/networkx/ drawing/nx_agraph.py ", строка 134, in to_agraph '(недоступно для Python3)') –

+1

Он отлично работает с python 2.7. Попробуйте установить http://pygraphviz.github.io/, который использует эта функция – lejlot

1

Вы не упомянули, если вы хотите 2 одномерный граф или нет. Я полагаю, что вы хотите построить график на 2 измерения из-за того, что вам нужно это для визуализации. Учитывая, что вы должны знать, что для большинства графиков это просто невозможно.

Возможно, что-то можно сделать, чтобы как-то приблизиться к значениям из матрицы расстояний, что-то вроде небольших значений, чтобы относительные небольшие ребра и большие значения имели относительную большую длину.

Со всеми предыдущими соображениями один из вариантов был бы graphviz. См. Функцию neato. Вообще то, что вас интересует, это рисунок с направленной силой. См. wikipedia для получения дополнительной информации.

0

Вы можете использовать d3js Force Directed Graph и настроить расстояние между узлами. Схема d3js force имеет некоторую возможность кластеризации для разделения узлов с одинаковыми расстояниями.Ниже приведен пример со значениями как расстояние между узлами:

http://vida.io/documents/SyT7DREdQmGSpsBkK

Другим способом визуализации заключается в использовании одинакового расстояния между узлами, но разной толщиной линии. В этом случае, вы хотите, чтобы вычислить обводки ширину на основе значений:

.style("stroke-width", function(d) { return Math.sqrt(d.value/50); }); 
2

Multidimensional scaling (MDS) это именно то, что вы хотите. См. here и here для получения дополнительной информации.

+0

Спасибо за ответ, это не то, что я искал, но выглядит интересно. Я хотел визуализировать эту матрицу как график с узлами и взвешенными ребрами, проходящими между узлами. Кроме того, я нашел пример R-реализации для MDS [здесь] (http://personality-project.org/r/mds.html). Вкратце расскажу вам об этом. –

Смежные вопросы