15

Estoy trabajando en un proyecto paralelo ahora que implica la codificación de todos los enlaces entre las páginas de Wikipedia. He extraído esta información en un disco, pero el uso de memoria requerido para codificar la estructura de este gráfico es bastante ridículo: hay millones de nodos y decenas de millones de enlaces. Si bien esta estructura cabe en la memoria, no estoy seguro de qué haría si hubiera, digamos, mil millones de enlaces o mil millones de páginas.Representación gráfica comprimida?

Mi pregunta es: ¿hay alguna manera de comprimir sin pérdidas un gráfico demasiado grande para caber en la memoria para que quepa en la memoria? De lo contrario, ¿existe un buen algoritmo con pérdidas que, para alguna definición de "estructura", no pierda demasiada estructura del gráfico original?

+0

¿Qué representación estás usando actualmente? ¿Matrix-forma? – fresskoma

+0

Lista de adyacencia simple donde cada página está codificada como un entero de 32 bits. – templatetypedef

+1

+1 - una pregunta realmente interesante. –

Respuesta

6

Los gráficos como los gráficos de enlaces y los gráficos sociales están muy bien estudiados y suelen tener propiedades estadísticas que permiten representaciones comprimidas eficientes.

Una de estas propiedades, por ejemplo, es que para bordes salientes la codificación diferencial de la lista de adyacencia tiene una baja distribución de potencia, es decir, hay muchos valores muy pequeños y muy pocos valores grandes, por lo que la mayoría universal codes funcionan bastante bien. En particular, la clase de zeta codes es probablemente óptima en este contexto, y en el documento los autores comprimieron el gráfico de enlace de un pequeño rastreo web con aproximadamente 3 bits por enlace.

Su código (para Java, Python y C++) es available in their webpage como un marco de compresión de gráficos, por lo que debería poder experimentar con él sin mucha codificación.

Este algoritmo es algo viejo (2005) y ha habido avances en el campo, pero no tengo los indicadores para los documentos en este momento, las mejoras no son significativas y no creo que haya ninguna código disponible y probado que los implementa.

1

¿Qué hay de simplemente escribir sus nodos, enlaces y asociaciones a un sistema de base de datos escalable existente (MySQL, SQL Server, Oracle, etc.)? Puede crear índices y procedimientos almacenados para un procesamiento de nivel de base de datos más rápido, si es necesario.

Si no puede seguir esta ruta por alguna razón, tendrá que ingresar y sacar datos de la página (¡como lo hacen los sistemas DB!). Comprimir los datos es una ayuda de banda a corto plazo en muchos casos. Si por alguna razón no puede elevar el techo RAM, solo se está comprando tiempo limitado, por lo que le recomiendo no comprimirlo.

+0

Definitivamente he considerado este enfoque. Estas son técnicas bien establecidas y comprobadas. Mi pregunta principal es si hay algunos buenos mecanismos de teoría de la información o estructuras de datos inteligentes que podrían hacer que esto sea innecesario. – templatetypedef

+0

Los filtros Bloom son estructuras probabilísticas basadas en hash que comprimen grandes conjuntos de datos y se utilizan para cosas como búsquedas en caché, etc. Pero recuerde que pueden emitir falsos positivos. Si puedes vivir con eso (y muchas personas pueden), pueden trabajar para ti. – kvista

+0

BTW, para saber si Bloom Filters podría funcionar para usted, tendríamos que saber más sobre las operaciones que intenta realizar con los datos. – kvista

3

En términos generales, si tiene N nodos y un promedio de X enlaces de salida por nodo, X mucho más pequeño que N, necesitará XN en N bits de información para representar esto, a menos que pueda encontrar patrones en la estructura de enlace (que luego puedes aprovechar para reducir la entropía). XN In N está dentro de un orden de magnitud de la complejidad de su lista de adyacencia de 32 bits.

hay algunos trucos que usted puede hacer para reducir el tamaño un poco más:

  • códigos de Huffman para codificar Uso destinos de vínculos. Asigne códigos más cortos a páginas de referencia frecuente y códigos más largos a páginas poco frecuentes.
  • Encuentra una manera de dividir el conjunto de páginas en clases. Almacene cada enlace entre páginas dentro de la misma clase que "0" + "# dentro de la clase"; enlaces entre páginas en diferentes categorías como "1" + "clase de destino" + "# dentro de clase".

Vale la pena consultar los enlaces de Giuseppe, pero solo el experimento le dirá qué tan bien esos algoritmos son aplicables a Wikipedia.

+0

¿Qué quiere decir con "XN ln N está dentro de un orden de magnitud a partir de la complejidad de su lista de adyacencia de 32 bits"? El OP solicitó un algoritmo que escala a miles de millones de páginas, por lo que 'ln N ~ = 32'.Además, los códigos Huffman no son una opción muy buena en este caso: aún debe almacenar la tabla de longitudes de código que requiere al menos un 'N log log N' adicional. –

+0

Exactamente. Si tiene 4 mil millones de páginas y los enlaces son completamente aleatorios, debe gastar 32 bits por enlace. Mi punto es que la lista de adyacencia trivial funcionará bastante bien en la situación. N log log N es insignificante, teniendo en cuenta que X es al menos 20, por lo que la tabla de longitud de código agrega 5-6 bits por nodo a la estructura de enlace que toma varios cientos de bits por nodo. – user434507

+0

Ok, interpreté mal la oración como "un orden de magnitud mejor". Acerca de huffman, la tabla de códigos puede ser costosa para la cola larga de nodos con pocos enlaces (que también estarían codificados con códigos largos, ya que probablemente se vinculen con páginas poco frecuentes) –

1

Si no necesita mutabilidad, eche un vistazo a cómo BGL representa un gráfico en un compressed sparse row format. De acuerdo con los documentos, "minimiza el uso de memoria a O (n + m) donde n y m son el número de vértices y bordes, respectivamente". Boost Graph Library incluso tiene an example que refleja su caso de uso.

Antes de ir más lejos con esto, realmente debe averiguar cómo piensa interrogar su gráfico. ¿Necesita enlaces que apuntan a la página, así como enlaces de una página? ¿Necesita poder encontrar de manera eficiente la cantidad de enlaces en una página determinada? Para obtener una lista bien pensada de operaciones gráficas básicas, consulte Boost Graph Library's (BGL) concepts. Puede asignar esto a los requisitos para diferentes algoritmos. Dijkstra's shortest path, por ejemplo, requiere un gráfico que modele "Gráfico de lista de vértices" y "Gráfico de incidencia".

4

Hace un tiempo formaba parte de a paper sobre la compresión de gráficos web para que cupieran en la memoria. Lo reducimos a alrededor de 6 bits por enlace.

+0

El problema general con la aplicación de técnicas de gráficos web (y todas las técnicas de codificación delta) a Wikipedia es que, en la web, podemos esperar razonablemente que los enlaces a menudo conectan nodos que están cerca uno del otro lexicográficamente (en el mismo servidor o en el mismo dominio). En un diccionario, los enlaces son mucho más aleatorios, p. http://en.wikipedia.org/wiki/Special:WhatLinksHere/J%C3%B4 – user434507

+3

Wikipedia no es tan aleatoria. Esperaría que el gráfico de enlace tuviera clústeres correspondientes a las categorías, al igual que los clústeres de gráficos web en dominios. –

1

En su caso, usted está tratando de comprimir un gráfico SINGLE en una memoria en lugar de una familia de gráficos general y grande. Cuando solo tiene un gráfico para comprimir, puede encontrar cualquier presentación algorítmica arbitraria para él y esto se convierte en un problema de Kolmogorov complexity. En general, no puede comprimir gráficos aleatorios de manera eficiente porque son aleatorios y, por lo tanto, no se pueden predecir y, cuando no se pueden predecir, no se pueden comprimir. Esto proviene de la teoría de la información básica; es lo mismo que no puedes comprimir imágenes con ruido aleatorio.

Suponga que tiene 2 (mil millones) páginas y cada uno tiene exactamente 2 enlaces salientes y que los enlaces son verdaderamente distribuida al azar. Los enlaces en cada página representan casi 16 * 30 bits de información (no totalmente porque los 16 enlaces son todos distintos y esto agrega una cantidad minúscula de redundancia). Entonces tiene 2 * 16 * 30 = 2 * 120 = 15 GB de información allí, y la teoría de la información dice que no puede encontrar una representación GENERAL más pequeña. Necesita usar la estructura particular del gráfico de Wikipedia para obtener debajo de ese límite inferior teórico de la información.

Cuestiones relacionadas