Graph using python - igraph with attributes per node and edges

Speak up! I'm trying to create a graph using the Python-igraph library. Each node would have an attribute, for example, in a book graph whose nodes would be books and the attributes of those nodes would be:

titulo: nome_do_titulo
sinopse: descricao_do_livro
autor: nome_do_autor
prefacio: descricao_do_prefacio

And all these attributes of the nodes would have edges linking to similar attributes of other nodes containing the weight of the similarity between these attributes. So each node would have 4 edges for another node. I'm using python 3 and igraph.

A way I am implementing is as follows:

    g = Graph()
    g.vs["titulo"] = ['titulo1', 'titulo2', 'titulo3']
    g.vs["sinopse"] = ["sinopse1", "sinopse2", "sinopse3"]
    g.vs["autor"] = ["autor1","autor2","autor3"]
    g.vs["prefacio"] = ["prefacio1","prefacio2", "prefacio3"]

Now how to put the link ente they know that it uses g.es but the Igraph website is somewhat vague about it.

Author: jsbueno, 2017-05-03

1 answers

Did not know this igraph - apparently it is the Library to work with graphs in Python.

So, taking a look at the documentation and experimenting on Python's Interactive prompt (that's the secret to figuring out how to do things) - I understood the following:

The library does not give "1st Class" support for edges bound to node-specific attributes - (or maybe, whatever support it has is considered first class - I don't know :-) )

But since edges can have arbitrary attributes, you can put a "type" attribute on each edge - this way you'll know which attribute it concerns. And being complete, it perfectly supports more than one edge connecting the same pair of nodes, so you can have 2 edges relating two nodes that you want to link both per title and per author.

The only way to create an edge is to pass the numeric indexes of the nodes it is connecting - I suggest you put an attribute "type" (or "type" - it is always better to have all your program - variables including in English - you never know when the project will grow to have international collaborators. But more important than being in English is to be all variables and functions in the same language - if you started with Portuguese, continue with everything in Portuguese) - But then, to connect the nodes "0" and " 1 " by the title attribute, call

g.add_edge(source=0, target=1, tipo="titulo")

To find the contents of the nodes that you want to connect each other, if you want an exact match (==) of parameters, you can use the search with " find "in the object" G.vs "- for other searches, you can use the filter with" IF " of normal Python - and then use itertools.combinations to have all possible pairs of edges.

Example: let's assume that you want to connect all nodes whose titles contain the word "Narnia" - you can use such a function:

import itertools 

def conecta(grafo, palavra, atributo):
   nos_relevantes = [no.index for no in grafo.vs if palavra in getattr(no, atributo, "").lower()]
   for origem, destino in itertools.product(nos_relevantes, 2):
       grafo.add_edge(source=origem, target=destino, tipo=atributo)

I think your question has been answered so far. (test in interactive prompt these expressions, understand how itertools works.product, for example, etc...)

Now, I haven't seen enough of igraf to know if you're going to do what you want with the edges being distinguished only by that "type" attribute - now something you can definitely do is, when you need to use specific edges, create copies of the graph, and filter into the new graph only the edges that are relevant:

from copy imoport deep_copy
g_titulo = deepcopy(g)
g_titulo.delete_edges([e.index for  in g_titulo.es if e["tipo"] != "titulo"])

In time: this igraph API for associating the parameters to nodes from a list is kind of crazy - I don't know if it's the way you're going to prefer to use - I'd be more comfortable creating each node at once, passing all the linked parameters - it's how we usually work in Python. Igraph supports this. That is, instead of creating the vertices as you are doing, you can do:

g = igraph.Graph()
dados = [{"titulo": "titulo1", "sinopse": "sinopse1", "autor": "autor1"}, {"titulo": "titulo2", "sinopse": "sinopse2", "autor": "autor2"}, ]
for dado in dados:
    g.add_vertex(**dado)

This way it becomes easy to put your initial data in a spreadsheet, save as CSV, er with Python csv.DictReader to create a node for each one of your books, for example - and you don't have to worry - in parallel to the graph-about keeping lists with each attribute in the same order as the vertices are.

 1
Author: jsbueno, 2017-05-04 00:22:46