Implementando una similitud más rápida del vecino de entrada en NetworkX -- python campo con graph campo con pandas camp codereview Relacionados El problema

Implementing a faster inbound neighbour similarity in Networkx


2
vote

problema

Español

Dado un gráfico dirigido g de más de 20 millones de bordes y aproximadamente 2 millones de nodos únicos, ¿puede esta función / proceso que se realice más rápido en un conjunto de datos de 40k bordes?

La velocidad actual es a ~ 1.8 segundos por borde.

  import pandas as pd import networkx as nx  # main feature calculator def jacard_inbound(u,v):     preds = G.predecessors(v)     result = [jacard_coef(u,x) for x in preds]     return sum(result), max(result), sum(result)/len(result)   # jacquard's coefficient & helper functions def jacard_coef(u,v):     return common_friends(u,v)/total_friends(u,v)  def total_friends(u,v):     return len(set(Gamma(u)).union(Gamma(v)))  def common_friends(u,v):     return len(set(Gamma(u)).intersection(Gamma(v)))  # to cache calculated results gamma_dict = dict()    def Gamma(u):     s = gamma_dict.get(u)     if s is None:         s = set(G.successors(u)).union(G.predecessors(u))         gamma_dict[u]=s     return s   

Ejemplo de ejecución:

  # sample graph G = nx.DiGraph() G.add_edges_from([(1,2), (1,3), (2,3), (3,4), (3,5), (7,1), (5,6), (8,2), (9,0)])  # sample edges dataset = pd.DataFrame(columns = ['source','target']) dataset['target'] = [3, 6, 2, 3] dataset['source'] = [2, 1, 8, 1]   t = time.time() dataset['jacard_inbound'] = dataset[['source','target']].apply(lambda x: jacard_inbound(x['source'],x['target']), axis=1) print(time.time() - t)   
Original en ingles

Given a directed graph G of 20+ million edges and approximately 2 million unique nodes, can this function/process be made faster on a dataset of 40k edges?

The current speed is at ~1.8 seconds per edge.

import pandas as pd import networkx as nx  # main feature calculator def jacard_inbound(u,v):     preds = G.predecessors(v)     result = [jacard_coef(u,x) for x in preds]     return sum(result), max(result), sum(result)/len(result)   # jacquard's coefficient & helper functions def jacard_coef(u,v):     return common_friends(u,v)/total_friends(u,v)  def total_friends(u,v):     return len(set(Gamma(u)).union(Gamma(v)))  def common_friends(u,v):     return len(set(Gamma(u)).intersection(Gamma(v)))  # to cache calculated results gamma_dict = dict()    def Gamma(u):     s = gamma_dict.get(u)     if s is None:         s = set(G.successors(u)).union(G.predecessors(u))         gamma_dict[u]=s     return s 

Running example:

# sample graph G = nx.DiGraph() G.add_edges_from([(1,2), (1,3), (2,3), (3,4), (3,5), (7,1), (5,6), (8,2), (9,0)])  # sample edges dataset = pd.DataFrame(columns = ['source','target']) dataset['target'] = [3, 6, 2, 3] dataset['source'] = [2, 1, 8, 1]   t = time.time() dataset['jacard_inbound'] = dataset[['source','target']].apply(lambda x: jacard_inbound(x['source'],x['target']), axis=1) print(time.time() - t) 
        
       
       

Lista de respuestas

1
 
