Я новичок в Python и хотел бы использовать пакетный граф-инструмент для оценки оптимального числа сообществ в моей сети, используя подход стохастической блочной модели (вложенный и не вложенный).
Я прочитал документацию, касающуюся основных функций «График» (для создания графика), а затем «minimal_blockmodel_dl» и «minimal_nested_blockmodel_dl», чтобы, наконец, получить то, что мне нужно, но я не смог найти ничего специфического для двудольных сетей.
Кажется, что функция Graph не позволяет создавать двудольный граф, но это было бы странно ...
По этой причине я только что увидел, как создать его с помощью пакета networkx, а затем преобразовать его в объект Graph, используя функции, которые я нашел в Интернете:
#
def get_prop_type(value, key=None):
# Deal with the value
if isinstance(value, bool):
tname = 'bool'
elif isinstance(value, int):
tname = 'float'
value = float(value)
elif isinstance(value, float):
tname = 'float'
elif isinstance(value, str):
tname = 'string'
elif isinstance(value, dict):
tname = 'object'
else:
tname = 'string'
value = str(value)
return tname, value, key
#
def nx2gt(nxG):
# Phase 0: Create a directed or undirected graph-tool Graph
gtG = Graph(directed=False)
# Add the Graph properties as "internal properties"
for key, value in nxG.graph.items():
# Convert the value and key into a type for graph-tool
tname, value, key = get_prop_type(value, key)
prop = gtG.new_graph_property(tname) # Create the PropertyMap
gtG.graph_properties[key] = prop # Set the PropertyMap
gtG.graph_properties[key] = value # Set the actual value
# Phase 1: Add the vertex and edge property maps
# Go through all nodes and edges and add seen properties
# Add the node properties first
nprops = set() # cache keys to only add properties once
for node, data in nxG.nodes(data=True):
# Go through all the properties if not seen and add them.
for key, val in data.items():
if key in nprops: continue # Skip properties already added
# Convert the value and key into a type for graph-tool
tname, _, key = get_prop_type(val, key)
prop = gtG.new_vertex_property(tname) # Create the PropertyMap
gtG.vertex_properties[key] = prop # Set the PropertyMap
# Add the key to the already seen properties
nprops.add(key)
# Also add the node id: in NetworkX a node can be any hashable type, but
# in graph-tool node are defined as indices. So we capture any strings
# in a special PropertyMap called 'id' -- modify as needed!
gtG.vertex_properties['id'] = gtG.new_vertex_property('string')
# Add the edge properties second
eprops = set() # cache keys to only add properties once
for src, dst, data in nxG.edges(data=True):
# Go through all the edge properties if not seen and add them.
for key, val in data.items():
if key in eprops: continue # Skip properties already added
# Convert the value and key into a type for graph-tool
tname, _, key = get_prop_type(val, key)
prop = gtG.new_edge_property(tname) # Create the PropertyMap
gtG.edge_properties[key] = prop # Set the PropertyMap
# Add the key to the already seen properties
eprops.add(key)
# Phase 2: Actually add all the nodes and vertices with their properties
# Add the nodes
vertices = {} # vertex mapping for tracking edges later
for node, data in nxG.nodes(data=True):
# Create the vertex and annotate for our edges later
v = gtG.add_vertex()
vertices[node] = v
# Set the vertex properties, not forgetting the id property
data['id'] = str(node)
for key, value in data.items():
gtG.vp[key][v] = value # vp is short for vertex_properties
# Add the edges
for src, dst, data in nxG.edges(data=True):
# Look up the vertex structs from our vertices mapping and add edge.
e = gtG.add_edge(vertices[src], vertices[dst])
# Add the edge properties
for key, value in data.items():
gtG.ep[key][e] = value # ep is short for edge_properties
return gtG
#
Итак, используя его метод list_properties (), я вижу следующее:
направленный (график) (тип: bool, val: 0)
двудольный (вершина) (тип: строка)
id (вершина) (тип: строка)
вес (ребро) (тип: двойной)
ОК, ненаправленный, двудольный, с вершинами, чьи целочисленные последовательности являются метками и весами для ребер.
Пока, кажется, все в порядке.
Наконец, пытаемся передать новый объект Graph функции
Минимизируй_blockmodel_dl и, используя метод get_blocks (), чтобы получить окончательные метки для каждой вершины в сети, я понимаю, что на самом деле бывает, что вершины, принадлежащие разным наборам двудольной сети, группируются в кластеры вместе с вершинами другого множества сети , Это означает, что первоначальное свойство быть двудольным больше не существует, и модель не применяет это ограничение.
Почему?
Я надеюсь, что некоторые из вас, кто использовал эти функции, могут помочь мне решить мою проблему.
Спасибо!