2010-07-27 19 views
6

Tras mirar alrededor de este sitio para problemas similares, encontré esto: http://math.nist.gov/javanumerics/jama/ y esto: http://sujitpal.blogspot.com/2008/09/ir-math-with-java-similarity-measures.htmlcoseno similitud de vectores, con <O (n^2) la complejidad

Sin embargo, parece que estos se ejecutan en O (n^2). He estado haciendo algunos clústeres de documentos y me di cuenta de que este nivel de complejidad no era factible cuando se trataba incluso de conjuntos de documentos pequeños. Dado que, para el producto escalar, solo necesitamos los términos vectoriales contenidos en ambos vectores, debería ser posible poner los vectores en un árbol y así calcular el producto escalar con n log n complejidad, donde n es el número más bajo de términos únicos en 1 de los 2 documentos.

¿Echo de menos algo? ¿Hay una biblioteca de Java que hace esto?

gracias

+1

No va a haber mucha suerte esperando que la gente lea ambas páginas. Quizás puedas explicar tu problema más claramente: ¿por qué estás multiplicando vectores (y qué quieres decir con O (n^2)? Comprender el producto de puntos de dos vectores n-dimensionales es trivialmente O (n), dudo mucho de que cualquier el paquete de vectores podría estropearlo gravemente) –

+1

Está calculando el producto de puntos por cada * par * de documentos. Eso lo hace cuadrativamente complejo. – Rekin

+2

BlueRaja - Danny Pflughoeft, este problema consiste en multiplicar vectores muy grandes pero muy dispersos; y n no es la dimensión sino el recuento de elementos distintos de cero. –

Respuesta

2

Si almacena los elementos del vector en una tabla hash, búsqueda sólo se log n de todos modos, ¿no? Pasa el cursor por todas las teclas del documento más pequeño y observa si existen en el documento más grande ...

+0

¿Alguna clase que recomendarías? Creo que este es bastante bueno, si la memoria es un problema: http://www.java2s.com/Code/Java/Collections-Data-Structure/Amemoryefficienthashmap.htm – Ash

+0

Wow no puede juzgar esto tan rápido, pero puedes siempre vaya con un java.util.HashMap normal para comenzar. Por cierto, ya que dice que es un efecto del tamaño de la recopilación de documentos: si compara cada documento con cada documento, tiene otro término cuadrático (ahora en el número de documentos) envuelto en el término (n * log n). Para mí, esta parte a menudo ha sido mucho más problemática que el cálculo del coseno real. ¿Podría ser este el caso para ti también? – Nicolas78

+0

Hago recortes en el conjunto de clúster para obtener la comparación a una constante, pero para algo como GAHC está completamente en lo cierto, tiene un problema n^2, donde n es el número de clústeres que se van a comparar. – Ash

2

Hashmap es bueno, pero puede llevar mucha memoria.

Si sus vectores están almacenados como pares clave-valor ordenados por clave, la multiplicación vectorial se puede hacer en O (n): solo tiene que iterar en paralelo sobre ambos vectores (la misma iteración se usa, por ejemplo, en algoritmo de ordenación de fusión) El pseudocódigo para la multiplicación:

i = 0 
j = 0 
result = 0 
while i < length(vec1) && j < length(vec2): 
    if vec1[i].key == vec2[j].key: 
    result = result + vec1[i].value * vec2[j].value 
    else if vec1[i].key < vec2[j].key: 
    i = i + 1 
    else 
    j = j + 1 
+0

Me gusta esta idea, gracias. ¿Hay una biblioteca de Java que utiliza este principio? – Ash

+0

No lo sé; pero lucene (http://lucene.apache.org/java/docs/index.html) podría contener dicho algoritmo. –

+0

Gracias dmitry-vk, parece que un mapa ordenado sería probablemente el mejor: http://java.sun.com/j2se/1.4.2/docs/api/java/util/SortedMap.html – Ash

0

Si sólo desea recomendar objetos limitados, para los artículos ejemplo, m, a cada elemento de un conjunto con el tamaño de n, la complejidad no tiene por qué ser n^2, pero m * norte. Como m es una constante, la complejidad es lineal.

Puede consultar con la base de datos del proyecto https://github.com/guokr/simbase, es una base de datos de semejanza vectorial nosql.

Simbase utilizar por debajo de conceptos:

  • Conjunto de vectores: un conjunto de vectores
  • Base: la base de vectores, los vectores en un conjunto de vectores tienen la misma base
  • Recomendación: a una sola dirección binaria relación entre dos conjuntos de vectores que tienen la misma base
0

Si está planeando utilizar la similitud del coseno como una forma de encontrar grupos de documentos similares, puede convencer Mirando hacia el locality-sensitive hashing, un enfoque basado en hash que fue diseñado específicamente con esto en mente. Intuitivamente, LSH clasifica los vectores de forma tal que con alta probabilidad coloca elementos similares en el mismo cubo y elementos distantes en diferentes segmentos. Existen esquemas LSH que usan la similitud de coseno como su distancia subyacente, por lo que para buscar clústeres, use LSH para colocar cosas en cubos y luego solo calcule las distancias por pares de elementos en el mismo cubo. En el peor de los casos, esto será cuadrático (si todo cae en el mismo cubo), pero es mucho más probable que tenga una disminución significativa en el trabajo.

Espero que esto ayude!

Cuestiones relacionadas