vote
  1. "Jaccard Coefficient", no "Jacard" o "Jacquard": se llama después de paul Jaccard .

  2. No hay docesis. ¿Qué hacen estas funciones? ¿Qué devuelven?

  3. Los resultados de estas funciones dependen de la variable global for i in range(1, length+1): if length % i == 0: x.append(i) 2 . Si alguna vez necesita generalizar su programa para operar en más de un gráfico a la vez, esta dependencia se volvería muy inconveniente. Las funciones deben tomar la gráfica como argumento, o ser métodos en la clase de gráfico.

  4. es for i in range(1, length+1): if length % i == 0: x.append(i) 3 Terminología de gráfico estándar para esta función? Lo he visto llamado ' barrio ' (o 'vecindario abierto' cuando necesita ser borrado de que for i in range(1, length+1): if length % i == 0: x.append(i) 4 no está incluido).

  5. Python tiene un decorador incorporado for i in range(1, length+1): if length % i == 0: x.append(i) 5 para almacenar en caché los resultados de una función. Para que puedas escribir:

          for i in range(1, length+1):         if length % i == 0:             x.append(i) 6  
  6. Reutilice el conjunto de sucesores en lugar de descartarlo:

          for i in range(1, length+1):         if length % i == 0:             x.append(i) 7  
  7. En for i in range(1, length+1): if length % i == 0: x.append(i) 8 y for i in range(1, length+1): if length % i == 0: x.append(i) 9 , no es necesario hacer una copia del vecindario antes de tomar la unión / intersección. Puede tomar la unión / intersección directamente:

      length0  
 
  1. "Jaccard coefficient", not "Jacard" or "Jacquard": it's named after Paul Jaccard.

  2. There are no docstrings. What do these functions do? What do they return?

  3. The results of these functions depend on the global variable G. If you ever needed to generalize your program to operate on more than one graph at a time this dependency would become very inconvenient. The functions ought to either take the graph as an argument, or be methods on the graph class.

  4. Is Gamma standard graph terminology for this function? I've seen it called 'neighbourhood' (or 'open neighbourhood' when it needs to be clear that u is not included).

  5. Python has a built-in decorator functools.lru_cache for caching the results of a function. So you can write:

    @lru_cache(maxsize=None) def neighbourhood(g, u):     "Return the set of vertices in the graph g that are adjacent to u."     return set(g.successors(u)).union(g.predecessors(u)) 
  6. Reuse the set of successors instead of discarding it:

    @lru_cache(maxsize=None) def neighbourhood(g, u):     "Return the set of vertices in the graph g that are adjacent to u."     result = set(g.successors(u))     result.update(g.predecessors(u))     return result 
  7. In common_friends and total_friends, there is no need to make a copy of the neighbourhood before taking the union/intersection. You can take the union/intersection directly:

    def total_friends(g, u, v):     """Return the number of vertices in the graph g that are in the     neighbourhoods of u or v (or both).      """     return len(neighbourhood(g, u) | neighbourhood(g, v))  def common_friends(g, u, v):     """Return the number of vertices in the graph g that are in the     neighbourhoods of both u and v.      """     return len(neighbourhood(g, u) & neighbourhood(g, v)) 
 
 

Relacionados problema

6  Valores coincidentes de la tabla HTML para actualizar los valores en Pandas DataFrame  ( Matching values from html table for updating values in pandas dataframe ) 
Esto es más un ejercicio para que me utilice a Pandas y sus cuadros de datos. Para aquellos que no escucharon de él: Panda es un paquete de Python que prop...

5  Automatizar un conjunto A de informes semanales, incluidos los gráficos y la entrega de informes  ( Automating a set a of weekly reports including graphs and delivery of reports ) 
He estado escribiendo código para automatizar algunos informes semanales. Tuve Ayuda sobre el desbordamiento de la pila . Tengo código que funciona en su may...

4  Cuentos acumulativos de artículos en un marco de datos Panda  ( Cumulative counts of items in a pandas dataframe ) 
Estoy usando un conteo de datos lleno de encabezados / nombres de campo para desarrollar un esquema y necesito valores únicos para cada encabezado, pero cada ...

2  K_nearest_neighbors desde cero [cerrado]  ( K nearest neighbors from scratch ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

2  Regresión en Pandas DataFrame  ( Regression on pandas dataframe ) 
Estoy trabajando en la siguiente tarea y estoy un poco perdido: construir un modelo de regresión que predecirá la puntuación de calificación de cada Prod...

7  Salida de parcelas de dispersión [cerrada]  ( Outputting scatter plots ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

10  Tkinter GUI por hacer ediciones muy simples a Pandas DataFrames  ( Tkinter gui for making very simple edits to pandas dataframes ) 
Es parte de una aplicación separada que permite a los usuarios interactuar muy libremente con diferentes bases de datos y verificar los posibles errores y rea...

0  Manipulando los cuadros de datos en Pandas  ( Manipulating dataframes on pandas ) 
Recientemente no pudo finalizar un código para una entrevista de trabajo. Uno de los problemas es que decidí usar Pandas (tenía sentido), pero no estaba famil...

8  Python CSV a XML Converter  ( Python csv to xml converter ) 
Estoy creando una aplicación que se lee en los datos de un archivo CSV y crea un archivo XML usando LXML. El siguiente código funciona como se esperaba. Sin e...

7  La forma más rápida de escribir un archivo CSV grande en Python  ( Fastest way to write large csv file in python ) 
Soy bastante nuevo para Python y Pandas, pero tratando de mejorar con él para analizar y procesar archivos de datos grandes. Actualmente estoy trabajando en u...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos