Warning: Constant WP_MEMORY_LIMIT already defined in /home/elorenzo/domains/arvo.es/public_html/dspace/wp-config.php on line 94
Configurando el buscador Lucene, sobre alfabetos, diacríticos, stemmers …. | Hablando de DSpace

Configurando el buscador Lucene, sobre alfabetos, diacríticos, stemmers ….

A raiz de algunas preguntas que aparecieron últimamente en las listas de GUDE , sobre anomalías en los resultados de búquedas, me comprometí a escribir sobre el tema. No se si este post arrojará alguna luz o confundirá aún más…espero que lo primero.

Este post es aplicable a las configuraciones de buscador basadas en Lucene, no en SOLR, es decir, todas las 1.6 y anteriores y las 1.7 y 1.8 que no usen la facilidad Discovery…

Nuestro camino empieza a partir de la línea en dspace.cfg:

search.analyzer = org.dspace.search.DSAnalyzer

es decir, el analizador estándar de Dspace, que como bien nos recuerdan, está diseñado para textos en inglés. Y este analizador tiene los siguientes filtros, aplicados en cascada:

  • StandarFilter -> labores preparatorias de conversión del texto en cadena de palabras para el resto de filtros
  • LowerCaseFilter–> conversión a minúsculas
  • StopFilter –> Elimina las palabras gramaticales o «vacías» , que no aportan gran significado a la búsqueda, como artículos, conjunciones, preposiciones, etc, a partir de una lista de exclusión o «stopword». La lista original del filtro incorpora términos ingleses
  • PorterStemFilter–> El algoritmo de Raíces de Porter (es lo que significa Porter Stem) retira sufijos y otras terminaciones morfológicas comunes de las palabras inglesas. Y desde luego con el español, catalán, portugués, etc… no es donde ofrece sus mejores resultados….

Sobre PorterStemFilter: Básicamente mejora las búsquedas en inglés, obteniendo la raíz de una mayoría de términos. Así loving, loves, loved, lovable, .., se ven reducidas a lov- y se mejora sustancialmente la búsqueda. De manera colateral, y por eso su uso pasa desapercibido a los hispanohablantes, es un stemmer válido para algunos plurales, pero no todos, del español, ya que recordemos que no está diseñado para nuestro idioma.

Para los curiosos, el filtro implementa un proceso definido en 1979 por Martin Porter, y que puede verse aquí .. Como dice Porter, y otros antes y después, el algoritmo simplemente devuelve mejores resultados en las búsquedas automatizadas, en inglés. Mejores que si no se usa el filtro. Pero tiene, evidentemente, sus carencias y equivocaciones, ya identificadas por Porter.

Y de forma «histórica», como un conocimiento pasado de instalación en instalación, y que nosotros mismos hemos implentado, la mayoría de instalaciones con textos en español, portugués, francés… han añadido, a continuación en la cadena de transformaciones un nuevo filtro:

  • ISOLatin1AccentFilter, que reemplaza los caracteres acentuados del juego de caracteres ISO Latin 1 (ISO-8859-1) por sus equivalentes sin acentuar, es decir reemplaza á por a.

Con esta configuración, y con este orden de transformaciones, entre otros efectos, las palabras terminadas en es, son consideradas plurales (en inglés, pero plurales) y reducidas a su raíz, singular, por el PorterStemFilter. Por contra, las palabras terminadas en és, no son reducidas, pues para este Filtro, si terminas en és no eres un plural. Los resultados de la búsqueda son así dispares…y de ahí las preguntas en GUDE.

