jesusutrera.com Jesús Utrera Burgal

Stemmer en C# para lengua castellana

Presento aquí un Stemmer de la lengua castellana escrito en C#. Se trata de un primera versión, basado en las reglas definidas en la web Snowball

Introducción

Descargar fuentes

En la morfología lingüística y en la recuperación de información, Stemming es un método para reducir una palabra a su raíz o (en inglés) a un stem. El stem no tiene que ser idéntico a la raíz morfológica de la palabra. Por lo general, es suficiente que las palabras relacionadas se asignen a la misma raíz, aunque esta raíz no sea en sí misma una raíz válida. Algoritmos para obtener la raíz se han estudiado en informática desde 1960. Muchos motores de búsqueda tratan palabras con la misma raíz como sinónimos como una especie de expansión de consultas, un proceso llamado fusión.
Andaba buscando un código en C# para realizar steemming en lenguaje castellano, pero no encontré nada, así que me puse manos a la obra... Y este es el resultado. Como dije antes, es un primer acercamiento y se basa en las reglas definidas en la web Snowball. El método de procesamiento de la palabra stemm sigue los pasos definidos a continuación.

El algoritmo de stemming

Las letras en castellano se presentan también acentuadas:
á é í ó ú

Las siguientes letras son vocales:
a e i o u á é í ó ú ü

R1 y R2 se definen como sigue:
- R1 es la región tras la que la primera letra no vocal sigue a una vocal, o es la región vacía al final de la palabra si no hay vocales.
- R2 es la región tras la que la primera letra no vocal sigue a una vocal en R1, o es la región vacía al final de la palabra si no hay vocales.

RV se define como sigue:
Si la segunda letra es consonante, RV es la región después de la cual le sigue una vocal, o si las dos primeras letras son vocales, RV es la región tras la primera consonante y, en otro caso, (caso consonante-vocal) RV es la región después de la tercera letra. Pero RV es el final de la palabra si estas posiciones no han podido ser encontradas.

Por ejemplo

Realizar siempre los pasos 0 and 1.

Paso 0: Pronombres adjuntos

Buscar el sufijo más largo de la siguiente lista:
me se sela selo selas selos la le lo las les los nos

y borrarlo, si viene detrás de:
(a) iéndo ándo ár ér ír
(b) ando iendo ar er ir
(c) yendo following u

en RV. En el caso de (c), yendo debe terminar en RV, pero la letra u que precede puede ir fuera.
En el caso de (a), el borrado vendrá seguida por la eliminación del acento (por ejemplo, haciéndola -> haciendo).

Paso 1: Eliminación de sufijos

Buscar el mas largo de entre los siguientes sufijos y realizar la acción indicada.

anza anzas ico ica icos icas ismo ismos able ables ible ibles ista istas oso osa osos osas amiento amientos imiento imientos
-- borrar si está en R2

adora ador ación adoras adores aciones ante antes ancia ancias
-- borrar si está en R2
-- si está precedida por ic, borrar si está en R2

logía logías
-- reemplazar por log si está en R2

ución uciones
-- reemplazar por u si está en R2

encia encias
-- reemplazar por ente si está en R2

amente
-- borrar si está en R1
-- si está precedida por iv, borrar si está en R2 (y si sigue precedida por at, borrar si está en R2), en otro caso,
-- si está precedida por os, ic o ad, borrar si está en R2

mente
-- borrar si está en R2
-- si está precedida por ante, able o ible, borrar si está en R2

idad idades
-- borrar si está en R2
-- si está precedida por abil, ic o iv, borrar si está en R2

iva ivo ivas ivos
-- borrar si está en R2
-- si está precedida por at, borrar si está en R2

Realizar el paso 2a si no se eliminó ninguna terminación en el paso 1.

Paso 2a: Sufijos verbales que comienzan por y

Buscar el sufijo más largoin RV de entre los siguientes y, en caso de encontrarlo, borrarlo si va precedido de u.
ya ye yan yen yeron yendo yo yó yas yes yais yamos

(Nótese que la u que la precede no necesita estar en RV.)

Realizar el paso 2b si el paso 2a se ha realizado pero falló al remover sufijos.

Paso 2b: Otros sufijos verbales

Buscar el más largo de entre los siguientes sufijos en RV y realizar la acción indicada.
en es éis emos
-- borrar, y si va precedido por gu borrar la u (no es necesario que la gu esté en RV)

arían arías arán arás aríais aría aréis aríamos aremos ará aré erían erías erán erás eríais ería eréis eríamos eremos erá eré irían irías irán irás iríais iría iréis iríamos iremos irá iré aba ada ida ía ara iera ad ed id ase iese aste iste an aban ían aran ieran asen iesen aron ieron ado ido ando iendo ió ar er ir as abas adas idas ías aras ieras ases ieses ís áis abais íais arais ierais aseis ieseis asteis isteis ados idos amos ábamos íamos imos áramos iéramos iésemos ásemos
-- borrar

Realizar siempre el paso 3.

Paso 3: Sufijos residuales

Buscar el más largo de entre los siguientes sufijos en RV y realizar la acción indicada.
os a o á í ó
-- borrar si está en RV

e é
-- borrar si está en RV. Y si está precedido por gu con la u en RV borrar la u

Y finalmente:
-- Borrar los acentos

Uso del código

Tenemos dos proyectos.

  1. Librería de clases SpanishStemmer
  2. Proyecto de testing (No haré mención del mismo por ser muy simple)
La librería de clases consta de dos clases, Stemmer y Specials. La clase Specials contiene la lista de términos usados por la clase Stemmer que procesa las palabras de entrada y que contiene palabras especiales en castellano. Stemmer es la clase que hace todo el trabajo. El método Execute recibe una palabra y devuelve la raíz (stem). Opcionalmente, este método recibe un valor booleano (useStopWords) que indicato si se deben o no incluir las palabras especiales en el proceso de stemming. Cuando la palabra es una de la lista de Specials.stop_words, entonces devuelve la propia palabra.

Cuando el valor de la variable useStopWord es falso o la palabra a procesar no es una palabra especial (Specials.stop_words), el proceso es el siguiente:

  1. Procesa R1, R2 y RV como se ha definido
  2. Realiza el paso 0.
  3. Realiza el paso 1.
  4. Realiza el paso 2a si el paso 1 no eliminó ninguna terminación.
  5. Realiza el paso 2b si el paso 2a fue realizado y no se eliminó ningún sufijo.
  6. Realiza el paso 3
  7. Elimina los acentos
  8. Devuelve la raíz de la palabra obtenida

Tweet