2010-05-27 12 views
6

tengo un Lucene-índice con los siguientes documentos:¿Cómo se cuenta la frecuencia de los términos para el conjunto de documentos?

doc1 := { caldari, jita, shield, planet } 
doc2 := { gallente, dodixie, armor, planet } 
doc3 := { amarr, laser, armor, planet } 
doc4 := { minmatar, rens, space } 
doc5 := { jove, space, secret, planet } 

por lo que estos 5 documentos utilizan 14 términos diferentes:

[ caldari, jita, shield, planet, gallente, dodixie, armor, amarr, laser, minmatar, rens, jove, space, secret ] 

la frecuencia de cada término:

[ 1, 1, 1, 4, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1 ] 

para una fácil lectura:

[ caldari:1, jita:1, shield:1, planet:4, gallente:1, dodixie:1, 
armor:2, amarr:1, laser:1, minmatar:1, rens:1, jove:1, space:2, secret:1 ] 

Lo que sí quiero saber ahora es, ¿cómo obtener el término vector de frecuencia para un conjunto de documentos ?

por ejemplo:

Set<Documents> docs := [ doc2, doc3 ] 

termFrequencies = magicFunction(docs); 

System.out.pring(termFrequencies); 

daría lugar a que la salida:

[ caldari:0, jita:0, shield:0, planet:2, gallente:1, dodixie:1, 
armor:2, amarr:1, laser:1, minmatar:0, rens:0, jove:0, space:0, secret:0 ] 

quitan todos los ceros:

[ planet:2, gallente:1, dodixie:1, armor:2, amarr:1, laser:1 ] 

Aviso, que la vetor resultado contiene sólo las frecuencias plazo de el conjunto de documentos . ¡NO las frecuencias generales de todo el índice! El término 'planeta' está presente 4 veces en todo el índice, pero el conjunto fuente de los documentos solo lo contiene 2 veces.

Una implementación ingenua sería simplemente iterar sobre todos los documentos en el conjunto docs, crear un mapa y contar cada término. Pero necesito una solución que también funcione con un tamaño de conjunto de documentos de 100.000 o 500.000.

¿Existe alguna función en Lucene que pueda usarse para obtener este vector de términos? Si no existe tal característica, ¿cómo se vería una estructura de datos como que alguien pueda crear en el momento del índice para obtener dicho vector de términos fácil y rápido?

No soy el experto en Lucene, entonces lamento si la solución es obvia o trivial.

Tal vez vale la pena mencionar: la solución debe funcionar lo suficientemente rápido para una aplicación web, aplicada a consultas de búsqueda de clientes.

+1

Así que hay 500 mil documentos, qué tan grande es su lista de términos? – Justin

+0

Sé exactamente lo que estás tratando de lograr, lástima que no tengo una respuesta a tu pregunta :) – Esko

+0

@Justin: tengo alrededor de 2.000 términos diferentes, máximo absoluto en unos años tal vez 10.000 pero con certeza no más . – ManBugra

Respuesta

5

entra aquí: http://lucene.apache.org/java/3_0_1/api/core/index.html y comprobar este método

org.apache.lucene.index.IndexReader.getTermFreqVectors(int docno); 

tendrá que conocer el ID de documento. Esta es una identificación interna de lucene y generalmente cambia en cada actualización de índice (que tiene eliminaciones :-)).

Creo que hay un método similar para Lucene 2.x.x

+0

¿Cómo podemos obtener esta identificación interna? Cuando no conocemos la identificación, ¿cómo podemos usar 'getTermFreqVectors' ??? –

0

No sé Lucene, sin embargo; su implementación ingenua se escalará, siempre que no lea todo el documento en la memoria al mismo tiempo (es decir, utilice un analizador en línea). El texto en inglés es aproximadamente el 83% redundante, por lo que su documento más grande tendrá un mapa con 85000 entradas. Use un mapa por hilo (y un hilo por archivo, agrupado obvio) y escalará muy bien.

Actualización: Si su lista de términos no cambia con frecuencia; puede intentar construir un árbol de búsqueda a partir de los caracteres en su lista de términos, o construir una función hash perfecta (http://www.gnu.org/software/gperf/) para acelerar el análisis de archivos (mapeo de términos de búsqueda a cadenas de destino). Probablemente solo un gran HashMap funcionaría también.

Cuestiones relacionadas