Un poco de wikipedia: Un signo diacrítico es un signo gráfico que confiere a los signos escritos, no necesariamente letra, un valor especial.
Son diacríticos, por ejemplo, los acentos ortográficos ( ´ ; ` ), la diéresis ( ¨ ), los signos empleados en el alfabeto fonético, como la oclusión (^) o la nasalización ( ~ ), la tilde de la ñ (virgulilla), la cedilla ( ¸ ) , la colita ( ˛ ), la coma ( , ), el doble acento agudo, ( ˝ ), el carón ( ˇ ), el breve ( ˘ ), el macrón ( ˉ ), el anillo ( ˚ ), el punto ( . ), el acento circunflejo ( ^ ) y el garfio ( ̉ ).

Otro poco de wikipedia: ISO 8859-1 es la norma de la ISO que define la codificación del alfabeto latino, incluyendo los diacríticos (como letras acentuadas, ñ, ç), y letras especiales (como ß, Ø), necesarios para la escritura de las siguientes lenguas originarias de Europa occidental: afrikáans, alemán, aragonés, asturiano, castellano, catalán, danés, escocés, español, feroés, finés, francés, gaélico, gallego, inglés, islandés, italiano, neerlandés, noruego, portugués, sueco y Euskera.
También conocida como Alfabeto Latino n.º 1 o ISO Latín 1.

Dicho esto, señalar que ISOLatin1AccentFilter ha sido retirado, «deprecated», por Apache Lucene y ha sido sustituido por ASCIIFoldingFilter (hubo un ISOLatinACCENT por el intermedio..). Los detalles de la sustitución, aquí.

Esta clase mejora la ISOLatin1Accent, ya que ésta solo trataba el primer bloque de BASIC Latin, y lo amplía incluyendo (y filtrando a sus caracteres base) una larga lista de extensiones: C1 Controls y Latin-1 Supplement, Latin Extended-A, Latin Extended-B, Phonetic Extensions, General Punctuation, Superscripts and Subscripts, etc…

Y también señalar que Lucene tiene un org.apache.lucene.analysis.es.SpanishAnalyzer, que puede ser declarado en dspace.cfg como sustitución a org.dspace.search.DSAnalyzer. Las implicaciones de esta sustitución, es que en vez de usar la cadena StandarFilter -> LowerCaseFilter–> StopFilter –> PorterStemFilter–> ISOLatin1AccentFilter, usa el filtro definido por SpanishAnalyzer, un SpanishLightStemFilter. Las malas noticias son que las pruebas que hemos realizado con este Stemmer son ¿decepcionantes?, con un tratamiento desconcertante de las palabras agudas acentuadas terminadas en o, a y e …os suena, ¿verdad? No obstante, nos reservamos una segunda evaluación más pausada sobre este filtro.

ya casi… Conclusiones o recomendaciones

  • Seguir adoptando y adaptando org.dspace.search.DSAnalyzer, no cambiar a org.apache.lucene.analysis.es.SpanishAnalyzer, en tanto Lucene no mejore el Stemmer de español incluido por defecto.
  • Posiblemente cambiar ISOLatin1AccentFilter por ASCIIFoldingFilter. No mejorará radicalmente los resultados de ninguna búsqueda, pero si en el futuro se retira de las librerías Apache, el build no os dará problemas
  • Dependiendo del idioma predominante en nuestro Repositorio, valorar quitar PorterStemFilter de la cadena del analizador. Si requerís un Stemmer, otra opción, que hemos probado y aparentemente no tiene los problemas reportados en las listas GUDE, aunque a lo peor tiene otros efectos colaterales, es invertir el orden de los filtros PorterStem e ISOLatin1/ASCIIFolding.

con lo que org.dspace.search.DSAnalyzer nos podría quedar así:

import org.apache.lucene.analysis.ASCIIFoldingFilter;
..
..
result = new StandardFilter(result);
result = new LowerCaseFilter(result);
result = new StopFilter(result, stopSet);
result = new ASCIIFoldingFilter(result);
result = new PorterStemFilter(result);

Ya terminamos

Sobre todo, recordar los objetivos de un analizador: simplemente devolver mejores resultados en la mayoría de consultas. Es una transacción. Si dejamos pelada la cadena de análisis, los resultados serán extremadamente precisos, en el sentido de ofrecer solo resultados coincidentes con la cadena de búsqueda, pero no estaremos aprovechando las posibilidades de Lucene y nos habremos dejado en el camino un porcentaje amplio de resultados relevantes. Vuestra decisión.

(y perdón por que esta vez me ha salido un rollo)
(y sacaremos un post con la configuración propuesta para SOLR)

4 Comentarios.

  1. muy buena explicación acerca del uso de lucene, muchas gracias,

  2. muy clara la explicación acerca de lucene, gracias

  3. Wilmar Alzate

    Concluyendo que debemos hacer, en una D-Space 1.6.2 bajo Windows para que nuestros Repositorios, en español, busquen y visualicen los resultados donde se incluyen Ñ, ñ, Á, á, É, é, Í, í etc.

    • Estimado Wilmar, el post comenta cambios posibles a la configuración del DSAnalyzer para mejorar determinadas búsquedas sobre diacríticos (en problemas que algunas instalaciones habían detectado..de ahi el comienzo de post…)

      La situación final de su clase DSAnalyzer debería parecerse a:

      import org.apache.lucene.analysis.ASCIIFoldingFilter;
      ..
      ..
      result = new StandardFilter(result);
      result = new LowerCaseFilter(result);
      result = new StopFilter(result, stopSet);
      result = new ASCIIFoldingFilter(result);
      result = new PorterStemFilter(result);

      Los cambios base a DSANALYZER se describen en múltiples tickets Jira y conversaciones pasadas en Dspace-tech. Un poco de google le proporcionará información exhaustiva al respecto sobre como incorporar los cambios base a Dspace.

      Y le recomendaría que su cliente abandone lo antes posible el Dspace 1.6.2.
      un saludo.
      Emilio